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 2017/11/30 21:42:32 UTC

[01/12] qpid-proton git commit: PROTON-1704: [c proactor] test_ipv4_ipv6 intermittent failure on FreeBSD

Repository: qpid-proton
Updated Branches:
  refs/heads/master 12aaab9d2 -> fe9069f9d


PROTON-1704: [c proactor] test_ipv4_ipv6 intermittent failure on FreeBSD

The negative tests that you can't connect from ipv4 to ipv6 and vice-versa
occasionally fail on FreeBSD because the connection succeeds. These tests are
not valid given the range of options for bridging ipv4 and ipv6, so they were
removed.


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

Branch: refs/heads/master
Commit: fe9069f9d9f5e27a8c3609eec366517ed8207b20
Parents: 06fbad3
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Nov 30 16:35:46 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/src/tests/proactor.c | 13 -------------
 tools/py/proctest.py          |  2 +-
 2 files changed, 1 insertion(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe9069f9/proton-c/src/tests/proactor.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/proactor.c b/proton-c/src/tests/proactor.c
index e020055..1d4137e 100644
--- a/proton-c/src/tests/proactor.c
+++ b/proton-c/src/tests/proactor.c
@@ -604,13 +604,6 @@ static void test_ipv4_ipv6(test_t *t) {
     TEST_PROACTORS_DRAIN(tps);                                           \
   } while(0)
 
-#define EXPECT_FAIL(TP, HOST) do {                                      \
-    pn_proactor_connect(client, pn_connection(), test_port_use_host(&(TP), (HOST))); \
-    TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));   \
-    TEST_COND_DESC(t, "refused", last_condition);                       \
-    TEST_PROACTORS_DRAIN(tps);                                           \
-  } while(0)
-
   EXPECT_CONNECT(l4.port, "127.0.0.1"); /* v4->v4 */
   EXPECT_CONNECT(l4.port, "");          /* local->v4*/
 
@@ -634,20 +627,14 @@ static void test_ipv4_ipv6(test_t *t) {
     EXPECT_CONNECT(l6.port, "");    /* local->v6 */
     EXPECT_CONNECT(l.port, "::1");  /* v6->all */
 
-    EXPECT_FAIL(l6.port, "127.0.0.1"); /* fail v4->v6 */
-    EXPECT_FAIL(l4.port, "::1");     /* fail v6->v4 */
-
     pn_listener_close(l6.listener);
   } else  {
     const char *d = pn_condition_get_description(last_condition);
     TEST_LOGF(t, "skip IPv6 tests: %s %s", pn_event_type_name(e), d ? d : "no condition");
   }
 
-  TEST_PROACTORS_DRAIN(tps);
   pn_listener_close(l.listener);
-  TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
   pn_listener_close(l4.listener);
-  TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
   TEST_PROACTORS_DESTROY(tps);
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe9069f9/tools/py/proctest.py
----------------------------------------------------------------------
diff --git a/tools/py/proctest.py b/tools/py/proctest.py
index 60b7384..802376e 100644
--- a/tools/py/proctest.py
+++ b/tools/py/proctest.py
@@ -7,7 +7,7 @@
 # "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
+#   http://www.apache.org/licenses/LICENSE-2.0OFF
 #
 # Unless required by applicable law or agreed to in writing,
 # software distributed under the License is distributed on an


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


[07/12] qpid-proton git commit: PROTON-1064: [ruby] Removed C-based Reactor

Posted by ac...@apache.org.
PROTON-1064: [ruby] Removed C-based Reactor

Kept a deprecated compatibility shim `Reactor::Container`,
delegates to the new native-ruby Qpid::Proton::Container


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

Branch: refs/heads/master
Commit: 0f03d826ba0e813c24ceb17b1a644c0f3cf9eccc
Parents: 67c4bae
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 14:01:17 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/README.rdoc              |  64 +++++-
 proton-c/bindings/ruby/cproton.i                |   9 -
 proton-c/bindings/ruby/lib/core/connection.rb   |   3 +-
 proton-c/bindings/ruby/lib/core/container.rb    |   3 +
 proton-c/bindings/ruby/lib/core/endpoint.rb     |  27 ---
 proton-c/bindings/ruby/lib/core/message.rb      |  22 +-
 proton-c/bindings/ruby/lib/core/selectable.rb   | 130 -----------
 proton-c/bindings/ruby/lib/core/session.rb      |   2 +-
 proton-c/bindings/ruby/lib/core/uri.rb          |   3 +
 proton-c/bindings/ruby/lib/event/event.rb       |  19 +-
 proton-c/bindings/ruby/lib/qpid_proton.rb       |  27 +--
 proton-c/bindings/ruby/lib/reactor/acceptor.rb  |  41 ----
 proton-c/bindings/ruby/lib/reactor/backoff.rb   |  41 ----
 proton-c/bindings/ruby/lib/reactor/connector.rb | 115 ----------
 proton-c/bindings/ruby/lib/reactor/container.rb | 220 +++----------------
 .../ruby/lib/reactor/global_overrides.rb        |  44 ----
 .../bindings/ruby/lib/reactor/link_option.rb    |  85 -------
 proton-c/bindings/ruby/lib/reactor/reactor.rb   | 197 -----------------
 .../ruby/lib/reactor/session_per_connection.rb  |  45 ----
 .../bindings/ruby/lib/reactor/ssl_config.rb     |  41 ----
 proton-c/bindings/ruby/lib/reactor/task.rb      |  39 ----
 proton-c/bindings/ruby/lib/reactor/urls.rb      |  45 ----
 .../bindings/ruby/lib/util/class_wrapper.rb     |   2 -
 proton-c/bindings/ruby/lib/util/reactor.rb      |  32 ---
 .../ruby/tests/old_examples/direct_send.rb      |   3 +-
 25 files changed, 128 insertions(+), 1131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/README.rdoc
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/README.rdoc b/proton-c/bindings/ruby/README.rdoc
index 566cb34..1b902da 100644
--- a/proton-c/bindings/ruby/README.rdoc
+++ b/proton-c/bindings/ruby/README.rdoc
@@ -1,20 +1,72 @@
 = Qpid Proton Ruby Language Bindings
 
-
 This is a Ruby language binding for the Qpid proton AMQP messaging library.
 You can build clients and servers using this library.
 
+== Class Overview
+
+The {Qpid::Proton} module contains the key classes:
+
+{Qpid::Proton::Message} represents a message that can be sent or received.
+A message body can be a string or byte sequence encoded any way you choose. However, AMQP also provides standard, interoperable encodings for basic data types like {Hash} and {Array}. The equivalent AMQP encodings can be understood as maps or sequences in any programming langauge with an AMQP library.
+
+{Qpid::Proton::Link} allows messages to be transferred to or from a remote AMQP process. The {Qpid::Proton::Sender} subclass sends messages, the {Qpid::Proton::Receiver} subclass receives them. Links have a source and target address, as explained below.
+
+Links are grouped in a {Qpid::Proton::Session}. Messages in the same session are sent sequentially, while those on different sessions can be interleaved. A large message being sent on one session does not block messages being sent on another session.
+
+Sessions belong to a {Qpid::Proton::Connection}. If you don't need multiple sessions, a connection will create links directly using a default session.
+
+A {Qpid::Proton::Delivery} represents the transfer of a message and allows the receiver to accept or reject it. The sender can use a {Qpid::Proton::Tracker} to track the status of a sent message and find out if it was accepted.
+
+A delivery is settled when both ends are done with it. Different settlement methods give different levels of reliability: at-most-once, at-least-once, and exactly-once. See below.
+
+== The anatomy of a Proton application
+
+{Qpid::Proton::Container} is the top-level object in a Proton application. A client uses {Qpid::Proton::Container#connect} to establish connections. A server uses {Qpid::Proton::Container#listen} to accept connections.
+
+Proton is an event-driven API. You implement a subclass of {Qpid::Proton::MessagingHandler MessagingHandler} and override functions to handle AMQP events, such as {Qpid::Proton::MessagingHandler#on_message #on_message}. Each connection is associated with a handler for its events. {Qpid::Proton::Container#run} polls all connections and listeners and calls the event handling functions on your handlers.
+
+A multi-threaded application can call {Qpid::Proton::Container#run} in more than one thread, the container will use all the {Qpid::Proton::Container#run #run} threads as a thread pool to dispatch events.
+
+== Sources and targets
+
+Every link has two addresses, _source_ and _target_. The most common pattern for using these addresses is as follows:
+
+When a client creates a {Qpid::Proton::Receiver Receiver} link, it sets the _source_ address. This means "I want to receive messages from this source". This is often referred to as "subscribing" to the source. When a client creates a {Qpid::Proton::Sender Sender} link, it sets the _target_ address. This means "I want to send to this target".
+
+In the case of a broker, the source or target usually refers to a queue or topic. In general they can refer to any AMQP-capable node.
+
+In the request-response pattern, a request message carries a reply-to address for the response message. This can be any AMQP address, but it is often useful to create a temporary address for the response message. The client creates a receiver with no source address and the dynamic flag set. The server generates a unique source address for the receiver, which is discarded when the link closes. The client uses this source address as the reply-to when it sends the request, so the response is delivered to the client's receiver.
+
+The server_direct.cpp example shows how to implement a request-response server.
+
+== Settlement
+
+A message is _settled_ by one end of a link when that end has forgotton the message.
+
+_Pre-settled_ messages are settled by the sender before sending. If the connection is lost before the message is received by the receiver, the message will not be delivered.
+
+If the sender does not pre-settle a message, then the receiver settles it once it is processed, and the receiver is informed of the settlement via the {Qpid::Proton::Tracker Tracker}. If the connection is lost before the sender is informed of the settlement, then the delivery is considered in-doubt and the message should be re-set. This ensures it eventually gets delivered (provided the connection and link can be reestablished) but also that it may be delivered multiple times.
 
 == Installing
 
-If you have the complete proton sources, you can build and install locally with:
+You can install the latest published Gem with
+
+    gem install qpid_proton
+
+*NOTE:* before installing the Gem, you must install the proton-C library.
+
+The proton-C library can be installed by the package manager on many platforms, e.g.
+    yum install qpid-proton-c # Fedora < 25, RHEL < 7
+    dnf install qpid-proton-c # Fedora >= 25, RHEL >= 7
+
+You can also download a source release or the latest development code from http://qpid.apache.org/proton. To build from source:
 
-    cmake -DBUILD_BINDINGS=ruby && make install
+    cmake -DBUILD_BINDINGS=ruby && make
 
-The cmake build also produces a Ruby Gem file at:
+This produces a Gem file at:
 
     ${CMAKE_BUILD_DIR}/proton-c/bindings/ruby/qpid_proton-${PN_VERSION}.gem
 
-You can install the gem with `gem install` as usual, but note that the proton-C
-library must be before installing the gem.
+You can install the gem with +gem install+
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/cproton.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/cproton.i b/proton-c/bindings/ruby/cproton.i
index 107f5d8..0f162fa 100644
--- a/proton-c/bindings/ruby/cproton.i
+++ b/proton-c/bindings/ruby/cproton.i
@@ -573,15 +573,6 @@ VALUE pni_address_of(void *object) {
 
 %}
 
-//%rename(pn_collector_put) wrap_pn_collector_put;
-//%inline %{
-//  pn_event_t *wrap_pn_collector_put(pn_collector_t *collector, void *context,
-//                               pn_event_type_t type) {
-//    return pn_collector_put(collector, PN_RBREF, context, type);
-//  }
-//  %}
-//%ignore pn_collector_put;
-
 int pn_ssl_get_peer_hostname(pn_ssl_t *ssl, char *OUTPUT, size_t *OUTPUT_SIZE);
 %ignore pn_ssl_get_peer_hostname;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index 4bd7e4f..fbef0cd 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -219,7 +219,6 @@ module Qpid::Proton
       object_to_data(opts[:offered_capabilities], Cproton.pn_connection_offered_capabilities(@impl))
       object_to_data(opts[:desired_capabilities], Cproton.pn_connection_desired_capabilities(@impl))
       object_to_data(opts[:properties], Cproton.pn_connection_properties(@impl))
-      Cproton.pn_connection_open(@impl)
     end
 
     # @private Generate a unique link name, internal use only.
@@ -272,9 +271,11 @@ module Qpid::Proton
     end
 
     # Open a sender on the default_session
+    # @option opts (see Session#open_sender)
     def open_sender(opts=nil) default_session.open_sender(opts) end
 
     # Open a  on the default_session
+    # @option opts (see Session#open_receiver)
     def open_receiver(opts=nil) default_session.open_receiver(opts) end
 
     # Returns the first session from the connection that matches the specified

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 05c45ed..7a4aeb1 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -142,6 +142,9 @@ module Qpid::Proton
       @stop_err = nil           # Optional error to pass to tasks, from #stop
     end
 
+    # @return [MessagingHandler] The container-wide handler
+    attr_reader :handler
+
     # @return [String] unique identifier for this container
     attr_reader :id
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/endpoint.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/endpoint.rb b/proton-c/bindings/ruby/lib/core/endpoint.rb
index 04551eb..53f5d49 100644
--- a/proton-c/bindings/ruby/lib/core/endpoint.rb
+++ b/proton-c/bindings/ruby/lib/core/endpoint.rb
@@ -118,32 +118,5 @@ module Qpid::Proton
     def remote_closed?
       check_state(REMOTE_CLOSED)
     end
-
-    def handler
-      reactor = Qpid::Proton::Reactor::Reactor.wrap(Cproton.pn_object_reactor(@impl))
-      if reactor.nil?
-        on_error = nil
-      else
-        on_error = reactor.method(:on_error)
-      end
-      record = self.attachments
-      puts "record=#{record}"
-      WrappedHandler.wrap(Cproton.pn_record_get_handler(record), on_error)
-    end
-
-    def handler=(handler)
-      reactor = Qpid::Proton::Reactor::Reactor.wrap(Cproton.pn_object_reactor(@impl))
-      if reactor.nil?
-        on_error = nil
-      else
-        on_error = reactor.method(:on_error)
-      end
-      impl = chandler(handler, on_error)
-      record = self.attachments
-      Cproton.pn_record_set_handler(record, impl)
-      Cproton.pn_decref(impl)
-    end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index d84e795..cbbe905 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -19,25 +19,17 @@
 
 module Qpid::Proton
 
-  # A Message represents an addressable quantity of data.
+  # Messsage data and headers that can sent or received on a {Link}
   #
-  # ==== Message Body
+  # {#body} is the main message content.
+  # {#properties} is a hash of extra properties that can be attached to the message.
   #
-  # The message body can be set using the #body= method. The message will
-  # then attempt to determine how exactly to encode the content.
+  # @example Create a message containing a Unicode string
+  #   msg = Qpid::Proton::Message.new "this is a string"
   #
-  # ==== Examples
-  #
-  # To create a message for sending:
-  #
-  #   # send a simple text message
-  #   msg = Qpid::Proton::Message.new
-  #   msg.body = "STATE: update"
-  #
-  #   # send a binary chunk of data
-  #   data = File.binread("/home/qpid/binfile.tar.gz")
+  # @example Create a message containing binary data
   #   msg = Qpid::Proton::Message.new
-  #   msg.body = Qpid::Proton::BinaryString.new(data)
+  #   msg.body = Qpid::Proton::BinaryString.new(File.binread("/home/qpid/binfile.tar.gz"))
   #
   class Message
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/selectable.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/selectable.rb b/proton-c/bindings/ruby/lib/core/selectable.rb
deleted file mode 100644
index 0ae2efe..0000000
--- a/proton-c/bindings/ruby/lib/core/selectable.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-#--
-# 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::Proton
-
-  # Selectable enables accessing the underlying file descriptors
-  # for Messenger.
-  #
-  # @private
-  class Selectable
-
-    # @private
-    include Util::SwigHelper
-
-    # @private
-    PROTON_METHOD_PREFIX = "pn_selectable"
-
-    # Returns the underlying file descriptor.
-    #
-    # This can be used in conjunction with the IO class.
-    #
-    def fileno
-      Cproton.pn_selectable_get_fd(@impl)
-    end
-
-    proton_reader :reading, :is_or_get => :is
-
-    proton_reader :writing, :is_or_get => :is
-
-    proton_caller :readable
-
-    proton_caller :writable
-
-    proton_caller :expired
-
-    proton_accessor :registered, :is_or_get => :is
-
-    proton_accessor :terminal, :is_or_get => :is
-
-    proton_caller :terminate
-
-    proton_caller :release
-
-    # @private
-    def self.wrap(impl)
-      return nil if impl.nil?
-
-      self.fetch_instance(impl, :pn_selectable_attachments) || Selectable.new(impl)
-    end
-
-    # @private
-    include Util::Wrapper
-
-    # @private
-    def initialize(impl)
-      @impl = impl
-      self.class.store_instance(self, :pn_selectable_attachments)
-    end
-
-    private
-
-    DEFAULT = Object.new
-
-    public
-
-    def fileno(fd = DEFAULT)
-      if fd == DEFAULT
-        Cproton.pn_selectable_get_fd(@impl)
-      elsif fd.nil?
-        Cproton.pn_selectable_set_fd(@impl, Cproton::PN_INVALID_SOCKET)
-      else
-        Cproton.pn_selectable_set_fd(@impl, fd)
-      end
-    end
-
-    def reading=(reading)
-      if reading.nil?
-        reading = false
-      elsif reading == "0"
-        reading = false
-      else
-        reading = true
-      end
-      Cproton.pn_selectable_set_reading(@impl, reading ? true : false)
-    end
-
-    def writing=(writing)
-      if writing.nil?
-        writing = false
-      elsif writing == "0"
-        writing = false
-      else
-        writing = true
-      end
-      Cproton.pn_selectable_set_writing(@impl, writing ? true : false)
-    end
-
-    def deadline
-      tstamp = Cproton.pn_selectable_get_deadline(@impl)
-      return nil if tstamp.nil?
-      mills_to_sec(tstamp)
-    end
-
-    def deadline=(deadline)
-      Cproton.pn_selectable_set_deadline(sec_to_millis(deadline))
-    end
-
-    def to_io
-      @io ||= IO.new(fileno)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/session.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/session.rb b/proton-c/bindings/ruby/lib/core/session.rb
index a21c152..2c1faeb 100644
--- a/proton-c/bindings/ruby/lib/core/session.rb
+++ b/proton-c/bindings/ruby/lib/core/session.rb
@@ -139,7 +139,7 @@ module Qpid::Proton
       return receiver
     end
 
-    # TODO aconway 2016-01-04: doc opts or target param
+    # TODO aconway 2016-01-04: doc opts or target param, connection and containers
     def open_sender(opts=nil)
       opts = { :target => opts } if opts.is_a? String
       opts ||= {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/core/uri.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/uri.rb b/proton-c/bindings/ruby/lib/core/uri.rb
index aea1e6a..636d20f 100644
--- a/proton-c/bindings/ruby/lib/core/uri.rb
+++ b/proton-c/bindings/ruby/lib/core/uri.rb
@@ -23,6 +23,9 @@ module URI
   # AMQP URI scheme for the AMQP protocol
   class AMQP < Generic
     DEFAULT_PORT = 5672
+
+    # Get the AMQP address: the {#path} minus any leading "/"
+    def amqp_address() path[0] == "/" ? path[1..-1] : path; end
   end
   @@schemes['AMQP'] = AMQP
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/event/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event.rb b/proton-c/bindings/ruby/lib/event/event.rb
index 67d5e92..8492b7c 100644
--- a/proton-c/bindings/ruby/lib/event/event.rb
+++ b/proton-c/bindings/ruby/lib/event/event.rb
@@ -218,20 +218,13 @@ module Qpid::Proton
         end
       end
 
-      # Returns the reactor for this event.
-      #
-      # @return [Reactor, nil] The reactor.
-      #
+      # @deprecated use {#container}
       def reactor
-        impl = Cproton.pn_event_reactor(@impl)
-        Qpid::Proton::Util::ClassWrapper::WRAPPERS["pn_reactor"].call(impl)
+        deprecated __method__, :container
       end
 
-      def container
-        @container || Util::ClassWrapper::WRAPPERS["pn_reactor"].call(Cproton.pn_event_reactor(@impl))
-      end
-
-      def container=(c); @container = c; end
+      # @return container associated with this event
+      attr_reader :container
 
       # Returns the transport for this event.
       #
@@ -312,8 +305,8 @@ module Qpid::Proton
         "#{self.type}(#{self.context})"
       end
 
+      # @private
+      def container=(c); @container = c; end
     end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 43b8071..cf1a01f 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -28,7 +28,10 @@ else
 end
 
 DEPRECATION = "[DEPRECATION]"
-def deprecated(old, new) warn "#{DEPRECATION} #{old} is deprecated, use #{new}"; end
+def deprecated(old, new)
+  repl = new ? ", use `#{new}`" : "with no replacement"
+  warn "#{DEPRECATION} `#{old}` is deprecated #{repl} (called from #{caller(2).first})"
+end
 
 # Exception classes
 require "core/exceptions"
@@ -44,7 +47,6 @@ require "util/class_wrapper"
 require "util/engine"
 require "util/timeout"
 require "util/handler"
-require "util/reactor"
 
 # Types
 require "types/strings"
@@ -63,7 +65,6 @@ require "event/event"
 require "event/collector"
 
 # Main Proton classes
-require "core/selectable"
 require "core/uri"
 require "core/message"
 require "core/endpoint"
@@ -100,24 +101,18 @@ require "handler/outgoing_message_handler"
 require "handler/c_flow_controller"
 require "handler/messaging_handler"
 
-# Reactor classes
-require "reactor/task"
-require "reactor/acceptor"
-require "reactor/reactor"
-require "reactor/ssl_config"
-require "reactor/global_overrides"
-require "reactor/urls"
-require "reactor/connector"
-require "reactor/backoff"
-require "reactor/session_per_connection"
-require "reactor/container"
-require "reactor/link_option"
-
 # Core classes that depend on handlers and events
 require "core/container"
 require "core/connection_driver"
 
+# Reactor classes for backwards compatibility
+require "reactor/container"
+
 module Qpid::Proton
+
+  include Qpid::Proton::Handler
+  Tracker = Delivery
+
   # @private
   def self.registry
     @registry ||= {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/acceptor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/acceptor.rb b/proton-c/bindings/ruby/lib/reactor/acceptor.rb
deleted file mode 100644
index 83e0596..0000000
--- a/proton-c/bindings/ruby/lib/reactor/acceptor.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class Acceptor
-
-    include Qpid::Proton::Util::Wrapper
-
-    def initialize(impl)
-      @impl = impl
-      self.class.store_instance(self)
-    end
-
-    def set_ssl_domain(ssl_domain)
-      Cproton.pn_acceptor_set_ssl_domain(@impl, ssl_domain.impl)
-    end
-
-    def close
-      Cproton.pn_acceptor_close(@impl)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/backoff.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/backoff.rb b/proton-c/bindings/ruby/lib/reactor/backoff.rb
deleted file mode 100644
index 54bb401..0000000
--- a/proton-c/bindings/ruby/lib/reactor/backoff.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class Backoff
-
-    def initialize min_ = 0, max_ = 3
-      @min = min_ > 0 ? min_ : 0.1
-      @max = [max_, min_].max
-      reset
-    end
-
-    def reset
-      @delay = 0
-    end
-
-    def next
-      current = @delay
-      @delay = @delay.zero? ? @min : [@max, 2 * @delay].min
-      return current
-    end
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/connector.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/connector.rb b/proton-c/bindings/ruby/lib/reactor/connector.rb
deleted file mode 100644
index b2d0c66..0000000
--- a/proton-c/bindings/ruby/lib/reactor/connector.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class Connector < Qpid::Proton::BaseHandler
-
-    def initialize(connection, url, options)
-      @connection, @options = connection, options
-      @urls = URLs.new(url) if url
-      options.each do |k,v|
-        case k
-        when :url, :urls, :address
-          @urls = URLs.new(v) unless @urls
-        when :reconnect
-          @reconnect = v
-        end
-      end
-      raise ::ArgumentError.new("no url for connect") unless @urls
-
-      # TODO aconway 2017-08-17: review reconnect configuration and defaults
-      @reconnect = Backoff.new() unless @reconnect
-      @ssl_domain = SessionPerConnection.new # TODO seems this should be configurable
-      @connection.overrides = self
-      @connection.open
-    end
-
-    def on_connection_local_open(event)
-      self.connect(event.connection)
-    end
-
-    def on_connection_remote_open(event)
-      @reconnect.reset if @reconnect
-    end
-
-    def on_transport_tail_closed(event)
-      self.on_transport_closed(event)
-    end
-
-    def on_transport_closed(event)
-      if !@connection.nil? && !(@connection.state & Qpid::Proton::Endpoint::LOCAL_ACTIVE).zero?
-        if !@reconnect.nil?
-          event.transport.unbind
-          delay = @reconnect.next
-          if delay == 0
-            self.connect(@connection)
-          else
-            event.reactor.schedule(delay, self)
-          end
-        else
-          @connection = nil
-        end
-      end
-    end
-
-    def on_timer_task(event)
-      self.connect(@connection)
-    end
-
-    def on_connection_remote_close(event)
-      @connection = nil
-    end
-
-    def connect(connection)
-      url = @urls.next
-      transport = Qpid::Proton::Transport.new
-      @options.each do |k,v|
-        case k
-        when :user
-          connection.user = v
-        when :password
-          connection.password = v
-        when :heartbeat
-          transport.idle_timeout = v.to_i
-        when :idle_timeout
-          transport.idle_timeout = v.(v*1000).to_i
-        when :sasl_enabled
-          transport.sasl if v
-        when :sasl_allow_insecure_mechs
-          transport.sasl.allow_insecure_mechs = v
-        when :sasl_allowed_mechs, :sasl_mechanisms
-          transport.sasl.allowed_mechs = v
-        end
-      end
-
-      # TODO aconway 2017-08-11: hostname setting is incorrect, reactor only
-      connection.hostname = "#{url.host}:#{url.port}"
-      connection.user = url.username if url.username && !url.username.empty?
-      connection.password = url.password if url.password && !url.password.empty?
-
-      transport.bind(connection)
-
-      if (url.scheme == "amqps") && @ssl_domain
-        @ssl = Qpid::Proton::SSL.new(transport, @ssl_domain)
-        @ssl.peer_hostname = url.host
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/container.rb b/proton-c/bindings/ruby/lib/reactor/container.rb
index fbe199e..8862133 100644
--- a/proton-c/bindings/ruby/lib/reactor/container.rb
+++ b/proton-c/bindings/ruby/lib/reactor/container.rb
@@ -19,206 +19,56 @@
 
 module Qpid::Proton::Reactor
 
-  private
-  class InternalTransactionHandler < Qpid::Proton::Handler::OutgoingMessageHandler
+  # @deprecated use {Qpid::Proton::Container}
+  class Container < Qpid::Proton::Container
 
-    def initialize
-      super
-    end
-
-    def on_settled(event)
-      if event.delivery.respond_to? :transaction
-        event.transaction = event.delivery.transaction
-        event.delivery.transaction.handle_outcome(event)
-      end
-    end
-
-  end
-
-  public
-  # A representation of the AMQP concept of a container which, loosely
-  # speaking, is something that establishes links to or from another
-  # container on which messages are transferred.
-  #
-  # This is an extension to the Reactor classthat adds convenience methods
-  # for creating instances of Qpid::Proton::Connection, Qpid::Proton::Sender
-  # and Qpid::Proton::Receiver.
-  class Container < Reactor
-
-    include Qpid::Proton::Util::Reactor
-
-    attr_accessor :container_id
-    attr_accessor :global_handler
-
-    def initialize(handlers, opts = {})
-      super(handlers, opts)
+    private
+    alias :super_connect :connect # Access to superclass method
 
-      # only do the following if we're creating a new instance
-      if !opts.has_key?(:impl)
-        @container_id = String.new(opts[:container_id] || SecureRandom.uuid).freeze
-        @ssl = SSLConfig.new
-        if opts[:global_handler]
-          self.global_handler = GlobalOverrides.new(opts[:global_handler])
-        else
-          # very ugly, but using self.global_handler doesn't work in the constructor
-          ghandler = Reactor.instance_method(:global_handler).bind(self).call
-          ghandler = GlobalOverrides.new(ghandler)
-          Reactor.instance_method(:global_handler=).bind(self).call(ghandler)
-        end
-        @trigger = nil
-      end
-    end
+    public
 
-    # Initiate an AMQP connection.
-    #
-    # @param url [String] Connect to URL host:port, using user:password@ if present
-    # @param opts [Hash] Named options
-    #   For backwards compatibility, can be called with a single parameter opts.
-    #
-    # @option opts [String] :url Connect to URL host:port using user:password@ if present.
-    # @option opts [String] :user user name for authentication if not given by URL
-    # @option opts [String] :password password for authentication if not given by URL
-    # @option opts [Numeric] :idle_timeout seconds before closing an idle connection,
-    #   can be a fractional value.
-    # @option opts [Boolean] :sasl_enabled Enable or disable SASL.
-    # @option opts [Boolean] :sasl_allow_insecure_mechs Allow mechanisms that disclose clear text
-    #   passwords, even over an insecure connection. By default, such mechanisms are only allowed
-    #   when SSL is enabled.
-    # @option opts [String] :sasl_allowed_mechs the allowed SASL mechanisms for use on the connection.
-    #
-    # @option opts [String] :address *deprecated* use the :url option
-    # @option opts [Numeric] :heartbeat milliseconds before closing an idle connection.
-    #   *deprecated* use :idle_timeout => heartbeat/1000 
-    #
-    # @return [Connection] the new connection
-    #
-    def connect(url, opts = {})
-      # Backwards compatible with old connect(opts)
-      if url.is_a? Hash and opts.empty?
-        opts = url
-        url = nil
-      end
-      conn = self.connection(opts[:handler])
-      connector = Connector.new(conn, url, opts)
-      return conn
+    # @deprecated use {Qpid::Proton::Container}
+    def initialize(handlers, opts=nil)
+      deprecated self.class, "Qpid::Proton::Container"
+      super handlers || (opts && opts[:global_handler]), opts && opts[:container_id]
     end
 
-    # Initiates the establishment of a link over which messages can be sent.
-    #
-    # @param context [String, URL] The context.
-    # @param opts [Hash] Additional opts.
-    # @param opts [String] :target The target address.
-    # @param opts [String] :source The source address.
-    # @param opts [Boolean] :dynamic
-    # @param opts [Object] :handler
-    #
-    # @return [Sender] The sender.
-    #
-    def open_sender(context, opts = {})
-      if context.is_a?(::String)
-        context = Qpid::Proton::URL.new(context)
-      end
-      if context.is_a?(Qpid::Proton::URL)
-        opts[:target] ||= context.path
-      end
+    alias :container_id :id
+    alias :global_handler :handler
 
-      return _session(context).open_sender(opts)
+    def connect(opts=nil)
+      url = opts && (opts[:url] || opts[:address])
+      raise ::ArgumentError.new, "no :url or :address option provided" unless url
+      super(url, opts)
     end
 
-    # @deprecated use @{#open_sender}
-    alias_method :create_sender, :open_sender
-
-    # Initiates the establishment of a link over which messages can be received.
-    #
-    # There are two accepted arguments for the context
-    #  1. If a Connection is supplied then the link is established using that
-    # object. The source, and optionally the target, address can be supplied
-    #  2. If it is a String or a URL then a new Connection is created on which
-    # the link will be attached. If a path is specified, but not the source
-    # address, then the path of the URL is used as the target address.
-    #
-    # The name will be generated for the link if one is not specified.
-    #
-    # @param context [Connection, URL, String] The connection or the connection address.
-    # @param opts [Hash] Additional opts.
-    # @option opts [String] :source The source address.
-    # @option opts [String] :target The target address
-    # @option opts [String] :name The link name.
-    # @option opts [Boolean] :dynamic
-    # @option opts [Object] :handler
-    #
-    # @return [Receiver]
-    #
-    def open_receiver(context, opts = {})
-      if context.is_a?(::String)
-        context = Qpid::Proton::URL.new(context)
+    # @deprecated use {#connect} then {Connection#open_sender}
+    def create_sender(context, opts=nil)
+      c = context if context.is_a? Qpid::Proton::Connection
+      unless c
+        url = Qpid::Proton::uri context
+        c = super_connect(url, opts)
+        opts ||= {}
+        opts[:target] ||= url.amqp_address
       end
-      if context.is_a?(Qpid::Proton::URL)
-        opts[:source] ||= context.path
-      end
-      return _session(context).open_receiver(opts)
+      c.open_sender opts
     end
 
-    # @deprecated use @{#open_sender}
-    alias_method :create_receiver, :open_receiver
-
-    def declare_transaction(context, handler = nil, settle_before_discharge = false)
-      if context.respond_to? :txn_ctl && !context.__send__(:txn_ctl).nil?
-        class << context
-          attr_accessor :txn_ctl
-        end
-        context.txn_ctl = self.create_sender(context, nil, "txn-ctl",
-        InternalTransactionHandler.new())
+    # @deprecated use {#connect} then {Connection#open_receiver}
+    def create_receiver(context, opts=nil)
+      c = context if context.is_a? Qpid::Proton::Connection
+      unless c
+        url = Qpid::Proton::uri context
+        c = super_connect(url, opts)
+        opts ||= {}
+        opts[:source] ||= url.amqp_address
       end
-      return Transaction.new(context.txn_ctl, handler, settle_before_discharge)
+      c.open_receiver opts
     end
 
-    # Initiates a server socket, accepting incoming AMQP connections on the
-    # interface and port specified.
-    #
-    # @param url []
-    # @param ssl_domain []
-    #
     def listen(url, ssl_domain = nil)
-      url = Qpid::Proton::URL.new(url)
-      acceptor = self.acceptor(url.host, url.port)
-      ssl_config = ssl_domain
-      if ssl_config.nil? && (url.scheme == 'amqps') && @ssl
-        ssl_config = @ssl.server
-      end
-      if !ssl_config.nil?
-        acceptor.ssl_domain(ssl_config)
-      end
-      return acceptor
-    end
-
-    private
-
-    def _session(context)
-      if context.is_a?(Qpid::Proton::URL)
-        return _session(self.connect(:url => context))
-      elsif context.is_a?(Qpid::Proton::Session)
-        return context
-      elsif context.is_a?(Qpid::Proton::Connection)
-        return context.default_session
-      else
-        return context.session
-      end
+      # TODO aconway 2017-11-29: ssl_domain
+      super(url)
     end
-
-    def do_work(timeout = nil)
-      self.timeout = timeout unless timeout.nil?
-      self.process
-    end
-
-    def _apply_link_opts(opts, link)
-      opts.each {|o| o.apply(link) if o.test(link)}
-    end
-
-    def to_s
-      "#{self.class}<@impl=#{Cproton.pni_address_of(@impl)}>"
-    end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/global_overrides.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/global_overrides.rb b/proton-c/bindings/ruby/lib/reactor/global_overrides.rb
deleted file mode 100644
index 11d05a5..0000000
--- a/proton-c/bindings/ruby/lib/reactor/global_overrides.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class GlobalOverrides
-
-    def initialize(base)
-      @base = base
-    end
-
-    def on_unhandled(name, event)
-      event.dispatch(@base) unless self.override?(event)
-    end
-
-    def override?(event)
-      conn = event.connection
-      if !conn.nil? && conn.overrides?
-        overrides = conn.overrides
-        result = event.dispatch(overrides)
-        return result
-      end
-      false
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/link_option.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/link_option.rb b/proton-c/bindings/ruby/lib/reactor/link_option.rb
deleted file mode 100644
index 2066bab..0000000
--- a/proton-c/bindings/ruby/lib/reactor/link_option.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class LinkOption
-    def apply(link)
-    end
-
-    # Subclasses should override this to selectively apply an option.
-    def test(link)
-      true
-    end
-  end
-
-  class AtMostOne < LinkOption
-    def apply(link)
-      link.snd_settle_mod = Link::SND_SETTLED
-    end
-  end
-
-  class AtLeastOnce < LinkOption
-    def apply(link)
-      link.snd_settle_mode = Link::SND_UNSETTLED
-      link.rcv_settle_mode = Link::RCV_FIRST
-    end
-  end
-
-  class SenderOption < LinkOption
-    def test(link)
-      link.sender?
-    end
-  end
-
-  class ReceiverOption < LinkOption
-    def test(link)
-      link.receiver?
-    end
-  end
-
-  class DynamicNodeProperties < LinkOption
-    def initialize(properties = {})
-      @properties = []
-      properties.each do |property|
-        @properties << property.to_sym
-      end
-    end
-
-    def apply(link)
-      if link.receiver?
-        link.source.properties.object = @properties
-      else
-        link.target.properties.object = @properties
-      end
-    end
-  end
-
-  class Filter < ReceiverOption
-    def initialize(filter_set = {})
-      @filter_set = filter_set
-    end
-
-    def apply(receiver)
-      receiver.source.filter.object = @filter_set
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/reactor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/reactor.rb b/proton-c/bindings/ruby/lib/reactor/reactor.rb
deleted file mode 100644
index 88d062e..0000000
--- a/proton-c/bindings/ruby/lib/reactor/reactor.rb
+++ /dev/null
@@ -1,197 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class Reactor
-
-    include Qpid::Proton::Util::Handler
-
-    # @private
-    include Qpid::Proton::Util::SwigHelper
-
-    # @private
-    PROTON_METHOD_PREFIX = "pn_reactor"
-
-    proton_caller :yield
-
-    proton_caller :mark
-
-    proton_caller :start
-
-    proton_caller :stop
-
-    # @private
-    include Qpid::Proton::Util::Timeout
-
-    include Qpid::Proton::Util::Wrapper
-
-    attr_reader :errors
-
-    def self.wrap(impl)
-      return nil if impl.nil?
-
-      self.fetch_instance(impl, :pn_reactor_attachments) || Reactor.new(nil, :impl => impl)
-    end
-
-    def initialize(handlers, options = {})
-      deprecated(self.class, "Qpid::Proton::Container")
-      @impl = options[:impl]
-      if @impl.nil?
-        @impl = Cproton.pn_reactor
-      end
-      if !handlers.nil?
-        [handlers].flatten.each {|handler| self.handler.add(handler)}
-      end
-      @errors = []
-      @handlers = []
-      self.class.store_instance(self, :pn_reactor_attachments)
-    end
-
-    # Returns whether the reactor has any unbuffered data.
-    #
-    # @return [Boolean] True if there is no unbuffered data.
-    #
-    def quiesced?
-      Cproton.pn_reactor_quiesced(@impl)
-    end
-
-    def on_error(info)
-      self.errors << info
-      self.yield
-    end
-
-    def global_handler
-      impl = Cproton.pn_reactor_get_global_handler(@impl)
-      Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
-    end
-
-    def global_handler=(handler)
-      impl = chandler(handler, self.method(:on_error))
-      Cproton.pn_reactor_set_global_handler(@impl, impl)
-      Cproton.pn_decref(impl)
-    end
-
-    # Returns the timeout period.
-    #
-    # @return [Integer] The timeout period, in seconds.
-    #
-    def timeout
-      millis_to_timeout(Cproton.pn_reactor_get_timeout(@impl))
-    end
-
-    # Sets the timeout period.
-    #
-    # @param timeout [Integer] The timeout, in seconds.
-    #
-    def timeout=(timeout)
-      Cproton.pn_reactor_set_timeout(@impl, timeout_to_millis(timeout))
-    end
-
-    def handler
-      impl = Cproton.pn_reactor_get_handler(@impl)
-      Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
-    end
-
-    def handler=(handler)
-      impl = chandler(handler, set.method(:on_error))
-      Cproton.pn_reactor_set_handler(@impl, impl)
-      Cproton.pn_decref(impl)
-    end
-
-    def run(&block)
-      self.timeout = 3.14159265359
-      self.start
-      while self.process do
-        if block_given?
-          yield
-        end
-      end
-      self.stop
-    end
-
-    def wakeup
-      n = Cproton.pn_reactor_wakeup(@impl)
-      unless n.zero?
-        raise IOError.new(Cproton.pn_reactor_error(@impl))
-      end
-    end
-
-    def process
-      result = Cproton.pn_reactor_process(@impl)
-      if !self.errors.nil? && !self.errors.empty?
-        (0...self.errors.size).each do |index|
-          error_set = self.errors[index]
-          print error.backtrace.join("\n")
-        end
-        raise self.errors.last
-      end
-      return result
-    end
-
-    def schedule(delay, task)
-      impl = chandler(task, self.method(:on_error))
-      task = Task.wrap(Cproton.pn_reactor_schedule(@impl, sec_to_millis(delay), impl))
-      Cproton.pn_decref(impl)
-      return task
-    end
-
-    def acceptor(host, port, handler = nil)
-      impl = chandler(handler, self.method(:on_error))
-      aimpl = Cproton.pn_reactor_acceptor(@impl, host, "#{port}", impl)
-      Cproton.pn_decref(impl)
-      if !aimpl.nil?
-        return Acceptor.new(aimpl)
-      else
-        io_error = Cproton.pn_reactor_error(@impl)
-        error_text = Cproton.pn_error_text(io_error)
-        text = "(#{Cproton.pn_error_text(io_error)} (#{host}:#{port}))"
-        raise IOError.new(text)
-      end
-    end
-
-    def connection(handler = nil)
-      impl = chandler(handler, self.method(:on_error))
-      conn = Qpid::Proton::Connection.wrap(Cproton.pn_reactor_connection(@impl, impl))
-      Cproton.pn_decref(impl)
-      return conn
-    end
-
-    def selectable(handler = nil)
-      impl = chandler(handler, self.method(:on_error))
-      result = Selectable.wrap(Cproton.pn_reactor_selectable(@impl))
-      if !impl.nil?
-        record = Cproton.pn_selectable_attachments(result.impl)
-        Cproton.pn_record_set_handler(record, impl)
-        Cproton.pn_decref(impl)
-      end
-      return result
-    end
-
-    def update(sel)
-      Cproton.pn_reactor_update(@impl, sel.impl)
-    end
-
-    def push_event(obj, etype)
-      Cproton.pn_collector_put(Cproton.pn_reactor_collector(@impl), Qpid::Proton::Util::RBCTX, Cproton.pn_py2void(obj), etype.number)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/session_per_connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/session_per_connection.rb b/proton-c/bindings/ruby/lib/reactor/session_per_connection.rb
deleted file mode 100644
index f8180c0..0000000
--- a/proton-c/bindings/ruby/lib/reactor/session_per_connection.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class SessionPerConnection
-
-    include Qpid::Proton::Util::Reactor
-
-    def initialize
-      @default_session = nil
-    end
-
-    def session(connection)
-      if @default_session.nil?
-        @default_session = self.create_session
-        @default_session.context = self
-      end
-      return @default_session
-    end
-
-    def on_session_remote_close(event)
-      event.connection.close
-      @default_session = nil
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/ssl_config.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/ssl_config.rb b/proton-c/bindings/ruby/lib/reactor/ssl_config.rb
deleted file mode 100644
index 56fec71..0000000
--- a/proton-c/bindings/ruby/lib/reactor/ssl_config.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class SSLConfig
-
-    def initialize
-      @client = Qpid::Proton::SSLDomain.new(Qpid::Proton::SSLDomain::MODE_CLIENT)
-      @server = Qpid::Proton::SSLDomain.new(Qpid::Proton::SSLDomain::MODE_SERVER)
-    end
-
-    def set_credentials(cert_file, key_file, password)
-      @client.set_credentials(cert_file, key_file, password)
-      @server.set_credentials(cert_file, key_file, password)
-    end
-
-    def set_trusted_ca_db(certificate_db)
-      @client.set_trusted_ca_db(certificate_db)
-      @server.set_trusted_ca_db(certificate_db)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/task.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/task.rb b/proton-c/bindings/ruby/lib/reactor/task.rb
deleted file mode 100644
index 6818ed2..0000000
--- a/proton-c/bindings/ruby/lib/reactor/task.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class Task
-
-    # @private
-    include Qpid::Proton::Util::Wrapper
-
-    def self.wrap(impl)
-      return nil if impl.nil?
-      self.fetch_instance(impl, :pn_task_attachments) || Task.new(impl)
-    end
-
-    def initialize(impl)
-      @impl = impl
-      self.class.store_instance(self, :pn_task_attachments)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/reactor/urls.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/urls.rb b/proton-c/bindings/ruby/lib/reactor/urls.rb
deleted file mode 100644
index 92cab81..0000000
--- a/proton-c/bindings/ruby/lib/reactor/urls.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-#--
-# 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::Proton::Reactor
-
-  class URLs
-
-    def initialize(values)
-      @values = values
-      if @values.is_a? Enumerable
-        @values = @values.map { |u| Qpid::Proton::URL.new(u) }
-      else
-        @values = [Qpid::Proton::URL.new(values)]
-      end
-      @iter = @values.each
-    end
-
-    def next
-      begin
-        return @iter.next
-      rescue StopIteration
-        @iter = @values.each
-        return @iter.next
-      end
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/util/class_wrapper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/class_wrapper.rb b/proton-c/bindings/ruby/lib/util/class_wrapper.rb
index dec16e9..134f655 100644
--- a/proton-c/bindings/ruby/lib/util/class_wrapper.rb
+++ b/proton-c/bindings/ruby/lib/util/class_wrapper.rb
@@ -36,8 +36,6 @@ module Qpid::Proton::Util
         "pn_delivery" => proc {|x| Qpid::Proton::Delivery.wrap(Cproton.pn_cast_pn_delivery(x))},
         "pn_transport" => proc {|x| Qpid::Proton::Transport.wrap(Cproton.pn_cast_pn_transport(x))},
         "pn_selectable" => proc {|x| Qpid::Proton::Selectable.wrap(Cproton.pn_cast_pn_selectable(x))},
-        "pn_reactor" => proc {|x| Qpid::Proton::Reactor::Reactor.wrap(Cproton.pn_cast_pn_reactor(x))},
-        "pn_task" => proc {|x| Qpid::Proton::Reactor::Task.wrap(Cproton.pn_cast_pn_task(x))},
       }
 
     def class_wrapper(clazz, c_impl, &block)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/lib/util/reactor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/reactor.rb b/proton-c/bindings/ruby/lib/util/reactor.rb
deleted file mode 100644
index 0bcb557..0000000
--- a/proton-c/bindings/ruby/lib/util/reactor.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-#--
-# 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::Proton::Util
-
-  module Reactor
-
-    def create_session(connection, handler = nil)
-      session = connection.session
-      session.open
-      return session
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0f03d826/proton-c/bindings/ruby/tests/old_examples/direct_send.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/old_examples/direct_send.rb b/proton-c/bindings/ruby/tests/old_examples/direct_send.rb
index 50543b2..c507b46 100644
--- a/proton-c/bindings/ruby/tests/old_examples/direct_send.rb
+++ b/proton-c/bindings/ruby/tests/old_examples/direct_send.rb
@@ -57,7 +57,8 @@ OptionParser.new do |opts|
 end.parse!
 
 begin
-  Qpid::Proton::Reactor::Container.new(SimpleSend.new(options[:address], options[:messages])).run
+  Qpid::Proton::Reactor::Container.new(SimpleSend.new(options[:address], options[:messages]), {:container_id=> "direct_send"}).run
+
 rescue Interrupt => error
   puts "ERROR: #{error}"
 end


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


[10/12] qpid-proton git commit: PROTON-1064: [ruby] tidy up delivery/dispolsition

Posted by ac...@apache.org.
PROTON-1064: [ruby] tidy up delivery/dispolsition

- Move constants to DeliveryState module
- Include DeliveryState constants in Delivery and Disposition
- Move Acking module methods to Delivery


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

Branch: refs/heads/master
Commit: db1cb9f125b74dc18a45e99115cfeeea386b16d8
Parents: de2d490
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 15:41:30 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/delivery.rb     | 48 ++++++-----
 proton-c/bindings/ruby/lib/core/disposition.rb  | 33 +++++---
 proton-c/bindings/ruby/lib/core/receiver.rb     |  2 +-
 proton-c/bindings/ruby/lib/handler/acking.rb    | 70 ----------------
 .../lib/handler/incoming_message_handler.rb     |  2 -
 proton-c/bindings/ruby/lib/qpid_proton.rb       |  4 +-
 proton-c/bindings/ruby/lib/util/constants.rb    | 85 --------------------
 7 files changed, 46 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/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 47b23d6..bb33207 100644
--- a/proton-c/bindings/ruby/lib/core/delivery.rb
+++ b/proton-c/bindings/ruby/lib/core/delivery.rb
@@ -38,6 +38,8 @@ module Qpid::Proton
   #
   class Delivery
 
+    include DeliveryState
+
     # @private
     include Util::Wrapper
 
@@ -121,14 +123,28 @@ module Qpid::Proton
     #
     proton_caller :settled?
 
+    # Update the state of the delivery
+    # @param state [Integer] the delivery state, defined in {DeliveryState}
+    def update(state) Cproton.pn_delivery_update(@impl, state); end
 
-    # @!method settle
-    #
-    # Settles a delivery.
-    #
-    #  A settled delivery can never be used again.
-    #
-    proton_caller :settle
+    # Settle a delivery, optionally update state before settling
+    # A settled delivery can never be used again.
+    # @param state [Integer] the delivery state, defined in {DeliveryState}
+    def settle(state = nil)
+      update(state) unless state.nil?
+      Cproton.pn_delivery_settle(@impl)
+    end
+
+    # Accept the receiveed message.
+    def accept() settle ACCEPTED; end
+
+    # Reject a received message that is considered invalid.
+    def reject() settle REJECTED; end
+
+    # FIXME aconway 2017-11-23: why the delivered argument?
+
+    # Release a received message making it available to other receivers.
+    def release(delivered = true) settle(delivered ? MODIFIED : RELEASED); end
 
     # @!method dump
     #
@@ -148,14 +164,6 @@ module Qpid::Proton
     #
     proton_caller :buffered?
 
-    def update(state)
-      impl = @local.impl
-      Codec::Data.from_object(Cproton.pn_disposition_data(impl), @local.data)
-      Codec::Data::from_object(Cproton.pn_disposition_annotations(impl), @local.annotations)
-      Condition.from_object(Cproton.pn_disposition_condition(impl), @local.condition)
-      Cproton.pn_delivery_update(@impl, state)
-    end
-
     # Returns the local disposition state for the delivery.
     #
     # @return [Disposition] The local disposition state.
@@ -172,16 +180,6 @@ module Qpid::Proton
       Cproton.pn_delivery_remote_state(@impl)
     end
 
-    # Returns the next delivery on the connection that has pending operations.
-    #
-    # @return [Delivery, nil] The next delivery, or nil if there are none.
-    #
-    # @see Connection#work_head
-    #
-    def work_next
-      Delivery.wrap(Cproton.pn_work_next(@impl))
-    end
-
     # Returns the parent link.
     #
     # @return [Link] The parent link.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/core/disposition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/disposition.rb b/proton-c/bindings/ruby/lib/core/disposition.rb
index 37f94a5..1f2c7fd 100644
--- a/proton-c/bindings/ruby/lib/core/disposition.rb
+++ b/proton-c/bindings/ruby/lib/core/disposition.rb
@@ -19,6 +19,26 @@
 
 module Qpid::Proton
 
+  # States of a delivery
+  module DeliveryState
+    # Message was successfully processed by the receiver
+    ACCEPTED = Cproton::PN_ACCEPTED
+
+    # Message rejected as invalid and unprocessable by the receiver.
+    REJECTED = Cproton::PN_REJECTED
+
+    # Message was not (and will not be) processed by the receiver, but may be
+    # acceptable if re-delivered to another receiver
+    RELEASED = Cproton::PN_RELEASED
+
+    # Like released, but the disposition includes modifications to be made to
+    # the message before re-delivery
+    MODIFIED = Cproton::PN_MODIFIED
+
+    # Partial message data was received, message can be resuemed - used only during link recovery.
+    RECEIVED =  Cproton::PN_RECEIVED
+  end
+
   # Disposition records the current state and/or final outcome of a transfer.
   #
   # Every delivery contains both a local and a remote disposition. The local
@@ -27,18 +47,7 @@ module Qpid::Proton
   #
   class Disposition
 
-    include Util::Constants
-
-    # Indicates the delivery was received.
-    self.add_constant(:RECEIVED, Cproton::PN_RECEIVED)
-    # Indicates the delivery was accepted.
-    self.add_constant(:ACCEPTED, Cproton::PN_ACCEPTED)
-    # Indicates the delivery was rejected.
-    self.add_constant(:REJECTED, Cproton::PN_REJECTED)
-    # Indicates the delivery was released.
-    self.add_constant(:RELEASED, Cproton::PN_RELEASED)
-    # Indicates the delivery was modified.
-    self.add_constant(:MODIFIED, Cproton::PN_MODIFIED)
+    include DeliveryState
 
     attr_reader :impl
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/core/receiver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/receiver.rb b/proton-c/bindings/ruby/lib/core/receiver.rb
index 2be36ab..df767e2 100644
--- a/proton-c/bindings/ruby/lib/core/receiver.rb
+++ b/proton-c/bindings/ruby/lib/core/receiver.rb
@@ -77,7 +77,7 @@ module Qpid::Proton
     # @param limit [Integer] The maximum bytes to receive.
     #
     # @return [Integer, nil] The number of bytes received, or nil if the end of
-    # the stream was reached.t
+    # the stream was reached.
     #
     # @see Deliver#pending To see how much buffer space is needed.
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/handler/acking.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/acking.rb b/proton-c/bindings/ruby/lib/handler/acking.rb
deleted file mode 100644
index 1c4f69d..0000000
--- a/proton-c/bindings/ruby/lib/handler/acking.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  # Mixing that provides methods for acknowledging a delivery.
-  #
-  module Acking
-
-    # Accept the receivered message.
-    #
-    # @param delivery [Qpid::Proton::Delivery] The delivery.
-    #
-    def accept(delivery)
-      self.settle(delivery, Qpid::Proton::Delivery::ACCEPTED)
-    end
-
-    # Rejects a received message that is considered invalid or unprocessable.
-    #
-    # @param delivery [Qpid::Proton::Delivery] The delivery.
-    #
-    def reject(delivery)
-      self.settle(delivery, Qpid::Proton::Delivery::REJECTED)
-    end
-
-    # Releases a received message, making it available at the source for any
-    # other interested receiver.
-    #
-    # @param delivery [Qpid::Proton::Delivery] The delivery
-    # @param delivered [Boolean] True if this was considered a delivery
-    #   attempt.
-    #
-    def release(delivery, delivered = true)
-      if delivered
-        self.settle(delivery, Qpid::Proton::Delivery::MODIFIED)
-      else
-        self.settle(delivery, Qpid::Proton::Delivery::RELEASED)
-      end
-    end
-
-    # Settles the specified delivery. Updates the delivery state if a state
-    # is specified.
-    #
-    # @param delivery [Qpid::Proton::Delivery] The delivery.
-    # @param state [Integer] The delivery state.
-    #
-    def settle(delivery, state = nil)
-      delivery.update(state) unless state.nil?
-      delivery.settle
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
index a64cffc..db0f6db 100644
--- a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
@@ -24,8 +24,6 @@ module Qpid::Proton::Handler
   #
   class IncomingMessageHandler
 
-    include Acking
-
     def initialize(auto_accept = true, delegate = nil)
       @delegate = delegate
       @auto_accept = auto_accept

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 4a1f677..b47b863 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -28,7 +28,7 @@ else
 end
 
 DEPRECATION = "[DEPRECATION]"
-def deprecated(old, new)
+def deprecated(old, new=nil)
   repl = new ? ", use `#{new}`" : "with no replacement"
   warn "#{DEPRECATION} `#{old}` is deprecated #{repl} (called from #{caller(2).first})"
 end
@@ -39,7 +39,6 @@ require "core/exceptions"
 # Utility classes
 require "util/version"
 require "util/error_handler"
-require "util/constants"
 require "util/swig_helper"
 require "util/wrapper"
 require "util/class_wrapper"
@@ -92,7 +91,6 @@ require "messenger/messenger"
 # Handler classes
 require "handler/c_adaptor"
 require "handler/wrapped_handler"
-require "handler/acking"
 require "handler/endpoint_state_handler"
 require "handler/incoming_message_handler"
 require "handler/outgoing_message_handler"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db1cb9f1/proton-c/bindings/ruby/lib/util/constants.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/constants.rb b/proton-c/bindings/ruby/lib/util/constants.rb
deleted file mode 100644
index 50225e6..0000000
--- a/proton-c/bindings/ruby/lib/util/constants.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-#--
-# 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::Proton::Util
-
-  # Provides a means for defining constant values within the namespace
-  # of a class.
-  #
-  # If the class has defined the class method, :post_add_constant, then that
-  # method will be invoked after each new item is added. It must be defined
-  # *before* any constants are defined.
-  #
-  # ==== Example
-  #
-  #   class GrammarComponent
-  #
-  #     include Qpid::Proton::Constants
-  #
-  #     def self.post_add_constant(key, value)
-  #       @terminal << value if value.terminal?
-  #       @nonterminal << value if !value.terminal? && !value.rule
-  #       @rule << value if value.rule
-  #     end
-  #
-  #     self.add_constant :LEFT_PARENTHESIS, new GrammarComponent("(", :terminal)
-  #     self.add_constant :RIGHT_PARENTHESIS, new GrammarComponent(")", :terminal)
-  #     self.add_constant :ELEMENT, new GrammarComponent("E", :rule)
-  #
-  #     def initialize(component, type)
-  #       @component = component
-  #       @type = type
-  #     end
-  #
-  #     def terminal?; @type == :terminal; end
-  #
-  #     def rule?; @type == :rule; end
-  #
-  #   end
-  #
-  # @private
-  #
-  module Constants
-
-    def self.included(base)
-      base.extend ClassMethods
-    end
-
-    module ClassMethods
-
-      def add_constant(key, value)
-        self.const_set(key, value)
-
-        @pn_by_value ||= {}
-        @pn_by_value[value] = key
-
-        if self.respond_to? :post_add_constant
-          self.post_add_constant(key, value)
-        end
-      end
-
-      def by_value(value)
-        (@pn_by_value || {})[value]
-      end
-
-    end
-
-  end
-
-end


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


[03/12] qpid-proton git commit: PROTON-1064: [ruby] Event handling refactor

Posted by ac...@apache.org.
PROTON-1064: [ruby] Event handling refactor

Event/handler/dispatch rework:
- No wrapped C handlers, native ruby handlers
- Simplified event class
- MessagingHandler pure interface, can be duck-typed
- Default handler logic moved to Handler::Adapter
- on_error catches unhandled on_xxx_error events
- on_unhandled catches all other unhandled events
- dropped ruby Collector wrapper - now internal to connection_driver.

Other changes
- Added close(error) for all endpoints to set condition on close
- Associate Connection with its Container
- Transport options: sasl, idle_timeout etc.
- Removed unused classes, corrected/clarified docs
- Connection_driver fixes - delegate proton closes to IO


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

Branch: refs/heads/master
Commit: b883393baae53bd59710c1c9595dab36139a8417
Parents: c4e5e58
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Nov 24 11:44:35 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/base_handler.rb |  31 --
 proton-c/bindings/ruby/lib/core/condition.rb    |   6 +-
 proton-c/bindings/ruby/lib/core/connection.rb   | 156 ++-------
 .../bindings/ruby/lib/core/connection_driver.rb |  53 ++--
 proton-c/bindings/ruby/lib/core/container.rb    |  16 +-
 proton-c/bindings/ruby/lib/core/delivery.rb     |  32 +-
 proton-c/bindings/ruby/lib/core/endpoint.rb     |  35 +-
 proton-c/bindings/ruby/lib/core/event.rb        | 151 +++++++++
 proton-c/bindings/ruby/lib/core/link.rb         |  16 +-
 proton-c/bindings/ruby/lib/core/message.rb      |  11 -
 .../bindings/ruby/lib/core/messaging_handler.rb | 261 +++++++--------
 proton-c/bindings/ruby/lib/core/sender.rb       |  11 +-
 proton-c/bindings/ruby/lib/core/session.rb      |  12 +-
 proton-c/bindings/ruby/lib/core/transport.rb    |  12 +-
 proton-c/bindings/ruby/lib/event/collector.rb   | 148 ---------
 proton-c/bindings/ruby/lib/event/event.rb       | 317 -------------------
 proton-c/bindings/ruby/lib/event/event_base.rb  |  91 ------
 proton-c/bindings/ruby/lib/event/event_type.rb  |  71 -----
 proton-c/bindings/ruby/lib/handler/adapter.rb   | 157 +++++++++
 proton-c/bindings/ruby/lib/handler/c_adaptor.rb |  47 ---
 .../ruby/lib/handler/c_flow_controller.rb       |  33 --
 .../ruby/lib/handler/endpoint_state_handler.rb  | 131 +-------
 .../ruby/lib/handler/flow_controller.rb         |  40 +++
 .../lib/handler/incoming_message_handler.rb     |  39 +--
 .../lib/handler/outgoing_message_handler.rb     |  57 +---
 .../ruby/lib/handler/wrapped_handler.rb         |  76 -----
 proton-c/bindings/ruby/lib/qpid_proton.rb       |  20 +-
 .../bindings/ruby/lib/util/class_wrapper.rb     |  52 ---
 proton-c/bindings/ruby/lib/util/handler.rb      |  41 ---
 proton-c/bindings/ruby/tests/test_adapter.rb    | 227 +++++++++++++
 .../ruby/tests/test_connection_driver.rb        |  14 +-
 proton-c/bindings/ruby/tests/test_container.rb  |  18 +-
 proton-c/bindings/ruby/tests/test_tools.rb      |  42 +--
 proton-c/include/proton/cproton.i               |   1 +
 34 files changed, 892 insertions(+), 1533 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/base_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/base_handler.rb b/proton-c/bindings/ruby/lib/core/base_handler.rb
deleted file mode 100644
index 9a7ece4..0000000
--- a/proton-c/bindings/ruby/lib/core/base_handler.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-#--
-# 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::Proton
-
-  class BaseHandler
-
-    # Override to process unhandled events.
-    #
-    def on_unhandled(method, *args)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/condition.rb b/proton-c/bindings/ruby/lib/core/condition.rb
index 9cd6eec..05231c6 100644
--- a/proton-c/bindings/ruby/lib/core/condition.rb
+++ b/proton-c/bindings/ruby/lib/core/condition.rb
@@ -58,7 +58,7 @@ module Qpid::Proton
     # - String-like: return String.try_convert(obj)
     # - nil: return nil
     # @raise ::ArgumentError if obj is not convertible to {Condition}
-    def self.convert(obj, default_name="proton")
+    def self.convert(obj, default_name="error")
       case obj
       when nil then nil
       when Condition then obj
@@ -76,9 +76,11 @@ module Qpid::Proton
     end
 
     private
-    def self.from_object(impl, cond)
+
+    def self.assign(impl, cond)
       Cproton.pn_condition_clear(impl)
       if cond
+        cond = self.convert(cond)
         Cproton.pn_condition_set_name(impl, cond.name) if cond.name
         Cproton.pn_condition_set_description(impl, cond.description) if cond.description
         Codec::Data.from_object(Cproton.pn_condition_info(impl), cond.info) if cond.info

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index d6ff029..25149ce 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -36,156 +36,68 @@ module Qpid::Proton
     #   @return [String] User name used for authentication (outgoing connection) or the authenticated user name (incoming connection)
     proton_accessor :user
 
-    # @private
-    proton_writer :password
+    private
 
-    # @private
+    proton_writer :password
     attr_accessor :overrides
-    # @private
     attr_accessor :session_policy
-
-    # @private
     include Util::Wrapper
 
-    # @private
     def self.wrap(impl)
       return nil if impl.nil?
-
       self.fetch_instance(impl, :pn_connection_attachments) || Connection.new(impl)
     end
 
-    # Constructs a new instance of Connection.
-    #
-    # You do *not* need to provide the underlying C struct, as this is
-    # automatically generated as needed. The argument is a convenience
-    # for returning existing Connection objects.
-    #
-    # @param impl [pn_connection_t] The pn_connection_t struct.
-    #
     def initialize(impl = Cproton.pn_connection)
       super()
       @impl = impl
       @overrides = nil
-      @collector = nil
       @session_policy = nil
       @link_count = 0
       @link_prefix = ""
       self.class.store_instance(self, :pn_connection_attachments)
     end
 
-    def overrides?
-      !@overrides.nil?
-    end
+    public
 
-    def session_policy?
-      !@session_policy.nil?
-    end
+    # @deprecated no replacement
+    def overrides?() deprecated __method__; false; end
 
-    # This method is used when working within the context of an event.
-    #
-    # @return [Connection] The connection itself.
-    #
-    def connection
-      self
-    end
+    # @deprecated no replacement
+    def session_policy?() deprecated __method__; false; end
 
-    # The Transport to which this connection is bound.
-    #
-    # @return [Transport] The transport, or nil if the Connection is unbound.
-    #
-    def transport
-      Transport.wrap(Cproton.pn_connection_transport(@impl))
-    end
+    # @return [Connection] self
+    def connection() self; end
 
-    # Associates the connection with an event collector.
-    #
-    # By doing this, key changes in the endpoint's state are reported to
-    # the connector via Event objects that can be inspected and processed.
+    # @return [Transport, nil] transport bound to this connection, or nil if unbound.
     #
-    # Note that, by registering a collector, the user is requesting that an
-    # indefinite number of events be queued up on its behalf. This means
-    # that, unless the application eventual processes these events, the
-    # storage requirements for keeping them will grow without bound. So be
-    # careful and do not register a collector with a connection unless the
-    # application will process the events.
-    #
-    # @param collector [Event::Collector] The event collector.
-    #
-    def collect(collector)
-      if collector.nil?
-        Cproton.pn_connection_collect(@impl, nil)
-      else
-        Cproton.pn_connection_collect(@impl, collector.impl)
-      end
-      @collector = collector
-    end
+    def transport() Transport.wrap(Cproton.pn_connection_transport(@impl)); end
 
-    # Get the AMQP container name advertised by the remote connection.
-    #
-    # This will return nil until the REMOTE_ACTIVE state is reached.
-    #
-    # @return [String] The remote connection's AMQP container name.
-    #
-    # @see #container
-    #
-    def remote_container
-      Cproton.pn_connection_remote_container(@impl)
-    end
+    # @return AMQP container ID advertised by the remote peer
+    def remote_container_id() Cproton.pn_connection_remote_container(@impl); end
 
-    # AMQP container ID string for the local end of the connection.
-    def container_id
-      Cproton.pn_connection_get_container(@impl)
-    end
+    alias :remote_container :remote_container_id
 
-    # Get the AMQP hostname set by the remote connection endpoint.
-    #
-    # This will return nil until the #REMOTE_ACTIVE state is
-    # reached.
-    #
-    # @return [String] The remote connection's AMQP hostname.
-    #
-    # @see #hostname
-    #
-    def remote_hostname
-      Cproton.pn_connection_remote_hostname(@impl)
-    end
+    # @return [Container] the container managing this connection
+    attr_reader :container
 
-    # Get the AMQP offered capabilities suppolied by the remote connection
-    # endpoint.
-    #
-    # This object returned is valid until the connection is freed. The Data
-    # object will be empty until the remote connection is opened, as
-    # indicated by the #REMOTE_ACTIVE flag.
-    #
-    # @return [Data] The offered capabilities.
-    #
+    # @return AMQP container ID for the local end of the connection
+    def container_id() Cproton.pn_connection_get_container(@impl); end
+
+    # @return [String] hostname used by the remote end of the connection
+    def remote_hostname() Cproton.pn_connection_remote_hostname(@impl); end
+
+    # @return [Array<Symbol>] offered capabilities provided by the remote peer
     def remote_offered_capabilities
-      # FIXME aconway 2017-11-22: doesn't match doc - returning object, not Data
       Codec::Data.to_object(Cproton.pn_connection_remote_offered_capabilities(@impl))
     end
 
-    # Get the AMQP desired capabilities supplied by the remote connection
-    # endpoint.
-    #
-    # The object returned is valid until the connection is freed. The Data
-    # object will be empty until the remote connection is opened, as
-    # indicated by the #REMOTE_ACTIVE flag.
-    #
-    # @return [Data] The desired capabilities.
-    #
+    # @return [Array<Symbol>] desired capabilities provided by the remote peer
     def remote_desired_capabilities
       Codec::Data.to_object(Cproton.pn_connection_remote_desired_capabilities(@impl))
     end
 
-    # Get the AMQP connection properties supplie by the remote connection
-    # endpoint.
-    #
-    # The object returned is valid until the connection is freed. The Data
-    # object will be empty until the remote connection is opened, as
-    # indicated by the #REMOTE_ACTIVE flag.
-    #
-    # @return [Data] The remote properties.
-    #
+    # @return [Hash] connection-properties provided by the remote peer
     def remote_properties
       Codec::Data.to_object(Cproton.pn_connection_remote_properites(@impl))
     end
@@ -213,7 +125,9 @@ module Qpid::Proton
       # NOTE: Only connection options are set here. Transport options are set
       # with {Transport#apply} from the connection_driver (or in
       # on_connection_bound if not using a connection_driver)
-      Cproton.pn_connection_set_container(@impl, opts[:container_id] || SecureRandom.uuid)
+      @container = opts[:container]
+      cid = opts[:container_id] || (@container && @container.id) || SecureRandom.uuid
+      Cproton.pn_connection_set_container(@impl, cid)
       Cproton.pn_connection_set_user(@impl, opts[:user]) if opts[:user]
       Cproton.pn_connection_set_password(@impl, opts[:password]) if opts[:password]
       @link_prefix = opts[:link_prefix] || container_id
@@ -227,16 +141,10 @@ module Qpid::Proton
       @link_prefix + "/" +  (@link_count += 1).to_s(16)
     end
 
-    # Closes the connection.
-    #
-    # Once this operation has completed, the #LOCAL_CLOSED state flag will be
-    # set.
-    #
-    def close(error = nil)
-      if error
-        @condition = Condition.convert error
-        self._update_condition
-      end
+    # Closes the local end of the connection. The remote end may or may not be closed.
+    # @param error [Condition] Optional error condition to send with the close.
+    def close(error=nil)
+      Condition.assign(_local_condition, error)
       Cproton.pn_connection_close(@impl)
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/connection_driver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection_driver.rb b/proton-c/bindings/ruby/lib/core/connection_driver.rb
index aeca133..1995f7d 100644
--- a/proton-c/bindings/ruby/lib/core/connection_driver.rb
+++ b/proton-c/bindings/ruby/lib/core/connection_driver.rb
@@ -65,7 +65,13 @@ module Qpid
       def finished?() Cproton.pn_connection_driver_finished(@impl); end
 
       # Get the next event to dispatch, nil if no events available
-      def event() Event::Event.wrap(Cproton.pn_connection_driver_next_event(@impl)); end
+      def event()
+        e = Cproton.pn_connection_driver_next_event(@impl)
+        Event.new(e) if e
+      end
+
+      # True if {#event} will return non-nil
+      def event?() Cproton.pn_connection_driver_has_event(@impl); end
 
       # Iterator for all available events
       def each_event()
@@ -119,19 +125,23 @@ module Qpid
       # transport will close itself once the protocol close is complete.
       #
       def close_write error=nil
-        return if Cproton.pn_connection_driver_write_closed(@impl)
-        set_error error if error
+        set_error error
         Cproton.pn_connection_driver_write_close(@impl)
-        @io.close_write
+        @io.close_write rescue nil # Allow double-close
       end
 
+      # Is the read side of the driver closed?
+      def read_closed?() Cproton.pn_connection_driver_read_closed(@impl); end
+
+      # Is the write side of the driver closed?
+      def write_closed?() Cproton.pn_connection_driver_read_closed(@impl); end
+
       # Disconnect the read side of the transport, without waiting for an AMQP
       # close frame. See comments on {#close_write}
       def close_read error=nil
-        return if Cproton.pn_connection_driver_read_closed(@impl)
-        set_error error if error
+        set_error error
         Cproton.pn_connection_driver_read_close(@impl)
-        @io.close_read
+        @io.close_read rescue nil # Allow double-close
       end
 
       # Disconnect both sides of the transport sending/waiting for AMQP close
@@ -143,10 +153,8 @@ module Qpid
 
       private
 
-      def set_error e
-        if cond = Condition.convert(e, "proton:io")
-          Cproton.pn_connection_driver_errorf(@impl, cond.name, "%s", cond.description)
-        end
+      def set_error err
+        transport.condition ||= Condition.convert(err, "proton:io") if err
       end
     end
 
@@ -160,32 +168,37 @@ module Qpid
       #   {#dispatch} and {#process}
       def initialize(io, handler)
         super(io)
-        @handler = handler || Handler::MessagingHandler.new
+        @handler = handler
+        @adapter = Handler::Adapter.try_convert(handler)
       end
 
+      # @return [MessagingHandler] The handler dispatched to by {#process}
       attr_reader :handler
 
       # Dispatch all events available from {#event} to {#handler}
-      # @param handlers [Enum<Handler::MessagingHandler>]
-      def dispatch()
-        each_event { |e| e.dispatch @handler }
+      def dispatch() each_event do |e|
+          e.dispatch self       # See private on_transport_ methods below
+          e.dispatch @adapter
+        end
       end
 
       # Do {#read}, {#tick}, {#write} and {#dispatch} without blocking.
-      #
-      # @param [Handle::MessagingHanlder] handler A handler to dispatch
-      #   events to.
       # @param [Time] now the current time
       # @return [Time] Latest time to call {#process} again for scheduled events,
       #   or nil if there are no scheduled events
       def process(now=Time.now)
         read
         next_tick = tick(now)
-        dispatch                # May generate more data to write
+        dispatch                # Generate data for write
         write
-        dispatch                # Make sure we consume all events
+        dispatch                # Consume all events
         return next_tick
       end
+
+      private
+      def on_transport_tail_closed(event) close_read; end
+      def on_transport_head_closed(event) close_write; end
+      def on_transport_authenticated(event) connection.user = transport.user; end
     end
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 28c394f..df89d1a 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -39,14 +39,6 @@ module Qpid::Proton
         transport.set_server if server
         transport.apply opts
         connection.apply opts
-        @container = container
-      end
-
-      def event
-        # Add a container to the event
-        e = super()
-        e.container = @container if e
-        e
       end
     end
 
@@ -237,11 +229,7 @@ module Qpid::Proton
         case task
 
         when :on_start
-          # TODO aconway 2017-11-27: proper syntesized events
-          event = Class.new do
-            def initialize(c) @container = c; end
-            attr_reader :container
-          end.new(self)
+          event = Event.new(nil, :on_start, self)
           @handler.on_start(event) if @handler.respond_to? :on_start
 
         when Container
@@ -329,7 +317,7 @@ module Qpid::Proton
 
     def connection_driver(io, opts=nil, server=false)
       opts ||= {}
-      opts[:container_id] ||= @id
+      opts[:container] = self
       opts[:handler] ||= @handler
       ConnectionTask.new(self, io, opts, server)
     end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/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 bb33207..a642a7b 100644
--- a/proton-c/bindings/ruby/lib/core/delivery.rb
+++ b/proton-c/bindings/ruby/lib/core/delivery.rb
@@ -123,6 +123,15 @@ module Qpid::Proton
     #
     proton_caller :settled?
 
+    # @!attribute [r] aborted?
+    #
+    # A delivery can be aborted before it is complete by the remote sender.
+    # The receiver must ignore the message and discard any partial data.
+    #
+    # @return [Boolean] Returns if a delivery is aborted.
+    #
+    proton_caller :aborted?
+
     # Update the state of the delivery
     # @param state [Integer] the delivery state, defined in {DeliveryState}
     def update(state) Cproton.pn_delivery_update(@impl, state); end
@@ -141,8 +150,6 @@ module Qpid::Proton
     # Reject a received message that is considered invalid.
     def reject() settle REJECTED; end
 
-    # FIXME aconway 2017-11-23: why the delivered argument?
-
     # Release a received message making it available to other receivers.
     def release(delivered = true) settle(delivered ? MODIFIED : RELEASED); end
 
@@ -262,6 +269,25 @@ module Qpid::Proton
       self.remote_state == Disposition::MODIFIED
     end
 
-  end
+    # @return true if the delivery has a complete incoming message ready to decode
+    def message?
+      readable? && !aborted? && !partial?
+    end
 
+    # Decode the message from the delivery into a new {Message}
+    # @raise [ProtonError] unless {#message?}
+    def message
+      if message?
+        m = Message.new
+        m.decode(link.receive(pending))
+        link.advance
+        m
+      else
+        status = [("not readable" if !readable?),
+                  ("aborted" if aborted?),
+                  ("partial" if partial?)].compact.join(", ")
+        raise ProtonError, "incoming delivery #{status}"
+      end
+    end
+  end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/endpoint.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/endpoint.rb b/proton-c/bindings/ruby/lib/core/endpoint.rb
index fe2eb7a..ea2b11f 100644
--- a/proton-c/bindings/ruby/lib/core/endpoint.rb
+++ b/proton-c/bindings/ruby/lib/core/endpoint.rb
@@ -33,7 +33,7 @@ module Qpid::Proton
   class Endpoint
 
     # The local connection is uninitialized.
-    LOCAL_UNINIT = Cproton::PN_LOCAL_UNINIT
+   LOCAL_UNINIT = Cproton::PN_LOCAL_UNINIT
     # The local connection is active.
     LOCAL_ACTIVE = Cproton::PN_LOCAL_ACTIVE
     # The local connection is closed.
@@ -47,32 +47,17 @@ module Qpid::Proton
     REMOTE_CLOSED = Cproton::PN_REMOTE_CLOSED
 
     # Bitmask for the local-only flags.
-    LOCAL_MASK = Cproton::PN_LOCAL_UNINIT |
-                 Cproton::PN_LOCAL_ACTIVE |
-                 Cproton::PN_LOCAL_CLOSED
+    LOCAL_MASK = Cproton::PN_LOCAL_UNINIT | Cproton::PN_LOCAL_ACTIVE | Cproton::PN_LOCAL_CLOSED
 
     # Bitmask for the remote-only flags.
-    REMOTE_MASK = Cproton::PN_REMOTE_UNINIT |
-                  Cproton::PN_REMOTE_ACTIVE |
-                  Cproton::PN_REMOTE_CLOSED
+    REMOTE_MASK = Cproton::PN_REMOTE_UNINIT | Cproton::PN_REMOTE_ACTIVE | Cproton::PN_REMOTE_CLOSED
 
     # @private
-    def initialize
-      @condition = nil
-    end
-
+    def condition; remote_condition || local_condition; end
     # @private
-    def _update_condition
-      Condition.from_object(self._local_condition, @condition)
-    end
-
-    def condition
-      Condition.convert(_local_condition) || remote_condition; end
-
+    def remote_condition; Condition.convert(_remote_condition); end
     # @private
-    def remote_condition
-      Condition.convert(_remote_condition)
-    end
+    def local_condition; Condition.convert(_local_condition); end
 
     # Return the transport associated with this endpoint.
     #
@@ -96,7 +81,7 @@ module Qpid::Proton
       check_state(LOCAL_UNINIT)
     end
 
-    def local_active?
+    def local_open?
       check_state(LOCAL_ACTIVE)
     end
 
@@ -108,12 +93,16 @@ module Qpid::Proton
       check_state(REMOTE_UNINIT)
     end
 
-    def remote_active?
+    def remote_open?
       check_state(REMOTE_ACTIVE)
     end
 
     def remote_closed?
       check_state(REMOTE_CLOSED)
     end
+
+    alias local_active? local_open?
+    alias remote_active? remote_open?
+
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/event.rb b/proton-c/bindings/ruby/lib/core/event.rb
new file mode 100644
index 0000000..136c120
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/core/event.rb
@@ -0,0 +1,151 @@
+#--
+# 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::Proton
+  # AMQP protocol event.
+  #
+  # Includes a method name to call when the event is dispatched, and the context
+  # objects relevant to the event.
+  class Event
+    private
+
+    include Qpid::Proton::Util::Wrapper
+
+    EVENT_TYPE_NAMES = [:PN_EVENT_NONE,
+                        :PN_CONNECTION_INIT,
+                        :PN_CONNECTION_BOUND,
+                        :PN_CONNECTION_UNBOUND,
+                        :PN_CONNECTION_LOCAL_OPEN,
+                        :PN_CONNECTION_REMOTE_OPEN,
+                        :PN_CONNECTION_LOCAL_CLOSE,
+                        :PN_CONNECTION_REMOTE_CLOSE,
+                        :PN_CONNECTION_FINAL,
+                        :PN_SESSION_INIT,
+                        :PN_SESSION_LOCAL_OPEN,
+                        :PN_SESSION_REMOTE_OPEN,
+                        :PN_SESSION_LOCAL_CLOSE,
+                        :PN_SESSION_REMOTE_CLOSE,
+                        :PN_SESSION_FINAL,
+                        :PN_LINK_INIT,
+                        :PN_LINK_LOCAL_OPEN,
+                        :PN_LINK_REMOTE_OPEN,
+                        :PN_LINK_LOCAL_CLOSE,
+                        :PN_LINK_REMOTE_CLOSE,
+                        :PN_LINK_LOCAL_DETACH,
+                        :PN_LINK_REMOTE_DETACH,
+                        :PN_LINK_FLOW,
+                        :PN_LINK_FINAL,
+                        :PN_DELIVERY,
+                        :PN_TRANSPORT,
+                        :PN_TRANSPORT_AUTHENTICATED,
+                        :PN_TRANSPORT_ERROR,
+                        :PN_TRANSPORT_HEAD_CLOSED,
+                        :PN_TRANSPORT_TAIL_CLOSED,
+                        :PN_TRANSPORT_CLOSED]
+
+    TYPE_METHODS = EVENT_TYPE_NAMES.each_with_object({}) do |n, h|
+      type = Cproton.const_get(n)
+      h[type] = "on_#{Cproton.pn_event_type_name(type)[3..-1]}".downcase.to_sym
+    end
+
+    # Use Event.new(impl) to wrap a C event, or Event.new(nil, method, context)
+    # to create a pure-ruby event.
+    def initialize(impl, method=nil, context=nil)
+      @impl, @method, @context = impl, method, context
+      @method ||= TYPE_METHODS[Cproton.pn_event_type(@impl)] if @impl
+    end
+
+    def get(clazz, method=nil)
+      (ctx = context).is_a?(clazz) ? ctx : ctx.__send__(method) rescue nil
+    end
+
+    def _context
+      x = Cproton.pn_event_context(@impl)
+      case Cproton.pn_class_id(Cproton.pn_event_class(@impl))
+      when Cproton::CID_pn_transport then Transport.wrap(Cproton.pn_cast_pn_transport(x))
+      when Cproton::CID_pn_connection then Connection.wrap(Cproton.pn_cast_pn_connection(x))
+      when Cproton::CID_pn_session then Session.wrap(Cproton.pn_cast_pn_session(x))
+      when Cproton::CID_pn_link then Link.wrap(Cproton.pn_cast_pn_link(x))
+      when Cproton::CID_pn_delivery then Delivery.wrap(Cproton.pn_cast_pn_delivery(x))
+      else raise TypeError, "bad class-id #{pn_class_id(Cproton.pn_event_class(impl))}"
+      end
+    end
+
+    public
+
+    # Call handler.{#method}(self) if handler.respond_to? {#method}
+    # @return [Boolean] true if handler responded to the method, nil if not.
+    def dispatch(handler)
+      (handler.__send__(@method, self); true) if handler.respond_to? @method
+    end
+
+    # @return [Symbol] method name that this event will call in {#dispatch}
+    attr_accessor :method
+
+    alias :type :method
+
+    # @return [Object] the event context object
+    def context; return @context ||= _context; end
+
+    # @return [Container, nil] container for this event
+    def container() @container ||= get(Container, :container); end
+
+    # @return [Transport, nil] transport for this event
+    def transport() @transport ||= get(Transport, :transport); end
+
+    # @return [Connection, nil] the connection for this event
+    def connection() @connection ||= get(Connection, :connection); end
+
+    # @return [Session, nil] session for this event
+    def session() @session ||= get(Session, :session); end
+
+    # @return [Link, nil] link for this event
+    def link() @link ||= get(Link, :link); end
+
+    # @return [Sender, nil] sender associated with this event
+    def sender() link if link && link.sender?; end
+
+    # @return [Receiver, nil] receiver associated with this event
+    def receiver() link if link && link.receiver?; end
+
+    # @return [Delivery, nil] delivery for this event
+    def delivery() @delivery ||= get(Delivery); end
+
+    # @return [Tracker, nil] delivery for this event
+    def tracker() delivery; end
+
+    # @return [Message, nil] message for this event
+    def message() @message ||= delivery.message if delivery; end
+
+    def to_s() "#{self.class}(#{method}, #{context})"; end
+    def inspect() "#{self.class}(#{method.inspect}, #{context.inspect})"; end
+
+    # @return [Condition] Error condition associated with this event or nil if none.
+    def condition
+      (context.remote_condition if context.respond_to? :remote_condition) ||
+        (context.condition if context.respond_to? :condition)
+    end
+
+    # @deprecated use {#container}
+    def reactor() deprecated __method__, :container; container; end
+
+    # @deprecated use {Qpid::Proton::Event}
+    Event = self
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/link.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/link.rb b/proton-c/bindings/ruby/lib/core/link.rb
index 97f30f6..255e8b2 100644
--- a/proton-c/bindings/ruby/lib/core/link.rb
+++ b/proton-c/bindings/ruby/lib/core/link.rb
@@ -58,16 +58,12 @@ module Qpid::Proton
     # @see Endpoint::LOCAL_ACTIVE
     proton_caller :open
 
-    # @!method close
-    #
-    # Closes the link.
-    #
-    # Once this operation has completed, the state flag will be set.
-    # This may be called without first calling #open, which is the equivalent to
-    # calling #open and then #close.
-    #
-    # @see Endpoint::LOCAL_CLOSED
-    proton_caller :close
+    # Close the local end of the link. The remote end may or may not be closed.
+    # @param error [Condition] Optional error condition to send with the close.
+    def close(error=nil)
+      Condition.assign(_local_condition, error)
+      Cproton.pn_link_close(@impl)
+    end
 
     # @!method detach
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index ae0f9d1..747414c 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -51,17 +51,6 @@ module Qpid::Proton
       post_decode
     end
 
-    # Receive and decode a message from a delivery.
-    #
-    # @param delivery [Delivery] the delivery
-    # @return [Integer] the number of bytes decoded
-    def receive(delivery)
-      raise RangeError, "delivery is incomplete" if delivery.partial?
-      n = decode(delivery.link.receive(delivery.pending))
-      delivery.link.advance
-      return n
-    end
-
     def post_decode # :nodoc:
       # decode elements from the message
       @properties = {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/messaging_handler.rb b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
index 3babc05..b6b07c7 100644
--- a/proton-c/bindings/ruby/lib/core/messaging_handler.rb
+++ b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
@@ -19,198 +19,157 @@
 
 module Qpid::Proton
 
-  # A general purpose handler that simplifies processing events.
+  # A handler for AMQP messaging events.
+  #
+  # Subclass the handler and provide the #on_xxx methods with your event-handling code.
   #
   class MessagingHandler
 
-    attr_reader :handlers
-
-    # Creates a new instance.
-    #
-    # @param [Integer] prefetch
-    # @param [Boolean] auto_accept
-    # @param [Boolean] auto_settle
-    # @param [Boolean] peer_close_is_error
-    #
-    def initialize(prefetch = 10, auto_accept = true, auto_settle = true, peer_close_is_error = false)
-      @handlers = Array.new
-      @handlers << Handler::CFlowController.new(prefetch) unless prefetch.zero?
-      @handlers << Handler::EndpointStateHandler.new(peer_close_is_error, self)
-      @handlers << Handler::IncomingMessageHandler.new(auto_accept, self)
-      @handlers << Handler::OutgoingMessageHandler.new(auto_settle,self)
-    end
-
+    # @overload initialize(opts)
+    #   Create a {MessagingHandler} with options +opts+
+    #   @option opts [Integer] :prefetch (10)
+    #    The number of messages to  fetch in advance, 0 disables prefetch.
+    #   @option opts [Boolean] :auto_accept  (true)
+    #    If true, incoming messages are accepted automatically after {#on_message}.
+    #    If false, the application can accept, reject or release the message
+    #    by calling methods on {Delivery} when the message has been processed.
+    #   @option opts [Boolean] :auto_settle (true) If true, outgoing
+    #    messages are settled automatically when the remote peer settles. If false,
+    #    the application must call {Delivery#settle} explicitly.
+    #   @option opts [Boolean] :auto_open (true)
+    #    If true, incoming connections are  opened automatically.
+    #    If false, the application must call {Connection#open} to open incoming connections.
+    #   @option opts [Boolean] :auto_close (true)
+    #    If true, respond to a remote close automatically with a local close.
+    #    If false, the application must call {Connection#close} to finish closing connections.
+    #   @option opts [Boolean] :peer_close_is_error (false)
+    #    If true, and the remote peer closes the connection without an error condition,
+    #    the set the local error condition {Condition}("error", "unexpected peer close")
+    #
+    # @overload initialize(prefetch=10, auto_accept=true, auto_settle=true, peer_close_is_error=false)
+    #   @deprecated use +initialize(opts)+ overload
+    def initialize(*args)
+      @options = {}
+      if args.size == 1 && args[0].is_a?(Hash)
+        @options.replace(args[0])
+      else                      # Fill options from deprecated fixed arguments
+        [:prefetch, :auto_accept, :auto_settle, :peer_close_is_error].each do |k|
+          opts[k] = args.shift unless args.empty?
+        end
+      end
+      # NOTE: the options are processed by {Handler::Adapater}
+    end
+
+    public
+
+    # @private
+    # @return [Hash] handler options, see {#initialize}
+    attr_reader :options
+
+
+    # @!method on_transport_error(event)
+    # Called when the transport fails or closes unexpectedly.
+    # @param event [Event] The event.
+
+    # !@method on_connection_error(event)
     # Called when the peer closes the connection with an error condition.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_error(event)
-      Handler::EndpointStateHandler.print_error(event.connection, "connection")
-    end
+    # @param event [Event] The event.
 
-      # Called when the peer closes the session with an error condition.
-      #
-      # @param event [Qpid:Proton::Event::Event] The event.
-      #
-    def on_session_error(event)
-      Handler::EndpointStateHandler.print_error(event.session, "session")
-      event.connection.close
-    end
+    # @!method on_session_error(event)
+    # Called when the peer closes the session with an error condition.
+    # @param event [Qpid:Proton::Event] The event.
 
+    # @!method on_link_error(event)
     # Called when the peer closes the link with an error condition.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_error(event)
-      Handler::EndpointStateHandler.print_error(event.link, "link")
-      event.connection.close
-    end
-
-    # Called when the event loop starts.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_reactor_init(event)
-      self.on_start(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_start(event)
     # Called when the event loop starts.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_start(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_connection_closed(event)
     # Called when the connection is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_closed(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_session_closed(event)
     # Called when the session is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_session_closed(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_link_closed(event)
     # Called when the link is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_closed(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_connection_closing(event)
     # Called when the peer initiates the closing of the connection.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_closing(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_session_closing(event)
     # Called when the peer initiates the closing of the session.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_session_closing(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_link_closing(event)
     # Called when the peer initiates the closing of the link.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_closing(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_disconnected(event)
     # Called when the socket is disconnected.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_disconnected(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_sendable(event)
     # Called when the sender link has credit and messages can therefore
     # be transferred.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_sendable(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_accepted(event)
     # Called when the remote peer accepts an outgoing message.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_accepted(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_rejected(event)
     # Called when the remote peer rejects an outgoing message.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_rejected(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_released(event)
     # Called when the remote peer releases an outgoing message.
-    #
     # Note that this may be in response to either the RELEASE or
     # MODIFIED state as defined by the AMPQ specification.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_released(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_settled(event)
     # Called when the remote peer has settled hte outgoing message.
-    #
     # This is the point at which it should never be retransmitted.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_settled(event)
-    end
+    # @param event [Event] The event.
 
+    # @!method on_message(event)
     # Called when a message is received.
     #
-    # The message itself can be obtained as a property on the event. For
-    # the purpose of referring to this message in further actions, such as
-    # explicitly accepting it) the delivery should be used. This is also
-    # obtainable vi a property on the event.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_message(event)
-    end
+    # The message is available from {Event#message}, to accept or reject the message
+    # use {Event#delivery}
+    # @param event [Event] The event.
+
+    # @!method on_aborted(event)
+    # Called when message delivery is aborted by the sender.
+    # The {Event#delivery} provides information about the delivery, but the message should be ignored.
+
+    # @!method on_error(event)
+    # If +on_xxx_error+ method is missing, {#on_error} is called instead.
+    # If {#on_error} is missing, the connection is closed with the error.
+    # @param event [Event] the event, {Event#method} provides the original method name.
 
+    # @!method on_unhandled(event)
+    # If an +on_xxx+ method is missing, {#on_unhandled} is called instead.
+    # @param event [Event] the event, {Event#method} provides the original method name.
   end
 
+  # An array of {MessagingHandler}, events are dispatched to each in turn
+  class MessagingHandlers < MessagingHandler
+    include Enumerable
+
+    # @param handlers an array of {MessagingHandler} objects
+    def initialize handlers; @handlers = handlers; end
+
+    def each(*args, &block) @handlers.each(*args, &block); end
+
+    def on_unhandled(event) each { |h| event.dispatch h }; end
+
+  end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/sender.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/sender.rb b/proton-c/bindings/ruby/lib/core/sender.rb
index deeb0c5..dddde15 100644
--- a/proton-c/bindings/ruby/lib/core/sender.rb
+++ b/proton-c/bindings/ruby/lib/core/sender.rb
@@ -39,10 +39,10 @@ module Qpid::Proton
       Cproton.pn_link_offered(@impl, n)
     end
 
-    # Sends the specified data to the remote endpoint.
+    # Send a message to the remote endpoint.
     #
-    # @param object [Object] The content to send.
-    # @param tag [Object] The tag
+    # @param message [Message] The message to send.
+    # @param tag [Object] Optional unique delivery tag, one will be generated if not supplied.
     #
     # @return [Integer] The number of bytes sent.
     #
@@ -56,7 +56,7 @@ module Qpid::Proton
 
     # Send the specified bytes as part of the current delivery.
     #
-    # @param bytes [Array] The bytes to send.
+    # @param bytes [String] The bytes to send.
     #
     # @return [Integer] The number of bytes sent.
     #
@@ -64,11 +64,12 @@ module Qpid::Proton
       Cproton.pn_link_send(@impl, bytes)
     end
 
+    # Generate a new unique delivery tag for this sender
     def delivery_tag
       @tag_count ||= 0
       result = @tag_count.succ
       @tag_count = result
-      return "#{result}"
+      return result.to_s(32) # Base 32 compactness
     end
 
   end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/session.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/session.rb b/proton-c/bindings/ruby/lib/core/session.rb
index 2c1faeb..6bed0ba 100644
--- a/proton-c/bindings/ruby/lib/core/session.rb
+++ b/proton-c/bindings/ruby/lib/core/session.rb
@@ -87,14 +87,10 @@ module Qpid::Proton
       self.class.store_instance(self, :pn_session_attachments)
     end
 
-    # Closed the session.
-    #
-    # Once this operation has completed, the state flag will be set. This may be
-    # called without calling #open, in which case it is the equivalence of
-    # calling #open and then close immediately.
-    #
-    def close
-      self._update_condition
+    # Close the local end of the session. The remote end may or may not be closed.
+    # @param error [Condition] Optional error condition to send with the close.
+    def close(error=nil)
+      Condition.assign(_local_condition, error)
       Cproton.pn_session_close(@impl)
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index 7589788..9b12be3 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -234,7 +234,7 @@ module Qpid::Proton
     # Set the error condition for the transport.
     # @param c [Condition] The condition to set
     def condition=(c)
-      Condition.from_object(Cproton.pn_transport_condition(@impl), Condition.convert(c))
+      Condition.assign(Cproton.pn_transport_condition(@impl), c)
     end
 
     # Binds to the given connection.
@@ -395,10 +395,14 @@ module Qpid::Proton
 
     # @private
     def apply opts
-      if opts[:sasl_enabled] != false # SASL is not disabled.
-        sasl.allow_insecure_mechs = opts[:sasl_allow_insecure_mechs] if opts[:sasl_allow_insecure_mechs]
-        sasl.allowed_mechs = opts[:sasl_allowed_mechs] if opts[:sasl_allowed_mechs]
+      sasl if opts[:sasl_enabled]                                 # Explicitly enabled
+      unless opts.include?(:sasl_enabled) && !opts[:sasl_enabled] # Not explicitly disabled
+        sasl.allowed_mechs = opts[:sasl_allowed_mechs] if opts.include? :sasl_allowed_mechs
+        sasl.allow_insecure_mechs = opts[:sasl_allow_insecure_mechs] if opts.include? :sasl_allow_insecure_mechs
       end
+      self.channel_max= opts[:channel_max] if opts.include? :channel_max
+      self.max_frame_size= opts[:max_frame_size] if opts.include? :max_frame_size
+      self.idle_timeout= opts[:idle_timeout] if opts.include? :idle_timeout
     end
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/event/collector.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/collector.rb b/proton-c/bindings/ruby/lib/event/collector.rb
deleted file mode 100644
index 74e0182..0000000
--- a/proton-c/bindings/ruby/lib/event/collector.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-#--
-# 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::Proton::Event
-
-  # A Collector is used to register interest in events produced by one
-  # or more Connection objects.
-  #
-  # == Events
-  #
-  # @see Qpid::Proton::Event The list of predefined events.
-  #
-  # @example
-  #
-  #   conn = Qpid::Proton::Connection.new
-  #   coll = Qpid::Proton::Event::Collector.new
-  #   conn.collect(coll)
-  #
-  #   # transport setup not included here for brevity
-  #
-  #   loop do
-  #
-  #      # wait for an event and then perform the following
-  #
-  #      event = collector.peek
-  #
-  #      unless event.nil?
-  #        case event.type
-  #
-  #        when Qpid::Proton::Event::CONNECTION_REMOTE_CLOSE
-  #          conn = event.context # the context here is the connection
-  #          # the remote connection closed, so only close our side if it's
-  #          # still open
-  #          if !(conn.state & Qpid::Proton::Endpoint::LOCAL_CLOSED)
-  #            conn.close
-  #          end
-  #
-  #        when Qpid::proton::Event::SESSION_REMOTE_OPEN
-  #          session = event.session # the context here is the session
-  #          # the remote session is now open, so if the local session is
-  #          # uninitialized, then open it
-  #          if session.state & Qpid::Proton::Endpoint::LOCAL_UNINIT
-  #            session.incoming_capacity = 1000000
-  #            session.open
-  #          end
-  #
-  #        end
-  #
-  #       # remove the processed event and get the next event
-  #       # the loop will exit when we have no more events to process
-  #       collector.pop
-  #       event = collector.peek
-  #
-  #   end
-  #
-  class Collector
-
-    # @private
-    attr_reader :impl
-
-    # Creates a new Collector.
-    #
-    def initialize
-      @impl = Cproton.pn_collector
-      ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
-    end
-
-    # @private
-    def self.finalize!(impl)
-      proc {
-        Cproton.pn_collector_free(impl)
-      }
-    end
-
-    # Releases the collector.
-    #
-    # Once in a released state, a collector will drain any internally queued
-    # events, shrink its memory footprint to a minimu, and discard any newly
-    # created events.
-    #
-    def release
-      Cproton.pn_collector_release(@impl)
-    end
-
-    # Place a new event on the collector.
-    #
-    # This operation will create a new event of the given type and context
-    # and return a new Event instance. In some cases an event of a given
-    # type can be elided. When this happens, this operation will return
-    # nil.
-    #
-    # @param context [Object] The event context.
-    # @param event_type [EventType] The event type.
-    #
-    # @return [Event] the event if it was queued
-    # @return [nil] if it was elided
-    #
-    def put(context, event_type)
-      Cproton.pn_collector_put(@impl, Cproton.pn_class(context.impl), context.impl, event_type.number)
-    end
-
-    # Access the head event.
-    #
-    # This operation will continue to return the same event until it is
-    # cleared by using #pop. The pointer return by this  operation will be
-    # valid until ::pn_collector_pop is invoked or #free is called, whichever
-    # happens sooner.
-    #
-    # @return [Event] the head event
-    # @return [nil] if there are no events
-    #
-    # @see #pop
-    # @see #put
-    #
-    def peek
-      Event.wrap(Cproton.pn_collector_peek(@impl))
-    end
-
-    # Clear the head event.
-    #
-    # @return [Boolean] true if an event was removed
-    #
-    # @see #release
-    # @see #peek
-    #
-    def pop
-      Cproton.pn_collector_pop(@impl)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/event/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event.rb b/proton-c/bindings/ruby/lib/event/event.rb
deleted file mode 100644
index 92f7eb7..0000000
--- a/proton-c/bindings/ruby/lib/event/event.rb
+++ /dev/null
@@ -1,317 +0,0 @@
-#--
-# 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::Proton
-
-  module Event
-
-    # @private
-    def self.event_type(const_name, method_name = nil) # :nodoc:
-      unless Cproton.const_defined?(const_name)
-        raise RuntimeError.new("no such constant: #{const_name}")
-      end
-
-      const_value = Cproton.const_get(const_name)
-      method_name = "on_#{const_name.to_s[3..-1]}".downcase if method_name.nil?
-
-      EventType.new(const_value, method_name)
-    end
-
-    # Defined as a programming convenience. No even of this type will ever
-    # be generated.
-    NONE = event_type(:PN_EVENT_NONE)
-
-    # A reactor has been started.
-    REACTOR_INIT = event_type(:PN_REACTOR_INIT)
-    # A reactor has no more events to process.
-    REACTOR_QUIESCED = event_type(:PN_REACTOR_QUIESCED)
-    # A reactor has been stopred.
-    REACTOR_FINAL = event_type(:PN_REACTOR_FINAL)
-
-    # A timer event has occurred.
-    TIMER_TASK = event_type(:PN_TIMER_TASK)
-
-    # A connection has been created. This is the first even that will ever
-    # be issued for a connection.
-    CONNECTION_INIT = event_type(:PN_CONNECTION_INIT)
-    # A conneciton has been bound toa  transport.
-    CONNECTION_BOUND = event_type(:PN_CONNECTION_BOUND)
-    # A connection has been unbound from its transport.
-    CONNECTION_UNBOUND = event_type(:PN_CONNECTION_UNBOUND)
-    # A local connection endpoint has been opened.
-    CONNECTION_LOCAL_OPEN = event_type(:PN_CONNECTION_LOCAL_OPEN)
-    # A local connection endpoint has been closed.
-    CONNECTION_LOCAL_CLOSE = event_type(:PN_CONNECTION_LOCAL_CLOSE)
-    # A remote endpoint has opened its connection.
-    CONNECTION_REMOTE_OPEN = event_type(:PN_CONNECTION_REMOTE_OPEN)
-    # A remote endpoint has closed its connection.
-    CONNECTION_REMOTE_CLOSE = event_type(:PN_CONNECTION_REMOTE_CLOSE)
-    # A connection has been freed and any outstanding processing has been
-    # completed. This is the final event htat will ever be issued for a
-    # connection
-    CONNECTION_FINAL = event_type(:PN_CONNECTION_FINAL)
-
-    # A session has been created. This is the first event that will ever be
-    # issues for a session.
-    SESSION_INIT = event_type(:PN_SESSION_INIT)
-    # A local session endpoint has been opened.
-    SESSION_LOCAL_OPEN = event_type(:PN_SESSION_LOCAL_OPEN)
-    # A local session endpoint has been closed.
-    SESSION_LOCAL_CLOSE = event_type(:PN_SESSION_LOCAL_CLOSE)
-    # A remote endpoint has opened its session.
-    SESSION_REMOTE_OPEN = event_type(:PN_SESSION_REMOTE_OPEN)
-    # A remote endpoint has closed its session.
-    SESSION_REMOTE_CLOSE = event_type(:PN_SESSION_REMOTE_CLOSE)
-    # A session has been freed and any outstanding processing has been
-    # completed. This is the final event that will ever be issued for a
-    # session
-    SESSION_FINAL = event_type(:PN_SESSION_FINAL)
-
-    # A link has been created. This is the first event that will ever be
-    # issued for a link.
-    LINK_INIT = event_type(:PN_LINK_INIT)
-    # A local link endpoint has been opened.
-    LINK_LOCAL_OPEN = event_type(:PN_LINK_LOCAL_OPEN)
-    # A local link endpoint has been closed.
-    LINK_LOCAL_CLOSE = event_type(:PN_LINK_LOCAL_CLOSE)
-    # A local link endpoint has been detached.
-    LINK_LOCAL_DETACH = event_type(:PN_LINK_LOCAL_DETACH)
-    # A remote endpoint has opened its link.
-    LINK_REMOTE_OPEN = event_type(:PN_LINK_REMOTE_OPEN)
-    # A remote endpoint has closed its link.
-    LINK_REMOTE_CLOSE = event_type(:PN_LINK_REMOTE_CLOSE)
-    # A remote endpoint has detached its link.
-    LINK_REMOTE_DETACH = event_type(:PN_LINK_REMOTE_DETACH)
-    # The flow control state for a link has changed.
-    LINK_FLOW = event_type(:PN_LINK_FLOW)
-    # A link has been freed and any outstanding processing has been completed.
-    # This is the final event htat will ever be issued for a link.
-    LINK_FINAL = event_type(:PN_LINK_FINAL)
-
-    # A delivery has been created or updated.
-    DELIVERY = event_type(:PN_DELIVERY)
-
-    # A transport has new data to read and/or write.
-    TRANSPORT = event_type(:PN_TRANSPORT)
-    # Indicates that a transport error has occurred.
-    # @see Transport#condition To access the details of the error.
-    TRANSPORT_ERROR = event_type(:PN_TRANSPORT_ERROR)
-    # Indicates that the head of a transport has been closed. This means the
-    # transport will never produce more bytes for output to the network.
-    TRANSPORT_HEAD_CLOSED = event_type(:PN_TRANSPORT_HEAD_CLOSED)
-    # Indicates that the trail of a transport has been closed. This means the
-    # transport will never be able to process more bytes from the network.
-    TRANSPORT_TAIL_CLOSED = event_type(:PN_TRANSPORT_TAIL_CLOSED)
-    # Indicates that both the head and tail of a transport are closed.
-    TRANSPORT_CLOSED = event_type(:PN_TRANSPORT_CLOSED)
-
-    SELECTABLE_INIT = event_type(:PN_SELECTABLE_INIT)
-    SELECTABLE_UPDATED = event_type(:PN_SELECTABLE_UPDATED)
-    SELECTABLE_READABLE = event_type(:PN_SELECTABLE_READABLE)
-    SELECTABLE_WRITABLE = event_type(:PN_SELECTABLE_WRITABLE)
-    SELECTABLE_EXPIRED = event_type(:PN_SELECTABLE_EXPIRED)
-    SELECTABLE_ERROR = event_type(:PN_SELECTABLE_ERROR)
-    SELECTABLE_FINAL = event_type(:PN_SELECTABLE_FINAL)
-
-    # An Event provides notification of a state change within the protocol
-    # engine.
-    #
-    # Every event has a type that identifies what sort of state change has
-    # occurred, along with a pointer to the object whose state has changed,
-    # and also any associated objects.
-    #
-    # For more details on working with Event, please refer to Collector.
-    #
-    # @see Qpid::Proton::Event The list of predefined events.
-    #
-    class Event < EventBase
-
-      # @private
-      include Qpid::Proton::Util::ClassWrapper
-      # @private
-      include Qpid::Proton::Util::Wrapper
-
-      # Creates a Ruby object for the given pn_event_t.
-      #
-      # @private
-      def self.wrap(impl, number = nil)
-        return nil if impl.nil?
-
-        result = self.fetch_instance(impl, :pn_event_attachments)
-        return result unless result.nil?
-        number = Cproton.pn_event_type(impl) if number.nil?
-        event = Event.new(impl, number)
-        return event.context if event.context.is_a? EventBase
-        return event
-      end
-
-      # @private
-      def initialize(impl, number)
-        @impl = impl
-        class_name = Cproton.pn_class_name(Cproton.pn_event_class(impl))
-        context = class_wrapper(class_name, Cproton.pn_event_context(impl))
-        event_type = EventType.by_type(Cproton.pn_event_type(impl))
-        super(class_name, context, event_type)
-        @type = EventType.by_type(number)
-        self.class.store_instance(self, :pn_event_attachments)
-      end
-
-      # Notifies the handler(s) of this event.
-      #
-      # If a handler responds to the event's method then that method is invoked
-      # and passed the event. Otherwise, if the handler defines the
-      # +on_unhandled+ method, then that will be invoked instead.
-      #
-      # If the handler defines a +handlers+ method then that will be invoked and
-      # passed the event afterward.
-      #
-      # @example
-      #
-      #   class FallbackEventHandler
-      #
-      #     # since it now defines a handlers method, any event will iterate
-      #     # through them and invoke the +dispatch+ method on each
-      #     attr_accessor handlers
-      #
-      #     def initialize
-      #       @handlers = []
-      #     end
-      #
-      #     # invoked for any event not otherwise handled
-      #     def on_unhandled(event)
-      #       puts "Unable to invoke #{event.type.method} on #{event.context}."
-      #     end
-      #
-      #   end
-      #
-      # @param handler [Object] An object which implements either the event's
-      #    handler method or else responds to :handlers with an array of other
-      #    handlers.
-      #
-      def dispatch(handler, type = nil)
-        type = @type if type.nil?
-        if handler.is_a?(Qpid::Proton::Handler::WrappedHandler)
-          Cproton.pn_handler_dispatch(handler.impl, @impl, type.number)
-        else
-          result = Qpid::Proton::Event.dispatch(handler, type.method, self)
-          if (result != "DELEGATED") && handler.respond_to?(:handlers) && handler.handlers
-            handler.handlers.each do |hndlr|
-              self.dispatch(hndlr)
-            end
-          end
-        end
-      end
-
-      # @deprecated use {#container}
-      def reactor
-        deprecated __method__, :container
-      end
-
-      # @return container associated with this event
-      attr_reader :container
-
-      # Returns the transport for this event.
-      #
-      # @return [Transport, nil] The transport.
-      #
-      def transport
-        Qpid::Proton::Transport.wrap(Cproton.pn_event_transport(@impl))
-      end
-
-      # Returns the Connection for this event.
-      #
-      # @return [Connection, nil] The connection.
-      #
-      def connection
-        Qpid::Proton::Connection.wrap(Cproton.pn_event_connection(@impl))
-      end
-
-      # Returns the Session for this event.
-      #
-      # @return [Session, nil] The session
-      #
-      def session
-        Qpid::Proton::Session.wrap(Cproton.pn_event_session(@impl))
-      end
-
-      # Returns the Link for this event.
-      #
-      # @return [Link, nil] The link.
-      #
-      def link
-        Qpid::Proton::Link.wrap(Cproton.pn_event_link(@impl))
-      end
-
-      # Returns the Sender, or nil if there is no Link, associated  with this
-      # event if that link is a sender.
-      #
-      # @return [Sender, nil] The sender.
-      #
-      def sender
-        return self.link if !self.link.nil? && self.link.sender?
-      end
-
-      # Returns the Receiver, or nil if there is no Link, associated with this
-      # event if that link is a receiver.
-      #
-      # @return [Receiver, nil] The receiver.
-      #
-      def receiver
-        return self.link if !self.link.nil? && self.link.receiver?
-      end
-
-      # Returns the Delivery associated with this event.
-      #
-      # @return [Delivery, nil] The delivery.
-      #
-      def delivery
-        Qpid::Proton::Delivery.wrap(Cproton.pn_event_delivery(@impl))
-      end
-
-      # Sets the message.
-      #
-      # @param message [Qpid::Proton::Message] The message
-      #
-      def message=(message)
-        @message = message
-      end
-
-      # Returns the message.
-      #
-      # @return [Qpid::Proton::Message] The message.
-      #
-      def message
-        @message
-      end
-
-      # @private
-      def to_s
-        "#{self.type}(#{self.context})"
-      end
-
-      # @private
-      def container=(c); @container = c; end
-
-      # @return The remote error {Condition} or nil if there is none.
-      def condition
-        context.remote_condition if context.respond_to? :remote_condition
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/event/event_base.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event_base.rb b/proton-c/bindings/ruby/lib/event/event_base.rb
deleted file mode 100644
index 6ae6959..0000000
--- a/proton-c/bindings/ruby/lib/event/event_base.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-#--
-# 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::Proton::Event
-
-  # @private
-  def self.dispatch(handler, method, *args)
-    args = args.last unless args.nil?
-    if handler.respond_to? method.to_sym
-      return handler.__send__(method, args)
-    elsif handler.respond_to? :on_unhandled
-      return handler.__send__(:on_unhandled, method, args)
-    end
-  end
-
-  # EventBase is the foundation for creating application-specific events.
-  #
-  # @example
-  #
-  #   # SCENARIO: A continuation of the example in EventType.
-  #   #
-  #   #           An Event class is defined to handle receiving encrypted
-  #   #           data from a remote endpoint.
-  #
-  #   class EncryptedDataEvent < EventBase
-  #     def initialize(message)
-  #       super(EncryptedDataEvent, message,
-  #             Qpid::Proton::Event::ENCRYPTED_RECV)
-  #     end
-  #   end
-  #
-  #   # at another point, when encrypted data is received
-  #   msg = Qpid::Proton::Message.new
-  #   msg.decode(link.receive(link.pending))
-  #   if encrypted?(msg)
-  #     collector.put(EncryptedDataEvent.new(msg)
-  #   end
-  #
-  # @see EventType The EventType class for how ENCRYPTED_RECV was defined.
-  #
-  class EventBase
-
-    # Returns the name for the class associated with this event.
-    attr_reader :class_name
-
-    # Returns the associated context object for the event.
-    attr_reader :context
-
-    # Returns the type of the event.
-    attr_reader :type
-
-    # Creates a new event with the specific class_name and context of the
-    # specified type.
-    #
-    # @param class_name [String] The name of the class.
-    # @param context [Object] The event context.
-    # @param type [EventType] The event type.
-    #
-    def initialize(class_name, context, type)
-      @class_name = class_name
-      @context = context
-      @type = type
-    end
-
-    # Invokes the type-specific method on the provided handler.
-    #
-    # @param handler [Object] The handler to be notified of this event.
-    #
-    def dispatch(handler)
-      Qpid::Proton.dispatch(handler, @type.method, self)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/event/event_type.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event_type.rb b/proton-c/bindings/ruby/lib/event/event_type.rb
deleted file mode 100644
index aa5944d..0000000
--- a/proton-c/bindings/ruby/lib/event/event_type.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-#--
-# 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::Proton::Event
-
-  # Manages the association between an Event and the method which should
-  # process on the context object associated with an occurance of the event.
-  #
-  # Each type is identified by a unique #type value.
-  #
-  # @example
-  #
-  #   # SCENARIO: A part of an application handles extracting and decrypting
-  #   #            data received from a remote endpoint.
-  #   #
-  #   #            An EventType is created to notify handlers that such a
-  #   #            situation has occurred.
-  #
-  #   ENCRYPTED_RECV = 10000 # the unique constant value for the event
-  #
-  #   # create a new event type which, when it occurs, invokes a method
-  #   # named :on_encrypted_data when a handler is notified of its occurrance
-  #   Qpid::Proton::Event::ENCRYPTED_RECV =
-  #     Qpid::Proton::Event::EventType.new(ENCRYPTED_RECV, :on_encrypted_data)
-  #
-  # @see EventBase EventBase for the rest of this example.
-  # @see Qpid::Proton::Event::Event The Event class for more details on events.
-  #
-  class EventType
-
-    # The method to invoke on any potential handler.
-    attr_reader :method
-    attr_reader :number
-
-    def initialize(number, method)
-      @number = number
-      @name = Cproton.pn_event_type_name(@number)
-      @method = method
-      @@types ||= {}
-      @@types[number] = self
-    end
-
-    # @private
-    def to_s
-      @name
-    end
-
-    # @private
-    def self.by_type(type) # :nodoc:
-      @@types[type]
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/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
new file mode 100644
index 0000000..2efa2b7
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/handler/adapter.rb
@@ -0,0 +1,157 @@
+#--
+# 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.
+#++
+
+# @private
+module Qpid::Proton::Handler
+
+  # @private
+  # Adapter to convert raw proton events to {#MessagingHandler} events
+  class Adapter
+
+    def self.try_convert(h) h.is_a?(Adapter) ? h : Adapter.new(h); end
+
+    def initialize handler
+      @handler = handler || MessagingHandler.new # Pick up default MH behavior
+      @opts = handler.respond_to?(:options) ? handler.options : {}
+      @opts[:prefetch] ||= 10
+      @opts[:peer_close_is_error] = false unless @opts.include? :peer_close_is_error
+      [:auto_accept, :auto_settle, :auto_open, :auto_close].each do |k|
+        @opts[k] = true unless @opts.include? k
+      end
+    end
+
+    def dispatch(method, event)
+      (@handler.__send__(method, event); true) if @handler.respond_to? method
+    end
+
+    def delegate(method, event)
+      event.method = method     # Update the event with the new method
+      event.dispatch(@handler) || dispatch(:on_unhandled, event)
+    end
+    def delegate_error(method, event)
+      event.method = method
+      unless event.dispatch(@handler) # Default behaviour if not dispatched
+        dispatch(:on_error, event) || dispatch(:on_unhandled, event)
+        event.connection.close event.context.condition # Close the connection by default
+      end
+    end
+
+    # Define repetative on_xxx_open/close methods for each endpoint type
+    def self.open_close(endpoint)
+      on_opening = :"on_#{endpoint}_opening"
+      on_opened = :"on_#{endpoint}_opened"
+      on_closing = :"on_#{endpoint}_closing"
+      on_closed = :"on_#{endpoint}_closed"
+      on_error = :"on_#{endpoint}_error"
+
+      Module.new do
+        define_method(:"on_#{endpoint}_local_open") do |event|
+          delegate(on_opened, event) if event.context.remote_open?
+        end
+
+        define_method(:"on_#{endpoint}_remote_open") do |event|
+          if event.context.local_open?
+            delegate(on_opened, event)
+          elsif event.context.local_uninit?
+            delegate(on_opening, event)
+            event.context.open if @opts[:auto_open]
+          end
+        end
+
+        define_method(:"on_#{endpoint}_local_close") do |event|
+          delegate(on_closed, event) if event.context.remote_closed?
+        end
+
+        define_method(:"on_#{endpoint}_remote_close") do |event|
+          if event.context.remote_condition
+            delegate_error(on_error, event)
+          elsif event.context.local_closed?
+            delegate(on_closed, event)
+          elsif @opts[:peer_close_is_error]
+            Condition.assign(event.context.__send__(:_remote_condition), "unexpected peer close")
+            delegate_error(on_error, event)
+          else
+            delegate(on_closing, event)
+          end
+          event.context.close if @opts[:auto_close]
+        end
+      end
+    end
+    # Generate and include open_close modules for each endpoint type
+    [:connection, :session, :link].each { |endpoint| include open_close(endpoint) }
+
+    def on_transport_error(event) delegate_error(:on_transport_error, event); end
+    def on_transport_closed(event) delegate(:on_transport_closed, event); end
+
+    # Add flow control for link opening events
+    def on_link_local_open(event) super; add_credit(event); end
+    def on_link_remote_open(event) super; add_credit(event); end
+
+
+    def on_delivery(event)
+      d = event.delivery
+      if d.link.receiver?       # Incoming message
+        if d.aborted?
+          delegate(:on_aborted, event)
+          d.settle
+        elsif d.message?
+          if d.link.local_closed? && @opts[:auto_accept]
+            d.release
+          else
+            begin
+              delegate(:on_message, event)
+              d.accept if @opts[:auto_accept]
+            rescue Qpid::Proton::Reject
+              d.reject
+            rescue Qpid::Proton::Release
+              d.release(true)
+            end
+          end
+        elsif d.updated? && d.settled?
+          delegate(:on_settled, event)
+        end
+        add_credit(event)
+      else                      # Outgoing message
+        if d.updated?
+          case d.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)
+          end
+          delegate(:on_settled, event) if d.settled?
+          d.settle if @opts[:auto_settle]
+        end
+      end
+    end
+
+    def on_link_flow(event)
+      add_credit(event)
+      l = event.link
+      delegate(:on_sendable, event) if l.sender? && l.open? && l.credit > 0
+    end
+
+    def add_credit(event)
+      r = event.receiver
+      prefetch = @opts[:prefetch]
+      if r && r.open? && (r.drained == 0) && prefetch && (prefetch > r.credit)
+        r.flow(prefetch - r.credit)
+      end
+    end
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/c_adaptor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/c_adaptor.rb b/proton-c/bindings/ruby/lib/handler/c_adaptor.rb
deleted file mode 100644
index ef4852e..0000000
--- a/proton-c/bindings/ruby/lib/handler/c_adaptor.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  # @private
-  class CAdaptor
-
-    def initialize(handler, on_error = nil)
-      @handler = handler
-      @on_error = on_error
-    end
-
-    def dispatch(cevent, ctype)
-      event = Qpid::Proton::Event::Event.wrap(cevent, ctype)
-      # TODO add a variable to enable this programmatically
-      # print "EVENT: #{event} going to #{@handler}\n"
-      event.dispatch(@handler)
-    end
-
-    def exception(error)
-      if @on_error.nil?
-        raise error
-      else
-        @on_error.call(error)
-      end
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/c_flow_controller.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/c_flow_controller.rb b/proton-c/bindings/ruby/lib/handler/c_flow_controller.rb
deleted file mode 100644
index 377cc2f..0000000
--- a/proton-c/bindings/ruby/lib/handler/c_flow_controller.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  # @private
-  class CFlowController < Qpid::Proton::Handler::WrappedHandler
-
-    include Qpid::Proton::Util::Wrapper
-
-    def initialize(window = 1024)
-      super(Cproton.pn_flowcontroller(window))
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
index 7f0c85b..98b8d3a 100644
--- a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
@@ -17,36 +17,25 @@
 # under the License.
 #++
 
+# @private
 module Qpid::Proton::Handler
 
-  # A utility that exposes endpoint events; i.e., the open/close of a link,
-  # session or connection, in a more intuitive manner.
-  #
-  # A XXX_opened method will be called when both local and remote peers have
-  # opened the link, session or connection. This can be used to confirm a
-  # locally initiated action for example.
+  # Mixin to convert raw proton endpoint events to {#MessagingHandler} events
   #
   # A XXX_opening method will be called when the remote peer has requested
   # an open that was not initiated locally. By default this will simply open
   # locally, which then trigtgers the XXX_opened called.
   #
+  # A XXX_opened method will be called when both local and remote peers have
+  # opened the link, session or connection. This can be used to confirm a
+  # locally initiated action for example.
+  #
   # The same applies to close.
   #
-  class EndpointStateHandler
-
-    def initialize(peer_close_is_error = false, delegate = nil)
-      @delegate = delegate
-      @peer_close_is_error = peer_close_is_error
-    end
-
-    def self.print_error(endpoint, endpoint_type)
-      if !endpoint.remote_condition.nil?
-      elsif self.local_endpoint?(endpoint) && endpoint.remote_closed?
-        logging.error("#{endpoint_type} closed by peer")
-      end
-    end
+  module EndpointStateHandler
 
     def on_link_remote_close(event)
+      super
       if !event.link.remote_condition.nil?
         self.on_link_error(event)
       elsif event.link.local_closed?
@@ -58,6 +47,7 @@ module Qpid::Proton::Handler
     end
 
     def on_session_remote_close(event)
+      super
       if !event.session.remote_condition.nil?
         self.on_session_error(event)
       elsif event.session.local_closed?
@@ -69,6 +59,7 @@ module Qpid::Proton::Handler
     end
 
     def on_connection_remote_close(event)
+      super
       if !event.connection.remote_condition.nil?
         self.on_connection_error(event)
       elsif event.connection.local_closed?
@@ -80,10 +71,12 @@ module Qpid::Proton::Handler
     end
 
     def on_connection_local_open(event)
+      super
       self.on_connection_opened(event) if event.connection.remote_active?
     end
 
     def on_connection_remote_open(event)
+      super
       if event.connection.local_active?
         self.on_connection_opened(event)
       elsif event.connection.local_uninit?
@@ -93,10 +86,12 @@ module Qpid::Proton::Handler
     end
 
     def on_session_local_open(event)
+      super
       self.on_session_opened(event) if event.session.remote_active?
     end
 
     def on_session_remote_open(event)
+      super
       if !(event.session.state & Qpid::Proton::Endpoint::LOCAL_ACTIVE).zero?
         self.on_session_opened(event)
       elsif event.session.local_uninit?
@@ -106,10 +101,12 @@ module Qpid::Proton::Handler
     end
 
     def on_link_local_open(event)
+      super
       self.on_link_opened(event) if event.link.remote_active?
     end
 
     def on_link_remote_open(event)
+      super
       if event.link.local_active?
         self.on_link_opened(event)
       elsif event.link.local_uninit?
@@ -117,101 +114,5 @@ module Qpid::Proton::Handler
         event.link.open
       end
     end
-
-    def on_connection_opened(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_connection_opened, event) if !@delegate.nil?
-    end
-
-    def on_session_opened(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_session_opened, event) if !@delegate.nil?
-    end
-
-    def on_link_opened(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_link_opened, event) if !@delegate.nil?
-    end
-
-    def on_connection_opening(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_connection_opening, event) if !@delegate.nil?
-    end
-
-    def on_session_opening(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_session_opening, event) if !@delegate.nil?
-    end
-
-    def on_link_opening(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_link_opening, event) if !@delegate.nil?
-    end
-
-    def on_connection_error(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_connection_error, event)
-      else
-        self.log_error(event.connection, "connection")
-      end
-    end
-
-    def on_session_error(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_session_error, event)
-      else
-        self.log_error(event.session, "session")
-        event.connection.close
-      end
-    end
-
-    def on_link_error(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_link_error, event)
-      else
-        self.log_error(event.link, "link")
-        event.conneciton.close
-      end
-    end
-
-    def on_connection_closed(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_connection_closed, event) if !@delegate.nil?
-    end
-
-    def on_session_closed(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_session_closed, event) if !@delegate.nil?
-    end
-
-    def on_link_closed(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_link_closed, event) if !@delegate.nil?
-    end
-
-    def on_connection_closing(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_connection_closing, event)
-      elsif @peer_close_is_error
-        self.on_connection_error(event)
-      end
-    end
-
-    def on_session_closing(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_session_closing, event)
-      elsif @peer_close_is_error
-        self.on_session_error(event)
-      end
-    end
-
-    def on_link_closing(event)
-      if !@delegate.nil?
-        Qpid::Proton::Event.dispatch(@delegate, :on_link_closing, event)
-      elsif @peer_close_is_error
-        self.on_link_error(event)
-      end
-    end
-
-    def on_transport_tail_closed(event)
-      self.on_transport_closed(event)
-    end
-
-    def on_transport_closed(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_disconnected, event) if !@delegate.nil?
-    end
-
   end
-
 end


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


[02/12] qpid-proton git commit: PROTON-1064: [ruby] Event handling refactor

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/flow_controller.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/flow_controller.rb b/proton-c/bindings/ruby/lib/handler/flow_controller.rb
new file mode 100644
index 0000000..38d925f
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/handler/flow_controller.rb
@@ -0,0 +1,40 @@
+#--
+# 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.
+#++
+
+# @private
+module Qpid::Proton::Handler
+
+  # Mixin to establish automatic flow control for a prefetch window
+  # Uses {#@prefetch}
+  #
+  module FlowController
+
+    def on_link_local_open(event) topup(event); super; end
+    def on_link_remote_open(event) topup(event); super; end
+    def on_delivery(event) topup(event); super; end
+    def on_link_flow(event) topup(event); super; end
+
+    def add_credit(event)
+      r = event.receiver
+      if r && r.open? && (r.drained == 0) && @handler.prefetch && (@handler.prefetch > r.credit)
+        r.flow(@handler.prefetch - r.credit)
+      end
+    end
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
index db0f6db..9f34d0d 100644
--- a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
@@ -17,19 +17,18 @@
 # under the License.
 #++
 
+# @private
 module Qpid::Proton::Handler
+  private
 
   # A utility for simpler and more intuitive handling of delivery events
   # related to incoming messages.
   #
-  class IncomingMessageHandler
-
-    def initialize(auto_accept = true, delegate = nil)
-      @delegate = delegate
-      @auto_accept = auto_accept
-    end
-
+  # uses @auto_accept
+  #
+  module IncomingMessageHandler
     def on_delivery(event)
+      super
       delivery = event.delivery
       return unless delivery.link.receiver?
       if delivery.readable? && !delivery.partial?
@@ -37,38 +36,20 @@ module Qpid::Proton::Handler
         m.receive(delivery)
         event.message = m
         if event.link.local_closed?
-          if @auto_accept
-            delivery.update(Qpid::Proton::Disposition::RELEASED)
-            delivery.settle
-          end
+          delivery.settle Qpid::Proton::Delivery::RELEASED if @auto_accept
         else
           begin
             self.on_message(event)
-            if @auto_accept
-              delivery.update(Qpid::Proton::Disposition::ACCEPTED)
-              delivery.settle
-            end
+            delivery.settle Qpid::Proton::Delivery::ACCEPTED if @auto_accept
           rescue Qpid::Proton::Reject
-            delivery.update(Qpid::Proton::Disposition::REJECTED)
-            delivery.settle
+            delivery.settle REJECTED
           rescue Qpid::Proton::Release
-            delivery.update(Qpid::Proton::Disposition::MODIFIED)
-            delivery.settle
+            delivery.settle MODIFIED
           end
         end
       elsif delivery.updated? && delivery.settled?
         self.on_settled(event)
       end
     end
-
-    def on_message(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_message, event) if !@delegate.nil?
-    end
-
-    def on_settled(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_settled, event) if !@delegate.nil?
-    end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
index ee875b6..cedcead 100644
--- a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
@@ -22,20 +22,18 @@ module Qpid::Proton::Handler
   # A utility for simpler and more intuitive handling of delivery events
   # related to outgoing messages.
   #
-  class OutgoingMessageHandler
-
-    def initialize(auto_settle = true, delegate = nil)
-      @auto_settle = auto_settle
-      @delegate = delegate
-    end
+  # Uses {#@auto_settle}
+  module OutgoingMessageHandler
 
     def on_link_flow(event)
+      super
       self.on_sendable(event) if event.link.sender? && event.link.credit > 0 &&
                                  (event.link.state & Qpid::Proton::Endpoint::LOCAL_ACTIVE) &&
                                  (event.link.state & Qpid::Proton::Endpoint::REMOTE_ACTIVE)
     end
 
     def on_delivery(event)
+      super
       delivery = event.delivery
       if delivery.link.sender? && delivery.updated?
         if delivery.remote_accepted?
@@ -49,52 +47,5 @@ module Qpid::Proton::Handler
         delivery.settle if @auto_settle
       end
     end
-
-    # Called when the sender link has credit and messages and be transferred.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_sendable(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_sendable, event) if !@delegate.nil?
-    end
-
-    # Called when the remote peer accepts a sent message.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_accepted(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_accepted, event) if !@delegate.nil?
-    end
-
-    # Called when the remote peer rejects a sent message.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_rejected(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_rejected, event) if !@delegate.nil?
-    end
-
-    # Called when the remote peer releases an outgoing message.
-    #
-    # Note that this may be in resposnse to either the REELAASE or MODIFIED
-    # state as defined by the AMQP specification.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_released(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_released, event) if !@delegate.nil?
-    end
-
-    # Called when the remote peer has settled the outgoing message.
-    #
-    # This is the point at which it should never be retransmitted.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_settled(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_settled, event) if !@delegate.nil?
-    end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/handler/wrapped_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/wrapped_handler.rb b/proton-c/bindings/ruby/lib/handler/wrapped_handler.rb
deleted file mode 100644
index 6d55dee..0000000
--- a/proton-c/bindings/ruby/lib/handler/wrapped_handler.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  class WrappedHandler
-
-    # @private
-    include Qpid::Proton::Util::Wrapper
-
-    def self.wrap(impl, on_error = nil)
-      return nil if impl.nil?
-
-      result = self.fetch_instance(impl) || WrappedHandler.new(impl)
-      result.on_error = on_error
-      return result
-    end
-
-    include Qpid::Proton::Util::Handler
-
-    def initialize(impl_or_constructor)
-      if impl_or_constructor.is_a?(Method)
-        @impl = impl_or_constructor.call
-      else
-        @impl = impl_or_constructor
-        Cproton.pn_incref(@impl)
-      end
-      @on_error = nil
-      self.class.store_instance(self)
-    end
-
-    def add(handler)
-      return if handler.nil?
-
-      impl = chandler(handler, self.method(:_on_error))
-      Cproton.pn_handler_add(@impl, impl)
-      Cproton.pn_decref(impl)
-    end
-
-    def clear
-      Cproton.pn_handler_clear(@impl)
-    end
-
-    def on_error=(on_error)
-      @on_error = on_error
-    end
-
-    private
-
-    def _on_error(info)
-      if self.has?['on_error']
-        self['on_error'].call(info)
-      else
-        raise info
-      end
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index b47b863..d3040a0 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -21,10 +21,10 @@ require "cproton"
 require "date"
 require "weakref"
 
-if RUBY_VERSION < "1.9"
-require "kconv"
-else
+begin
   require "securerandom"
+rescue LoadError
+  require "kconv"               # Ruby < 1.9
 end
 
 DEPRECATION = "[DEPRECATION]"
@@ -41,9 +41,7 @@ require "util/version"
 require "util/error_handler"
 require "util/swig_helper"
 require "util/wrapper"
-require "util/class_wrapper"
 require "util/timeout"
-require "util/handler"
 
 # Types
 require "types/strings"
@@ -55,14 +53,9 @@ require "types/described"
 require "codec/mapping"
 require "codec/data"
 
-# Event API classes
-require "event/event_type"
-require "event/event_base"
-require "event/event"
-require "event/collector"
-
 # Main Proton classes
 require "core/condition"
+require "core/event"
 require "core/uri"
 require "core/message"
 require "core/endpoint"
@@ -89,12 +82,11 @@ require "messenger/tracker"
 require "messenger/messenger"
 
 # Handler classes
-require "handler/c_adaptor"
-require "handler/wrapped_handler"
 require "handler/endpoint_state_handler"
 require "handler/incoming_message_handler"
 require "handler/outgoing_message_handler"
-require "handler/c_flow_controller"
+require "handler/flow_controller"
+require "handler/adapter"
 
 # Core classes that depend on Handler
 require "core/messaging_handler"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/util/class_wrapper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/class_wrapper.rb b/proton-c/bindings/ruby/lib/util/class_wrapper.rb
deleted file mode 100644
index 134f655..0000000
--- a/proton-c/bindings/ruby/lib/util/class_wrapper.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-#--
-# 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::Proton::Util
-
-  # This mixin provides a method for mapping from an underlying Proton
-  # C library class to a Ruby class.
-  #
-  # @private
-  #
-  module ClassWrapper
-
-    WRAPPERS =
-      {
-        "pn_void" => proc {|x| Cproton.pn_void2rb(x)},
-        "pn_rbref" => proc {|x| Cproton.pn_void2rb(x)},
-        "pn_connection" => proc {|x| Qpid::Proton::Connection.wrap(Cproton.pn_cast_pn_connection(x))},
-        "pn_session" => proc {|x| Qpid::Proton::Session.wrap(Cproton.pn_cast_pn_session(x))},
-        "pn_link" => proc {|x| Qpid::Proton::Link.wrap(Cproton.pn_cast_pn_link(x))},
-        "pn_delivery" => proc {|x| Qpid::Proton::Delivery.wrap(Cproton.pn_cast_pn_delivery(x))},
-        "pn_transport" => proc {|x| Qpid::Proton::Transport.wrap(Cproton.pn_cast_pn_transport(x))},
-        "pn_selectable" => proc {|x| Qpid::Proton::Selectable.wrap(Cproton.pn_cast_pn_selectable(x))},
-      }
-
-    def class_wrapper(clazz, c_impl, &block)
-      proc_func = WRAPPERS[clazz]
-      if !proc_func.nil?
-        proc_func.yield(c_impl)
-      elsif block_given?
-        yield(c_impl)
-      end
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/lib/util/handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/handler.rb b/proton-c/bindings/ruby/lib/util/handler.rb
deleted file mode 100644
index e7d07b1..0000000
--- a/proton-c/bindings/ruby/lib/util/handler.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#--
-# 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::Proton::Util
-
-  # @private
-  module Handler
-
-    def chandler(handler, on_error)
-      return nil if handler.nil?
-
-      if handler.instance_of?(Qpid::Proton::Handler::WrappedHandler)
-        impl = handler.impl
-        Cproton.pn_incref(impl)
-        return impl
-      else
-        cadaptor = Qpid::Proton::Handler::CAdaptor.new(handler, on_error)
-        rbhandler = Cproton.pn_rbhandler(cadaptor)
-        return rbhandler
-      end
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/tests/test_adapter.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_adapter.rb b/proton-c/bindings/ruby/tests/test_adapter.rb
new file mode 100644
index 0000000..77aee76
--- /dev/null
+++ b/proton-c/bindings/ruby/tests/test_adapter.rb
@@ -0,0 +1,227 @@
+#--
+# 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
+
+# Tests with Mock handler that handles all methods.
+class TestAllHandler < Minitest::Test
+
+  class AllHandler < MessagingHandler
+    def initialize(*args)
+      super(*args)
+      @calls = []
+    end
+
+    attr_accessor :calls
+
+    def names; @calls.map { |c| c[0] }; end
+    def events; @calls.map { |c| c[1] }; end
+
+    def method_missing(name, *args) (/^on_/ =~ name) ? (@calls << [name] + args) : super; end
+    def respond_to_missing?(name, private=false); (/^on_/ =~ name); end
+    def respond_to?(name, all=false) super || respond_to_missing?(name); end # For ruby < 1.9.2
+  end
+
+  def setup
+    @h = [AllHandler.new, AllHandler.new]
+    @ch, @sh = *@h
+    @d = DriverPair.new(*@h)
+  end
+
+  def clear; @d.each { |d| h = d.handler; h.calls.clear }; end
+
+  def test_handler_defaults
+    want = { :prefetch => 10, :auto_settle => true, :auto_accept => true, :auto_open => true, :auto_close => true, :peer_close_is_error => false }
+    assert_equal want, @ch.options
+    assert_equal want, @sh.options
+  end
+
+  def test_auto_open_close
+    @d.client.connection.open; @d.client.connection.open_sender; @d.run
+    assert_equal [:on_connection_opened, :on_session_opened, :on_link_opened, :on_sendable], @ch.names
+    assert_equal [:on_connection_opening, :on_session_opening, :on_link_opening, :on_connection_opened, :on_session_opened, :on_link_opened], @sh.names
+    clear
+    @d.client.connection.close; @d.run
+    assert_equal [:on_connection_closed, :on_transport_closed], @ch.names
+    assert_equal [:on_connection_closing, :on_connection_closed, :on_transport_closed], @sh.names
+  end
+
+  def test_no_auto_open_close
+    [:auto_close, :auto_open].each { |k| @ch.options[k] = @sh.options[k] = false }
+    @d.client.connection.open; @d.run
+    assert_equal [:on_connection_opening], @sh.names
+    assert_equal [], @ch.names
+    @d.server.connection.open; @d.run
+    assert_equal [:on_connection_opened], @ch.names
+    assert_equal [:on_connection_opening, :on_connection_opened], @sh.names
+    clear
+    @d.client.connection.session.open; @d.run
+    assert_equal [:on_session_opening], @sh.names
+    assert_equal [], @ch.names
+    clear
+    @d.client.connection.close; @d.run
+    assert_equal [:on_connection_closing], @sh.names
+    assert_equal [], @ch.names
+    @d.server.connection.close; @d.run
+    assert_equal [:on_connection_closed, :on_transport_closed], @ch.names
+    assert_equal [:on_connection_closing, :on_connection_closed, :on_transport_closed], @sh.names
+  end
+
+  def test_transport_error
+    @d.client.connection.open; @d.run
+    clear
+    @d.client.close "stop that"; @d.run
+    assert_equal [:on_transport_closed], @ch.names
+    assert_equal [:on_transport_error, :on_transport_closed], @sh.names
+    assert_equal Condition.new("proton:io", "stop that (connection aborted)"), @d.client.transport.condition
+    assert_equal Condition.new("amqp:connection:framing-error", "connection aborted"), @d.server.transport.condition
+  end
+
+  def test_connection_error
+    @ch.options[:auto_open] = @sh.options[:auto_open] = false
+    @d.client.connection.open; @d.run
+    @d.server.connection.close "bad dog"; @d.run
+    assert_equal [:on_connection_opened, :on_connection_error, :on_connection_closed, :on_transport_closed], @ch.names
+    assert_equal "bad dog", @ch.calls[2][1].condition.description
+    assert_equal [:on_connection_opening, :on_connection_closed, :on_transport_closed], @sh.names
+  end
+
+  def test_session_error
+    @d.client.connection.open
+    s = @d.client.connection.session; s.open; @d.run
+    s.close "bad dog"; @d.run
+    assert_equal [:on_connection_opened, :on_session_opened, :on_session_closed], @ch.names
+    assert_equal [:on_connection_opening, :on_session_opening, :on_connection_opened, :on_session_opened, :on_session_error, :on_session_closed], @sh.names
+    assert_equal "bad dog", @sh.calls[-3][1].condition.description
+  end
+
+  def test_link_error
+    @d.client.connection.open
+    s = @d.client.connection.open_sender; @d.run
+    s.close "bad dog"; @d.run
+    assert_equal [:on_connection_opened, :on_session_opened, :on_link_opened, :on_sendable, :on_link_closed], @ch.names
+    assert_equal [:on_connection_opening, :on_session_opening, :on_link_opening,
+                  :on_connection_opened, :on_session_opened, :on_link_opened,
+                  :on_link_error, :on_link_closed], @sh.names
+    assert_equal "bad dog", @sh.calls[-3][1].condition.description
+  end
+
+  def test_options_off
+    off = {:prefetch => 0, :auto_settle => false, :auto_accept => false, :auto_open => false, :auto_close => false}
+    @ch.options.replace(off)
+    @sh.options.replace(off)
+    @d.client.connection.open; @d.run
+    assert_equal [[], [:on_connection_opening]], [@ch.names, @sh.names]
+    @d.server.connection.open; @d.run
+    assert_equal [[:on_connection_opened], [:on_connection_opening, :on_connection_opened]], [@ch.names, @sh.names]
+    clear
+    s = @d.client.connection.open_sender; @d.run
+    assert_equal [[], [:on_session_opening, :on_link_opening]], [@ch.names, @sh.names]
+    @sh.events[1].session.open
+    r = @sh.events[1].link
+    r.open; @d.run
+    assert_equal [[:on_session_opened, :on_link_opened], [:on_session_opening, :on_link_opening, :on_session_opened, :on_link_opened]], [@ch.names, @sh.names]
+    clear
+    r.flow(1); @d.run
+    assert_equal [[:on_sendable], []], [@ch.names, @sh.names]
+    assert_equal 1, s.credit
+    clear
+    s.send Message.new("foo"); @d.run
+    assert_equal [[], [:on_message]], [@ch.names, @sh.names]
+  end
+
+  def test_peer_close_is_error
+    @ch.options[:peer_close_is_error] = true
+    @d.client.connection.open; @d.run
+    @d.server.connection.close; @d.run
+    assert_equal [:on_connection_opened, :on_connection_error, :on_connection_closed, :on_transport_closed], @ch.names
+    assert_equal [:on_connection_opening, :on_connection_opened, :on_connection_closed, :on_transport_closed], @sh.names
+  end
+end
+
+# Test with real handlers that implement a few methods
+class TestUnhandled < Minitest::Test
+
+  def test_message
+    handler_class = Class.new(MessagingHandler) do
+      def on_message(event) @message = event.message; end
+      def on_accepted(event) @accepted = true; end
+      attr_accessor :message, :accepted, :sender
+    end
+    d = DriverPair.new(handler_class.new, handler_class.new)
+    d.client.connection.open;
+    s = d.client.connection.open_sender; d.run
+    assert_equal 10, s.credit   # Default prefetch
+    s.send(Message.new("foo")); d.run
+    assert_equal "foo", d.server.handler.message.body
+    assert d.client.handler.accepted
+  end
+
+  # Verify on_unhandled is called
+  def test_unhandled
+    handler_class = Class.new(MessagingHandler) do
+      def initialize() super; @unhandled = []; end
+      def on_unhandled(event) @unhandled << event.method; end
+      attr_accessor :unhandled
+    end
+    d = DriverPair.new(handler_class.new, handler_class.new)
+    d.client.connection.open; d.run
+    assert_equal [:on_connection_opened], d.client.handler.unhandled
+    assert_equal [:on_connection_opening, :on_connection_opened], d.server.handler.unhandled
+  end
+
+  # Verify on_error is called
+  def test_on_error
+    handler_class = Class.new(MessagingHandler) do
+      def initialize() super; @error = []; @unhandled = []; end
+      def on_error(event) @error << event.method; end
+      def on_unhandled(event) @unhandled << event.method; end
+      attr_accessor :error, :unhandled
+    end
+    d = DriverPair.new(handler_class.new, handler_class.new)
+    d.client.connection.open
+    r = d.client.connection.open_receiver; d.run
+    r.close "oops"; d.run
+    assert_equal [:on_connection_opened, :on_session_opened, :on_link_opened,
+                  :on_link_closed, :on_connection_closed, :on_transport_closed], d.client.handler.unhandled
+    assert_equal [:on_connection_error], d.client.handler.error
+    assert_equal [:on_connection_opening, :on_session_opening, :on_link_opening,
+                  :on_connection_opened, :on_session_opened, :on_link_opened, :on_sendable,
+                  :on_link_closed, :on_connection_closed, :on_transport_closed], d.server.handler.unhandled
+    assert_equal [:on_link_error], d.server.handler.error
+
+  end
+
+  # Verify on_unhandled is called even for errors if there is no on_error
+  def test_unhandled_error
+    handler_class = Class.new(MessagingHandler) do
+      def initialize() super; @unhandled = []; end
+      def on_unhandled(event) @unhandled << event.method; end
+      attr_accessor :unhandled
+    end
+    d = DriverPair.new(handler_class.new, handler_class.new)
+    d.client.connection.open; d.run
+    d.client.connection.close "oops"; d.run
+    assert_equal [:on_connection_opened, :on_connection_closed, :on_transport_closed], d.client.handler.unhandled
+    assert_equal [:on_connection_opening, :on_connection_opened, :on_connection_error, :on_connection_closed, :on_transport_closed], d.server.handler.unhandled
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/tests/test_connection_driver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_connection_driver.rb b/proton-c/bindings/ruby/tests/test_connection_driver.rb
index 8ce9fe8..f12076f 100644
--- a/proton-c/bindings/ruby/tests/test_connection_driver.rb
+++ b/proton-c/bindings/ruby/tests/test_connection_driver.rb
@@ -40,7 +40,7 @@ class HandlerDriverTest < Minitest::Test
     end
 
     sender = HandlerDriver.new(@sockets[0], send_class.new)
-    sender.connection.open();
+    sender.connection.open(:container_id => "sender");
     sender.connection.open_sender()
     receiver = HandlerDriver.new(@sockets[1], recv_class.new)
     drivers = [sender, receiver]
@@ -58,14 +58,16 @@ class HandlerDriverTest < Minitest::Test
   end
 
   def test_idle
-    idle_class = Class.new(MessagingHandler) do
-      def on_connection_bound(event) event.transport.idle_timeout = 10; end
-    end
-    drivers = [HandlerDriver.new(@sockets[0], idle_class.new), HandlerDriver.new(@sockets[1], nil)]
-    drivers[0].connection.open()
+    drivers = [HandlerDriver.new(@sockets[0], nil), HandlerDriver.new(@sockets[1], nil)]
+    opts = {:idle_timeout=>10}
+    drivers[0].transport.apply(opts)
+    assert_equal 10, drivers[0].transport.idle_timeout
+    drivers[0].connection.open(opts)
+    drivers[1].transport.set_server
     now = Time.now
     drivers.each { |d| d.process(now) } until drivers[0].connection.open?
     assert_equal(10, drivers[0].transport.idle_timeout)
+    assert_equal(5, drivers[1].transport.remote_idle_timeout) # proton changes the value
     assert_in_delta(10, (drivers[0].tick(now) - now)*1000, 1)
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/bindings/ruby/tests/test_container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_container.rb b/proton-c/bindings/ruby/tests/test_container.rb
index f89ffbe..173c421 100644
--- a/proton-c/bindings/ruby/tests/test_container.rb
+++ b/proton-c/bindings/ruby/tests/test_container.rb
@@ -160,27 +160,15 @@ class ContainerSASLTest < Minitest::Test
   # Handler for test client/server that sets up server and client SASL options
   class SASLHandler < TestHandler
 
-    def initialize(url="amqp://", opts=nil, mechanisms=nil, insecure=nil, realm=nil)
+    def initialize(url="amqp://", opts=nil)
       super()
-      @url, @opts, @mechanisms, @insecure, @realm = url, opts, mechanisms, insecure, realm
+      @url, @opts = url, opts
     end
 
     def on_start(e)
-      super
       @client = e.container.connect("#{@url}:#{e.container.port}", @opts)
     end
 
-    def on_connection_bound(e)
-      if e.connection != @client # Incoming server connection
-        sasl = e.transport.sasl
-        sasl.allow_insecure_mechs = @insecure unless @insecure.nil?
-        sasl.allowed_mechs = @mechanisms unless @mechanisms.nil?
-        # TODO aconway 2017-08-16: need `sasl.realm(@realm)` here for non-default realms.
-        # That reqiures pn_sasl_set_realm() at the C layer - the realm should
-        # be passed to cyrus_sasl_init_server()
-      end
-    end
-
     attr_reader :auth_user
 
     def on_connection_opened(e)
@@ -263,7 +251,7 @@ mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS
     # Don't set allow_insecure_mechs, but try to use PLAIN
     s = SASLHandler.new("amqp://user:password@", {:sasl_allowed_mechs => "PLAIN", :sasl_allow_insecure_mechs => true})
     e = assert_raises(TestError) { TestContainer.new(s, {:sasl_allowed_mechs => "PLAIN"}).run }
-    assert_match(/PN_TRANSPORT_ERROR.*unauthorized-access/, e.to_s)
+    assert_match(/amqp:unauthorized-access.*Authentication failed/, e.to_s)
   end
 end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/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 e64d36b..120c488 100644
--- a/proton-c/bindings/ruby/tests/test_tools.rb
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -67,28 +67,11 @@ class TestHandler < MessagingHandler
     raise TestError.new("TestHandler has errors:\n #{text}")
   end
 
-  # TODO aconway 2017-08-15: implement in MessagingHandler
-  def on_error(event, endpoint)
-    @errors.push "#{event.type}: #{endpoint.condition.inspect}"
+  def on_error(event)
+    @errors.push "#{event.type}: #{event.condition.inspect}"
     raise_errors if @raise_errors
   end
 
-  def on_transport_error(event)
-    on_error(event, event.transport)
-  end
-
-  def on_connection_error(event)
-    on_error(event, event.connection)
-  end
-
-  def on_session_error(event)
-    on_error(event, event.session)
-  end
-
-  def on_link_error(event)
-    on_error(event, event.link)
-  end
-
   def endpoint_opened(queue, endpoint)
     queue.push(endpoint)
   end
@@ -115,3 +98,24 @@ class ListenOnceHandler < ListenHandler
   def on_error(l, e)  raise TestError, e.inspect; end
   def on_accept(l) l.close; super; end
 end
+
+# A client/server pair of ConnectionDrivers linked by a socket pair
+class DriverPair < Array
+
+  def initialize(client_handler, server_handler)
+    handlers = [client_handler, server_handler]
+    self[0..-1] = Socket.pair(:LOCAL, :STREAM, 0).map { |s| HandlerDriver.new(s, handlers.shift) }
+    server.transport.set_server
+  end
+
+  alias :client :first
+  alias :server :last
+
+  # Run till there is nothing to do
+  def run
+    begin
+      each { |d| d.process }
+    end while (IO.select(self, [], [], 0) rescue nil)
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b883393b/proton-c/include/proton/cproton.i
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/cproton.i b/proton-c/include/proton/cproton.i
index 5f375de..464e74b 100644
--- a/proton-c/include/proton/cproton.i
+++ b/proton-c/include/proton/cproton.i
@@ -1068,3 +1068,4 @@ typedef unsigned long int uintptr_t;
 %include "proton/url.h"
 %include "proton/reactor.h"
 %include "proton/handlers.h"
+%include "proton/cid.h"


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


[12/12] qpid-proton git commit: PROTON-1064: [ruby] consistent handling of conditions and exceptions

Posted by ac...@apache.org.
PROTON-1064: [ruby] consistent handling of conditions and exceptions


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

Branch: refs/heads/master
Commit: c4e5e58cd87aff704fc71c4c7b3c1d006de17f1b
Parents: db1cb9f
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Nov 28 09:52:59 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/condition.rb    | 32 ++++++++++++++------
 proton-c/bindings/ruby/lib/core/connection.rb   |  2 +-
 .../bindings/ruby/lib/core/connection_driver.rb |  2 +-
 proton-c/bindings/ruby/lib/core/container.rb    |  2 +-
 proton-c/bindings/ruby/lib/core/disposition.rb  |  2 +-
 proton-c/bindings/ruby/lib/core/endpoint.rb     |  4 +--
 proton-c/bindings/ruby/lib/core/listener.rb     |  2 +-
 proton-c/bindings/ruby/lib/core/transport.rb    |  4 +--
 proton-c/bindings/ruby/lib/event/event.rb       |  5 +++
 9 files changed, 36 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/condition.rb b/proton-c/bindings/ruby/lib/core/condition.rb
index b0b8de7..9cd6eec 100644
--- a/proton-c/bindings/ruby/lib/core/condition.rb
+++ b/proton-c/bindings/ruby/lib/core/condition.rb
@@ -19,7 +19,15 @@
 
 module Qpid::Proton
 
-  class Condition
+  # An AMQP error condition.
+  #
+  # An error sent across an AMQP connection has a name, description and optional extra info.
+  # The {Connectin}, {Session} and {Link} endpoint classes all have a #condition method to
+  # check for errors.
+  #
+  # {Condition} can also be raised as an exception.
+  #
+  class Condition < ProtonError
 
     attr_reader :name, :description, :info
 
@@ -27,6 +35,7 @@ module Qpid::Proton
       @name = name
       @description = description
       @info = info
+      super(to_s)
     end
 
     def to_s() "#{@name}: #{@description}"; end
@@ -40,15 +49,16 @@ module Qpid::Proton
        (other.info == self.info))
     end
 
-    # Make a condition.
+    # Convert an object to a condition.
     # @param obj the object to turn into a condition
-    # @param default_name condition name to use if obj does not imply a name
-    # @return
-    # - when Condition return obj unchanged
-    # - when Exception return Condition(obj.class.name, obj.to_s)
-    # - when nil then nil
-    # - else return Condition(default_name, obj.to_s)
-    def self.make(obj, default_name="proton")
+    # @param default_name name to use if obj does not imply a name
+    # @return [Condition] Conversion depends on the type of obj
+    # - Condition: return obj
+    # - Exception: return Condition(obj.class.name, obj.to_s)
+    # - String-like: return String.try_convert(obj)
+    # - nil: return nil
+    # @raise ::ArgumentError if obj is not convertible to {Condition}
+    def self.convert(obj, default_name="proton")
       case obj
       when nil then nil
       when Condition then obj
@@ -59,7 +69,9 @@ module Qpid::Proton
                         Cproton.pn_condition_get_description(obj),
                         Codec::Data.to_object(Cproton.pn_condition_info(obj)))
         end
-      else Condition.new(default_name, obj.to_s)
+      else
+        raise ::ArgumentError, "can't convert #{obj.class.name} to #{self.class.name}" unless obj.respond_to? :to_str
+        Condition.new(default_name, obj.to_str)
       end
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index 318e925..d6ff029 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -234,7 +234,7 @@ module Qpid::Proton
     #
     def close(error = nil)
       if error
-        @condition = Condition.make error
+        @condition = Condition.convert error
         self._update_condition
       end
       Cproton.pn_connection_close(@impl)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/connection_driver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection_driver.rb b/proton-c/bindings/ruby/lib/core/connection_driver.rb
index f757328..aeca133 100644
--- a/proton-c/bindings/ruby/lib/core/connection_driver.rb
+++ b/proton-c/bindings/ruby/lib/core/connection_driver.rb
@@ -144,7 +144,7 @@ module Qpid
       private
 
       def set_error e
-        if cond = Condition.make(e, "proton:io")
+        if cond = Condition.convert(e, "proton:io")
           Cproton.pn_connection_driver_errorf(@impl, cond.name, "%s", cond.description)
         end
       end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 7a4aeb1..28c394f 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -302,7 +302,7 @@ module Qpid::Proton
       @lock.synchronize do
         raise StoppedError if @stopped
         @stopped = true
-        @stop_err = Condition.make(error)
+        @stop_err = Condition.convert(error)
         check_stop_lh
         # NOTE: @stopped =>
         # - no new run threads can join

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/disposition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/disposition.rb b/proton-c/bindings/ruby/lib/core/disposition.rb
index 1f2c7fd..2c12345 100644
--- a/proton-c/bindings/ruby/lib/core/disposition.rb
+++ b/proton-c/bindings/ruby/lib/core/disposition.rb
@@ -155,7 +155,7 @@ module Qpid::Proton
       if @local
         @condition
       else
-        Condition.make(Cproton.pn_disposition_condition(@impl))
+        Condition.convert(Cproton.pn_disposition_condition(@impl))
       end
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/endpoint.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/endpoint.rb b/proton-c/bindings/ruby/lib/core/endpoint.rb
index 7ef18c8..fe2eb7a 100644
--- a/proton-c/bindings/ruby/lib/core/endpoint.rb
+++ b/proton-c/bindings/ruby/lib/core/endpoint.rb
@@ -67,11 +67,11 @@ module Qpid::Proton
     end
 
     def condition
-      Condition.make(_local_condition) || remote_condition; end
+      Condition.convert(_local_condition) || remote_condition; end
 
     # @private
     def remote_condition
-      Condition.make(_remote_condition)
+      Condition.convert(_remote_condition)
     end
 
     # Return the transport associated with this endpoint.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/listener.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/listener.rb b/proton-c/bindings/ruby/lib/core/listener.rb
index 35dfe20..3feb44b 100644
--- a/proton-c/bindings/ruby/lib/core/listener.rb
+++ b/proton-c/bindings/ruby/lib/core/listener.rb
@@ -65,7 +65,7 @@ module Qpid::Proton
     # @param error [Condition] Optional error condition.
     def close(error=nil)
       @closing = true
-      @condition ||= Condition.make(error) if error
+      @condition ||= Condition.convert error
       @io.close_read rescue nil # Cause listener to wake out of IO.select
       nil
     end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index 7b70ffc..7589788 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -228,13 +228,13 @@ module Qpid::Proton
 
     # @return [Condition, nil] transport error condition or nil if there is no error.
     def condition
-      Condition.make(Cproton.pn_transport_condition(@impl))
+      Condition.convert(Cproton.pn_transport_condition(@impl))
     end
 
     # Set the error condition for the transport.
     # @param c [Condition] The condition to set
     def condition=(c)
-      Condition.from_object(Cproton.pn_transport_condition(@impl), Condition.make(c))
+      Condition.from_object(Cproton.pn_transport_condition(@impl), Condition.convert(c))
     end
 
     # Binds to the given connection.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c4e5e58c/proton-c/bindings/ruby/lib/event/event.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/event/event.rb b/proton-c/bindings/ruby/lib/event/event.rb
index 8492b7c..92f7eb7 100644
--- a/proton-c/bindings/ruby/lib/event/event.rb
+++ b/proton-c/bindings/ruby/lib/event/event.rb
@@ -307,6 +307,11 @@ module Qpid::Proton
 
       # @private
       def container=(c); @container = c; end
+
+      # @return The remote error {Condition} or nil if there is none.
+      def condition
+        context.remote_condition if context.respond_to? :remote_condition
+      end
     end
   end
 end


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


[09/12] qpid-proton git commit: PROTON-1064: [ruby] Move Condition to core

Posted by ac...@apache.org.
PROTON-1064: [ruby] Move Condition to core


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

Branch: refs/heads/master
Commit: 15c804c7a7a2206ed94a5557bc95a4913a3261ae
Parents: 0f03d82
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 15:04:01 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/condition.rb | 65 +++++++++++++++++++++++
 proton-c/bindings/ruby/lib/qpid_proton.rb    |  2 +-
 proton-c/bindings/ruby/lib/util/condition.rb | 65 -----------------------
 3 files changed, 66 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/15c804c7/proton-c/bindings/ruby/lib/core/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/condition.rb b/proton-c/bindings/ruby/lib/core/condition.rb
new file mode 100644
index 0000000..2b0e1bf
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/core/condition.rb
@@ -0,0 +1,65 @@
+#--
+# 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::Proton
+
+  class Condition
+
+    attr_reader :name, :description, :info
+
+    def initialize(name, description = nil, info = nil)
+      @name = name
+      @description = description
+      @info = info
+    end
+
+    def to_s() "#{@name}: #{@description}"; end
+
+    def inspect() "#{self.class.name}(#{@name.inspect}, #{@description.inspect}, #{@info.inspect})"; end
+
+    def ==(other)
+      ((other.is_a? Condition) &&
+       (other.name == self.name) &&
+       (other.description == self.description) &&
+       (other.info == self.info))
+    end
+
+    # Make a condition.
+    # @param obj the object to turn into a condition
+    # @param default_name condition name to use if obj does not imply a name
+    # @return
+    # - when Condition return obj unchanged
+    # - when Exception return Condition(obj.class.name, obj.to_s)
+    # - when nil then nil
+    # - else return Condition(default_name, obj.to_s)
+    def self.make(obj, default_name="proton")
+      case obj
+      when Condition then obj
+      when Exception then Condition.new(obj.class.name, obj.to_s)
+      when nil then nil
+      else Condition.new(default_name, obj.to_s)
+      end
+    end
+
+  end
+
+  module Util                   #TODO aconway 2017-10-28: backwards compat
+    Condition = Qpid::Proton::Condition
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/15c804c7/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index cf1a01f..62e308b 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -41,7 +41,6 @@ require "util/version"
 require "util/error_handler"
 require "util/constants"
 require "util/swig_helper"
-require "util/condition"
 require "util/wrapper"
 require "util/class_wrapper"
 require "util/engine"
@@ -65,6 +64,7 @@ require "event/event"
 require "event/collector"
 
 # Main Proton classes
+require "core/condition"
 require "core/uri"
 require "core/message"
 require "core/endpoint"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/15c804c7/proton-c/bindings/ruby/lib/util/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/condition.rb b/proton-c/bindings/ruby/lib/util/condition.rb
deleted file mode 100644
index 1cb307a..0000000
--- a/proton-c/bindings/ruby/lib/util/condition.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-#--
-# 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::Proton
-
-  class Condition
-
-    attr_reader :name, :description, :info
-
-    def initialize(name, description = nil, info = nil)
-      @name = name
-      @description = description
-      @info = info
-    end
-
-    def to_s() "#{@name}: #{@description}"; end
-
-    def inspect() "#{self.class.name}(#{@name.inspect}, #{@description.inspect}, #{@info.inspect})"; end
-
-    def ==(other)
-      ((other.is_a? Condition) &&
-       (other.name == self.name) && 
-       (other.description == self.description) &&
-       (other.info == self.info))
-    end
-
-    # Make a condition.
-    # @param obj the object to turn into a condition
-    # @param default_name condition name to use if obj does not imply a name
-    # @return
-    # - when Condition return obj unchanged
-    # - when Exception return Condition(obj.class.name, obj.to_s)
-    # - when nil then nil
-    # - else return Condition(default_name, obj.to_s)
-    def self.make(obj, default_name="proton")
-      case obj
-      when Condition then obj
-      when Exception then Condition.new(obj.class.name, obj.to_s)
-      when nil then nil
-      else Condition.new(default_name, obj.to_s)
-      end
-    end
-
-  end
-
-  module Util                   #TODO aconway 2017-10-28: backwards compat
-    Condition = Qpid::Proton::Condition
-  end
-end


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


[11/12] qpid-proton git commit: PROTON-1064: [ruby] allow multiple handlers to container

Posted by ac...@apache.org.
PROTON-1064: [ruby] allow multiple handlers to container


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

Branch: refs/heads/master
Commit: 06fbad394a48989e1028c684f374a4357854d97a
Parents: b883393
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Nov 30 14:25:02 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 .../bindings/ruby/lib/core/connection_driver.rb |   4 +-
 proton-c/bindings/ruby/lib/core/container.rb    |   8 +-
 .../bindings/ruby/lib/core/messaging_handler.rb |  15 ++-
 proton-c/bindings/ruby/lib/handler/adapter.rb   |   2 +-
 .../ruby/lib/handler/endpoint_state_handler.rb  | 118 -------------------
 .../ruby/lib/handler/flow_controller.rb         |  40 -------
 .../lib/handler/incoming_message_handler.rb     |  55 ---------
 .../lib/handler/outgoing_message_handler.rb     |  51 --------
 proton-c/bindings/ruby/lib/qpid_proton.rb       |   4 -
 proton-c/bindings/ruby/tests/test_container.rb  |  14 ++-
 proton-c/bindings/ruby/tests/test_tools.rb      |   2 -
 11 files changed, 27 insertions(+), 286 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/core/connection_driver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection_driver.rb b/proton-c/bindings/ruby/lib/core/connection_driver.rb
index 1995f7d..969b558 100644
--- a/proton-c/bindings/ruby/lib/core/connection_driver.rb
+++ b/proton-c/bindings/ruby/lib/core/connection_driver.rb
@@ -168,7 +168,9 @@ module Qpid
       #   {#dispatch} and {#process}
       def initialize(io, handler)
         super(io)
-        @handler = handler
+        # Allow multiple handlers for backwards compatibility
+        a = Array(handler)
+        @handler = a.size > 1 ? MessagingHandlers.new(a) : handler
         @adapter = Handler::Adapter.try_convert(handler)
       end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index df89d1a..fdc0247 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -106,11 +106,9 @@ module Qpid::Proton
     def initialize(handler = nil, id = nil)
       # Allow ID as sole argument
       (handler, id = nil, handler.to_str) if (id.nil? && handler.respond_to?(:to_str))
-      raise TypeError, "Expected MessagingHandler, got #{handler.class}" if
-        handler && !handler.is_a?(Qpid::Proton::Handler::MessagingHandler)
-
-      # TODO aconway 2017-11-08: allow multiple handlers, opts for backwards compat?
-      @handler = handler
+      # Allow multiple handlers for backwards compatibility
+      a = Array(handler)
+      @handler = a.size > 1 ? MessagingHandlers.new(a) : handler
       @id = ((id && id.to_s) || SecureRandom.uuid).freeze
 
       # Implementation note:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/core/messaging_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/messaging_handler.rb b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
index b6b07c7..580a4ab 100644
--- a/proton-c/bindings/ruby/lib/core/messaging_handler.rb
+++ b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
@@ -160,16 +160,15 @@ module Qpid::Proton
     # @param event [Event] the event, {Event#method} provides the original method name.
   end
 
-  # An array of {MessagingHandler}, events are dispatched to each in turn
+  # A {MessagingHandler} that delegates events to an array of handlers, in order.
   class MessagingHandlers < MessagingHandler
-    include Enumerable
+    # @param handlers [Array<MessagingHandler>] handler objects
+    def initialize(handlers) @handlers = handlers; end
 
-    # @param handlers an array of {MessagingHandler} objects
-    def initialize handlers; @handlers = handlers; end
-
-    def each(*args, &block) @handlers.each(*args, &block); end
-
-    def on_unhandled(event) each { |h| event.dispatch h }; end
+    # @return [Array<MessagingHandler>] array of handlers
+    attr_reader :handlers
 
+    # Dispatch events to each of {#handlers} in turn
+    def on_unhandled(event) @handlers.each { |h| event.dispatch h }; end
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/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 2efa2b7..6cf3831 100644
--- a/proton-c/bindings/ruby/lib/handler/adapter.rb
+++ b/proton-c/bindings/ruby/lib/handler/adapter.rb
@@ -28,7 +28,7 @@ module Qpid::Proton::Handler
 
     def initialize handler
       @handler = handler || MessagingHandler.new # Pick up default MH behavior
-      @opts = handler.respond_to?(:options) ? handler.options : {}
+      @opts = (handler.options if handler.respond_to?(:options)) || {}
       @opts[:prefetch] ||= 10
       @opts[:peer_close_is_error] = false unless @opts.include? :peer_close_is_error
       [:auto_accept, :auto_settle, :auto_open, :auto_close].each do |k|

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
deleted file mode 100644
index 98b8d3a..0000000
--- a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-#--
-# 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.
-#++
-
-# @private
-module Qpid::Proton::Handler
-
-  # Mixin to convert raw proton endpoint events to {#MessagingHandler} events
-  #
-  # A XXX_opening method will be called when the remote peer has requested
-  # an open that was not initiated locally. By default this will simply open
-  # locally, which then trigtgers the XXX_opened called.
-  #
-  # A XXX_opened method will be called when both local and remote peers have
-  # opened the link, session or connection. This can be used to confirm a
-  # locally initiated action for example.
-  #
-  # The same applies to close.
-  #
-  module EndpointStateHandler
-
-    def on_link_remote_close(event)
-      super
-      if !event.link.remote_condition.nil?
-        self.on_link_error(event)
-      elsif event.link.local_closed?
-        self.on_link_closed(event)
-      else
-        self.on_link_closing(event)
-      end
-      event.link.close
-    end
-
-    def on_session_remote_close(event)
-      super
-      if !event.session.remote_condition.nil?
-        self.on_session_error(event)
-      elsif event.session.local_closed?
-        self.on_session_closed(event)
-      else
-        self.on_session_closing(event)
-      end
-      event.session.close
-    end
-
-    def on_connection_remote_close(event)
-      super
-      if !event.connection.remote_condition.nil?
-        self.on_connection_error(event)
-      elsif event.connection.local_closed?
-        self.on_connection_closed(event)
-      else
-        self.on_connection_closing(event)
-      end
-      event.connection.close
-    end
-
-    def on_connection_local_open(event)
-      super
-      self.on_connection_opened(event) if event.connection.remote_active?
-    end
-
-    def on_connection_remote_open(event)
-      super
-      if event.connection.local_active?
-        self.on_connection_opened(event)
-      elsif event.connection.local_uninit?
-        self.on_connection_opening(event)
-        event.connection.open unless event.connection.local_active?
-      end
-    end
-
-    def on_session_local_open(event)
-      super
-      self.on_session_opened(event) if event.session.remote_active?
-    end
-
-    def on_session_remote_open(event)
-      super
-      if !(event.session.state & Qpid::Proton::Endpoint::LOCAL_ACTIVE).zero?
-        self.on_session_opened(event)
-      elsif event.session.local_uninit?
-        self.on_session_opening(event)
-        event.session.open
-      end
-    end
-
-    def on_link_local_open(event)
-      super
-      self.on_link_opened(event) if event.link.remote_active?
-    end
-
-    def on_link_remote_open(event)
-      super
-      if event.link.local_active?
-        self.on_link_opened(event)
-      elsif event.link.local_uninit?
-        self.on_link_opening(event)
-        event.link.open
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/handler/flow_controller.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/flow_controller.rb b/proton-c/bindings/ruby/lib/handler/flow_controller.rb
deleted file mode 100644
index 38d925f..0000000
--- a/proton-c/bindings/ruby/lib/handler/flow_controller.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-#--
-# 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.
-#++
-
-# @private
-module Qpid::Proton::Handler
-
-  # Mixin to establish automatic flow control for a prefetch window
-  # Uses {#@prefetch}
-  #
-  module FlowController
-
-    def on_link_local_open(event) topup(event); super; end
-    def on_link_remote_open(event) topup(event); super; end
-    def on_delivery(event) topup(event); super; end
-    def on_link_flow(event) topup(event); super; end
-
-    def add_credit(event)
-      r = event.receiver
-      if r && r.open? && (r.drained == 0) && @handler.prefetch && (@handler.prefetch > r.credit)
-        r.flow(@handler.prefetch - r.credit)
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
deleted file mode 100644
index 9f34d0d..0000000
--- a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-#--
-# 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.
-#++
-
-# @private
-module Qpid::Proton::Handler
-  private
-
-  # A utility for simpler and more intuitive handling of delivery events
-  # related to incoming messages.
-  #
-  # uses @auto_accept
-  #
-  module IncomingMessageHandler
-    def on_delivery(event)
-      super
-      delivery = event.delivery
-      return unless delivery.link.receiver?
-      if delivery.readable? && !delivery.partial?
-        m = Qpid::Proton::Message.new
-        m.receive(delivery)
-        event.message = m
-        if event.link.local_closed?
-          delivery.settle Qpid::Proton::Delivery::RELEASED if @auto_accept
-        else
-          begin
-            self.on_message(event)
-            delivery.settle Qpid::Proton::Delivery::ACCEPTED if @auto_accept
-          rescue Qpid::Proton::Reject
-            delivery.settle REJECTED
-          rescue Qpid::Proton::Release
-            delivery.settle MODIFIED
-          end
-        end
-      elsif delivery.updated? && delivery.settled?
-        self.on_settled(event)
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
deleted file mode 100644
index cedcead..0000000
--- a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  # A utility for simpler and more intuitive handling of delivery events
-  # related to outgoing messages.
-  #
-  # Uses {#@auto_settle}
-  module OutgoingMessageHandler
-
-    def on_link_flow(event)
-      super
-      self.on_sendable(event) if event.link.sender? && event.link.credit > 0 &&
-                                 (event.link.state & Qpid::Proton::Endpoint::LOCAL_ACTIVE) &&
-                                 (event.link.state & Qpid::Proton::Endpoint::REMOTE_ACTIVE)
-    end
-
-    def on_delivery(event)
-      super
-      delivery = event.delivery
-      if delivery.link.sender? && delivery.updated?
-        if delivery.remote_accepted?
-          self.on_accepted(event)
-        elsif delivery.remote_rejected?
-          self.on_rejected(event)
-        elsif delivery.remote_released? || delivery.remote_modified?
-          self.on_released(event)
-        end
-        self.on_settled(event) if delivery.settled?
-        delivery.settle if @auto_settle
-      end
-    end
-  end
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index d3040a0..ab24dfd 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -82,10 +82,6 @@ require "messenger/tracker"
 require "messenger/messenger"
 
 # Handler classes
-require "handler/endpoint_state_handler"
-require "handler/incoming_message_handler"
-require "handler/outgoing_message_handler"
-require "handler/flow_controller"
 require "handler/adapter"
 
 # Core classes that depend on Handler

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/proton-c/bindings/ruby/tests/test_container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_container.rb b/proton-c/bindings/ruby/tests/test_container.rb
index 173c421..519ca65 100644
--- a/proton-c/bindings/ruby/tests/test_container.rb
+++ b/proton-c/bindings/ruby/tests/test_container.rb
@@ -84,7 +84,19 @@ class ContainerTest < Minitest::Test
 
   class CloseOnOpenHandler < TestHandler
     def on_connection_opened(e) e.connection.close; end
-    def on_connection_closing(e) e.connection.close; end
+  end
+
+  def test_multi_handler
+    handler_class = Class.new(CloseOnOpenHandler) do
+      @@opened = 0
+      def self.opened; @@opened; end
+      def on_connection_opened(e) @@opened += 1; super; end
+    end
+    hs = 3.times.collect { handler_class.new }
+    c = TestContainer.new(hs)
+    c.connect(c.url)
+    c.run
+    assert_equal 6, handler_class.opened # Opened at each end * 3 handlers
   end
 
   def test_auto_stop_one

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06fbad39/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 120c488..eea0057 100644
--- a/proton-c/bindings/ruby/tests/test_tools.rb
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -45,8 +45,6 @@ end
 
 # Handler that records some common events that are checked by tests
 class TestHandler < MessagingHandler
-  # TODO aconway 2017-10-28: make on_error stuff part of the default handler.
-
   attr_reader :errors, :connections, :sessions, :links, :messages
 
   # Pass optional extra handlers and options to the Container


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


[05/12] qpid-proton git commit: PROTON-1064: [ruby] Consistent option handling, handle nil options

Posted by ac...@apache.org.
PROTON-1064: [ruby] Consistent option handling, handle nil options


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

Branch: refs/heads/master
Commit: f70764f52811b81008dec6a1dd00b68611139185
Parents: 12aaab9
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Nov 21 14:58:59 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/connection.rb  |  8 +++---
 proton-c/bindings/ruby/lib/core/container.rb   | 19 ++++++------
 proton-c/bindings/ruby/lib/core/listener.rb    |  2 +-
 proton-c/bindings/ruby/lib/core/session.rb     | 32 +++++++++++----------
 proton-c/bindings/ruby/tests/test_container.rb |  4 +--
 proton-c/bindings/ruby/tests/test_tools.rb     |  4 +--
 6 files changed, 36 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index 0c878d4..4bd7e4f 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -201,9 +201,9 @@ module Qpid::Proton
     # @option opts [String] :sasl_allowed_mechs the allowed SASL mechanisms for use on the connection.
     # @option opts [String] :container_id AMQP container ID, normally provided by {Container}
     #
-    def open(opts={})
+    def open(opts=nil)
       return if local_active?
-      apply opts
+      apply opts if opts
       Cproton.pn_connection_open(@impl)
     end
 
@@ -272,10 +272,10 @@ module Qpid::Proton
     end
 
     # Open a sender on the default_session
-    def open_sender(opts = {}) default_session.open_sender(opts) end
+    def open_sender(opts=nil) default_session.open_sender(opts) end
 
     # Open a  on the default_session
-    def open_receiver(opts = {}) default_session.open_receiver(opts) end
+    def open_receiver(opts=nil) default_session.open_receiver(opts) end
 
     # Returns the first session from the connection that matches the specified
     # state mask.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 39ac150..05c45ed 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -170,11 +170,14 @@ module Qpid::Proton
     # url.user, url.password are used as defaults if opts[:user], opts[:password] are nil
     # @option (see Connection#open)
     # @return [Connection] The new AMQP connection
-    def connect(url, opts = {})
+    def connect(url, opts=nil)
       not_stopped
-      url = Qpid::Proton::uri(url)
-      opts[:user] ||= url.user
-      opts[:password] ||= url.password
+      url = Qpid::Proton::uri url
+      if url.user ||  url.password
+        opts ||= {}
+        opts[:user] ||= url.user
+        opts[:password] ||= url.password
+      end
       # TODO aconway 2017-10-26: Use SSL for amqps URLs
       connect_io(TCPSocket.new(url.host, url.port), opts)
     end
@@ -182,7 +185,7 @@ module Qpid::Proton
     # Open an AMQP protocol connection on an existing {IO} object
     # @param io [IO] An existing {IO} object, e.g. a {TCPSocket}
     # @option (see Connection#open)
-    def connect_io(io, opts = {})
+    def connect_io(io, opts=nil)
       not_stopped
       cd = connection_driver(io, opts)
       cd.connection.open()
@@ -199,8 +202,8 @@ module Qpid::Proton
     #
     def listen(url, handler=Listener::Handler.new)
       not_stopped
-      url = Qpid::Proton::uri(url)
-      # TODO aconway 2017-11-01: amqps
+      url = Qpid::Proton::uri url
+      # TODO aconway 2017-11-01: amqps, SSL
       listen_io(TCPServer.new(url.host, url.port), handler)
     end
 
@@ -321,7 +324,7 @@ module Qpid::Proton
       end
     end
 
-    def connection_driver(io, opts, server=false)
+    def connection_driver(io, opts=nil, server=false)
       opts ||= {}
       opts[:container_id] ||= @id
       opts[:handler] ||= @handler

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/proton-c/bindings/ruby/lib/core/listener.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/listener.rb b/proton-c/bindings/ruby/lib/core/listener.rb
index 0584807..35dfe20 100644
--- a/proton-c/bindings/ruby/lib/core/listener.rb
+++ b/proton-c/bindings/ruby/lib/core/listener.rb
@@ -32,7 +32,7 @@ module Qpid::Proton
     # methods to provide more interesting behaviour.
     class Handler
       # @param opts [Hash] Options to return from on_accept.
-      def initialize(opts={}) @opts = opts; end
+      def initialize(opts=nil) @opts = opts || {}; end
 
       # Called when the listener is ready to accept connections.
       # @param listener [Listener] The listener

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/proton-c/bindings/ruby/lib/core/session.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/session.rb b/proton-c/bindings/ruby/lib/core/session.rb
index 3120d3f..a21c152 100644
--- a/proton-c/bindings/ruby/lib/core/session.rb
+++ b/proton-c/bindings/ruby/lib/core/session.rb
@@ -127,25 +127,27 @@ module Qpid::Proton
     def receiver(name) Receiver.new(Cproton.pn_receiver(@impl, name)); end
 
     # TODO aconway 2016-01-04: doc options or target param, move option handling to Link.
-    def open_receiver(options = {})
-      options = { :source => options } if options.is_a? String
-      receiver = Receiver.new Cproton.pn_receiver(@impl, options[:name] || connection.link_name)
-      receiver.source.address ||= options[:source]
-      receiver.target.address ||= options[:target]
-      receiver.source.dynamic = true if options[:dynamic]
-      receiver.handler = options[:handler] if !options[:handler].nil?
+    def open_receiver(opts=nil)
+      opts = { :source => opts } if opts.is_a? String
+      opts ||= {}
+      receiver = Receiver.new Cproton.pn_receiver(@impl, opts[:name] || connection.link_name)
+      receiver.source.address ||= opts[:source]
+      receiver.target.address ||= opts[:target]
+      receiver.source.dynamic = true if opts[:dynamic]
+      receiver.handler = opts[:handler] if !opts[:handler].nil?
       receiver.open
       return receiver
     end
 
-    # TODO aconway 2016-01-04: doc options or target param
-    def open_sender(options = {})
-      options = { :target => options } if options.is_a? String
-      sender = Sender.new Cproton.pn_sender(@impl, options[:name] || connection.link_name)
-      sender.target.address ||= options[:target]
-      sender.source.address ||= options[:source]
-      sender.target.dynamic = true if options[:dynamic]
-      sender.handler = options[:handler] if !options[:handler].nil?
+    # TODO aconway 2016-01-04: doc opts or target param
+    def open_sender(opts=nil)
+      opts = { :target => opts } if opts.is_a? String
+      opts ||= {}
+      sender = Sender.new Cproton.pn_sender(@impl, opts[:name] || connection.link_name)
+      sender.target.address ||= opts[:target]
+      sender.source.address ||= opts[:source]
+      sender.target.dynamic = true if opts[:dynamic]
+      sender.handler = opts[:handler] if !opts[:handler].nil?
       sender.open
       return sender
     end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/proton-c/bindings/ruby/tests/test_container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_container.rb b/proton-c/bindings/ruby/tests/test_container.rb
index 988acfb..f89ffbe 100644
--- a/proton-c/bindings/ruby/tests/test_container.rb
+++ b/proton-c/bindings/ruby/tests/test_container.rb
@@ -31,7 +31,7 @@ Thread::abort_on_exception=true
 # Container that listens on a random port
 class TestContainer < Container
 
-  def initialize(handler, lopts = {}, id=nil)
+  def initialize(handler, lopts=nil, id=nil)
     super handler, id
     @server = TCPServer.open(0)
     @listener = listen_io(@server, ListenOnceHandler.new(lopts))
@@ -160,7 +160,7 @@ class ContainerSASLTest < Minitest::Test
   # Handler for test client/server that sets up server and client SASL options
   class SASLHandler < TestHandler
 
-    def initialize(url="amqp://", opts={}, mechanisms=nil, insecure=nil, realm=nil)
+    def initialize(url="amqp://", opts=nil, mechanisms=nil, insecure=nil, realm=nil)
       super()
       @url, @opts, @mechanisms, @insecure, @realm = url, opts, mechanisms, insecure, realm
     end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70764f5/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 3b89cd0..e64d36b 100644
--- a/proton-c/bindings/ruby/tests/test_tools.rb
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -112,8 +112,6 @@ end
 
 # ListenHandler that closes the Listener after first accept
 class ListenOnceHandler < ListenHandler
-  def initialize(opts={}) @opts=opts; end
   def on_error(l, e)  raise TestError, e.inspect; end
-  def on_accept(l) l.close; return @opts; end
-  attr_reader :opts
+  def on_accept(l) l.close; super; end
 end


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


[08/12] qpid-proton git commit: PROTON-1064: [ruby] move engine.rb "helpers" to proper classes

Posted by ac...@apache.org.
PROTON-1064: [ruby] move engine.rb "helpers" to proper classes

Move utils/engine.rb "helper" methods directly to the relevant classes: Message, Data, Condition


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

Branch: refs/heads/master
Commit: de2d4908b8393c74f5cb7b11d14d37abeac561e0
Parents: 1f06e4b
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 15:59:27 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/codec/data.rb        | 17 ++--
 proton-c/bindings/ruby/lib/core/condition.rb    | 21 +++--
 proton-c/bindings/ruby/lib/core/connection.rb   | 13 ++--
 proton-c/bindings/ruby/lib/core/delivery.rb     |  8 +-
 proton-c/bindings/ruby/lib/core/disposition.rb  |  9 +--
 proton-c/bindings/ruby/lib/core/endpoint.rb     |  9 +--
 proton-c/bindings/ruby/lib/core/message.rb      | 22 ++++--
 proton-c/bindings/ruby/lib/core/transport.rb    | 21 +----
 .../lib/handler/incoming_message_handler.rb     |  4 +-
 proton-c/bindings/ruby/lib/qpid_proton.rb       |  1 -
 proton-c/bindings/ruby/lib/util/engine.rb       | 82 --------------------
 11 files changed, 65 insertions(+), 142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/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 be13512..bb242dc 100644
--- a/proton-c/bindings/ruby/lib/codec/data.rb
+++ b/proton-c/bindings/ruby/lib/codec/data.rb
@@ -80,16 +80,21 @@ module Qpid::Proton::Codec
   #
   class Data
 
-    # Creates a new instance with the specified capacity.
-    #
-    # @param capacity [Integer, Object] The initial capacity or content.
-    #
+    private
+
+    def self.to_object(impl) Data.new(impl).rewind.object; end
+    def self.from_object(impl, x) Data.new(impl).rewind.object = x; end
+
+    public
+
+    # Creates a new instance.
+    # @param capacity [Integer] capacity for the new data instance.
     def initialize(capacity = 16)
-      # TODO aconway 2017-08-11: error prone, confusion between capacity and Integer content.
       if capacity.is_a?(Integer)
         @data = Cproton.pn_data(capacity.to_i)
         @free = true
       else
+        # Assume non-integer capacity is a SWIG::pn_data_t*
         @data = capacity
         @free = false
       end
@@ -125,8 +130,10 @@ module Qpid::Proton::Codec
     # Clearing the current node sets it *before* the first node, calling
     # #next will advance to the first node.
     #
+    # @return self
     def rewind
       Cproton.pn_data_rewind(@data)
+      self
     end
 
     # Advances the current node to its next sibling and returns its types.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/condition.rb b/proton-c/bindings/ruby/lib/core/condition.rb
index 2b0e1bf..b0b8de7 100644
--- a/proton-c/bindings/ruby/lib/core/condition.rb
+++ b/proton-c/bindings/ruby/lib/core/condition.rb
@@ -50,16 +50,27 @@ module Qpid::Proton
     # - else return Condition(default_name, obj.to_s)
     def self.make(obj, default_name="proton")
       case obj
+      when nil then nil
       when Condition then obj
       when Exception then Condition.new(obj.class.name, obj.to_s)
-      when nil then nil
+      when SWIG::TYPE_p_pn_condition_t
+        if Cproton.pn_condition_is_set(obj)
+          Condition.new(Cproton.pn_condition_get_name(obj),
+                        Cproton.pn_condition_get_description(obj),
+                        Codec::Data.to_object(Cproton.pn_condition_info(obj)))
+        end
       else Condition.new(default_name, obj.to_s)
       end
     end
 
-  end
-
-  module Util                   #TODO aconway 2017-10-28: backwards compat
-    Condition = Qpid::Proton::Condition
+    private
+    def self.from_object(impl, cond)
+      Cproton.pn_condition_clear(impl)
+      if cond
+        Cproton.pn_condition_set_name(impl, cond.name) if cond.name
+        Cproton.pn_condition_set_description(impl, cond.description) if cond.description
+        Codec::Data.from_object(Cproton.pn_condition_info(impl), cond.info) if cond.info
+      end
+    end
   end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index fbef0cd..318e925 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -160,7 +160,8 @@ module Qpid::Proton
     # @return [Data] The offered capabilities.
     #
     def remote_offered_capabilities
-      data_to_object(Cproton.pn_connection_remote_offered_capabilities(@impl))
+      # FIXME aconway 2017-11-22: doesn't match doc - returning object, not Data
+      Codec::Data.to_object(Cproton.pn_connection_remote_offered_capabilities(@impl))
     end
 
     # Get the AMQP desired capabilities supplied by the remote connection
@@ -173,7 +174,7 @@ module Qpid::Proton
     # @return [Data] The desired capabilities.
     #
     def remote_desired_capabilities
-      data_to_object(Cproton.pn_connection_remote_desired_capabilities(@impl))
+      Codec::Data.to_object(Cproton.pn_connection_remote_desired_capabilities(@impl))
     end
 
     # Get the AMQP connection properties supplie by the remote connection
@@ -186,7 +187,7 @@ module Qpid::Proton
     # @return [Data] The remote properties.
     #
     def remote_properties
-      data_to_object(Cproton.pn_connection_remote_properites(@impl))
+      Codec::Data.to_object(Cproton.pn_connection_remote_properites(@impl))
     end
 
     # Open the local end of the connection.
@@ -216,9 +217,9 @@ module Qpid::Proton
       Cproton.pn_connection_set_user(@impl, opts[:user]) if opts[:user]
       Cproton.pn_connection_set_password(@impl, opts[:password]) if opts[:password]
       @link_prefix = opts[:link_prefix] || container_id
-      object_to_data(opts[:offered_capabilities], Cproton.pn_connection_offered_capabilities(@impl))
-      object_to_data(opts[:desired_capabilities], Cproton.pn_connection_desired_capabilities(@impl))
-      object_to_data(opts[:properties], Cproton.pn_connection_properties(@impl))
+      Codec::Data.from_object(Cproton.pn_connection_offered_capabilities(@impl), opts[:offered_capabilities])
+      Codec::Data.from_object(Cproton.pn_connection_desired_capabilities(@impl), opts[:desired_capabilities])
+      Codec::Data.from_object(Cproton.pn_connection_properties(@impl), opts[:properties])
     end
 
     # @private Generate a unique link name, internal use only.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/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 8849840..47b23d6 100644
--- a/proton-c/bindings/ruby/lib/core/delivery.rb
+++ b/proton-c/bindings/ruby/lib/core/delivery.rb
@@ -148,13 +148,11 @@ module Qpid::Proton
     #
     proton_caller :buffered?
 
-    include Util::Engine
-
     def update(state)
       impl = @local.impl
-      object_to_data(@local.data, Cproton.pn_disposition_data(impl))
-      object_to_data(@local.annotations, Cproton.pn_disposition_annotations(impl))
-      object_to_data(@local.condition, Cproton.pn_disposition_condition(impl))
+      Codec::Data.from_object(Cproton.pn_disposition_data(impl), @local.data)
+      Codec::Data::from_object(Cproton.pn_disposition_annotations(impl), @local.annotations)
+      Condition.from_object(Cproton.pn_disposition_condition(impl), @local.condition)
       Cproton.pn_delivery_update(@impl, state)
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/disposition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/disposition.rb b/proton-c/bindings/ruby/lib/core/disposition.rb
index daa7069..37f94a5 100644
--- a/proton-c/bindings/ruby/lib/core/disposition.rb
+++ b/proton-c/bindings/ruby/lib/core/disposition.rb
@@ -40,9 +40,6 @@ module Qpid::Proton
     # Indicates the delivery was modified.
     self.add_constant(:MODIFIED, Cproton::PN_MODIFIED)
 
-    # @private
-    include Util::Engine
-
     attr_reader :impl
 
     # @private
@@ -103,7 +100,7 @@ module Qpid::Proton
       if @local
         @data
       else
-        data_to_object(Cproton.pn_disposition_data(@impl))
+        Codec::Data.to_object(Cproton.pn_disposition_data(@impl))
       end
     end
 
@@ -126,7 +123,7 @@ module Qpid::Proton
       if @local
         @annotations
       else
-        data_to_object(Cproton.pn_disposition_annotations(@impl))
+        Codec::Data.to_object(Cproton.pn_disposition_annotations(@impl))
       end
     end
 
@@ -149,7 +146,7 @@ module Qpid::Proton
       if @local
         @condition
       else
-        condition_to_object(Cproton.pn_disposition_condition(@impl))
+        Condition.make(Cproton.pn_disposition_condition(@impl))
       end
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/endpoint.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/endpoint.rb b/proton-c/bindings/ruby/lib/core/endpoint.rb
index 53f5d49..7ef18c8 100644
--- a/proton-c/bindings/ruby/lib/core/endpoint.rb
+++ b/proton-c/bindings/ruby/lib/core/endpoint.rb
@@ -57,24 +57,21 @@ module Qpid::Proton
                   Cproton::PN_REMOTE_CLOSED
 
     # @private
-    include Util::Engine
-
-    # @private
     def initialize
       @condition = nil
     end
 
     # @private
     def _update_condition
-      object_to_condition(@condition, self._local_condition)
+      Condition.from_object(self._local_condition, @condition)
     end
 
     def condition
-      condition_to_object(_local_condition) || remote_condition; end
+      Condition.make(_local_condition) || remote_condition; end
 
     # @private
     def remote_condition
-      condition_to_object(self._remote_condition)
+      Condition.make(_remote_condition)
     end
 
     # Return the transport associated with this endpoint.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index cbbe905..ae0f9d1 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -43,19 +43,25 @@ module Qpid::Proton
       return dlv
     end
 
-    # Decodes a message from supplied AMQP data and returns the number
-    # of bytes consumed.
-    #
-    # ==== Options
-    #
-    # * encoded - the encoded data
-    #
+    # Decodes a message from AMQP binary data.
+    # @param encoded [String] the encoded bytes
+    # @return[Integer] the number of bytes consumed
     def decode(encoded)
       check(Cproton.pn_message_decode(@impl, encoded, encoded.length))
-
       post_decode
     end
 
+    # Receive and decode a message from a delivery.
+    #
+    # @param delivery [Delivery] the delivery
+    # @return [Integer] the number of bytes decoded
+    def receive(delivery)
+      raise RangeError, "delivery is incomplete" if delivery.partial?
+      n = decode(delivery.link.receive(delivery.pending))
+      delivery.link.advance
+      return n
+    end
+
     def post_decode # :nodoc:
       # decode elements from the message
       @properties = {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index 8804c8a..7b70ffc 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -64,9 +64,6 @@ module Qpid::Proton
   #
   class Transport
 
-    # @private
-    include Util::Engine
-
     # Turn logging off entirely.
     TRACE_OFF = Cproton::PN_TRACE_OFF
     # Log raw binary data into/out of the transport.
@@ -229,25 +226,15 @@ module Qpid::Proton
       Cproton.pn_transport_quiesced(@impl)
     end
 
-    # Returns additional information about the condition of the transport.
-    #
-    # When a TRANSPORT_ERROR event occurs, this operaiton can be used to
-    # access the details of the error condition.
-    #
-    # The object returned is valid until the Transport is discarded.
-    #
+    # @return [Condition, nil] transport error condition or nil if there is no error.
     def condition
-      condition_to_object Cproton.pn_transport_condition(@impl)
+      Condition.make(Cproton.pn_transport_condition(@impl))
     end
 
-    # Set the condition of the transport.
-    #
-    # Setting a non-empty condition before closing the transport will cause a
-    # TRANSPORT_ERROR event.
-    #
+    # Set the error condition for the transport.
     # @param c [Condition] The condition to set
     def condition=(c)
-      object_to_condition c, Cproton.pn_transport_condition(@impl)
+      Condition.from_object(Cproton.pn_transport_condition(@impl), Condition.make(c))
     end
 
     # Binds to the given connection.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
index ff59073..a64cffc 100644
--- a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
@@ -35,7 +35,9 @@ module Qpid::Proton::Handler
       delivery = event.delivery
       return unless delivery.link.receiver?
       if delivery.readable? && !delivery.partial?
-        event.message = Qpid::Proton::Util::Engine.receive_message(delivery)
+        m = Qpid::Proton::Message.new
+        m.receive(delivery)
+        event.message = m
         if event.link.local_closed?
           if @auto_accept
             delivery.update(Qpid::Proton::Disposition::RELEASED)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index a733393..4a1f677 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -43,7 +43,6 @@ require "util/constants"
 require "util/swig_helper"
 require "util/wrapper"
 require "util/class_wrapper"
-require "util/engine"
 require "util/timeout"
 require "util/handler"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de2d4908/proton-c/bindings/ruby/lib/util/engine.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/engine.rb b/proton-c/bindings/ruby/lib/util/engine.rb
deleted file mode 100644
index fa5c038..0000000
--- a/proton-c/bindings/ruby/lib/util/engine.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-#--
-# 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::Proton::Util
-
-  # @private
-  module Engine
-
-    # Convenience method to receive messages from a delivery.
-    #
-    # @param delivery [Qpid::Proton::Delivery] The delivery.
-    # @param msg [Qpid::Proton::Message] The message to use.
-    #
-    # @return [Qpid::Proton::Message] the message
-    #
-    def self.receive_message(delivery, msg = nil)
-      msg = Qpid::Proton::Message.new if msg.nil?
-      msg.decode(delivery.link.receive(delivery.pending))
-      delivery.link.advance
-      return msg
-    end
-
-    def data_to_object(data_impl) # :nodoc:
-      object = nil
-      unless data_impl.nil?
-        data = Qpid::Proton::Codec::Data.new(data_impl)
-        data.rewind
-        data.next
-        object = data.object
-        data.rewind
-      end
-      return object
-    end
-
-    def object_to_data(object, data_impl) # :nodoc:
-      unless object.nil?
-        data = Data.new(data_impl)
-        data.object = object
-      end
-    end
-
-    def condition_to_object(condition) # :nodoc:
-      result = nil
-      if Cproton.pn_condition_is_set(condition)
-        result = Condition.new(Cproton.pn_condition_get_name(condition),
-                               Cproton.pn_condition_get_description(condition),
-                               data_to_object(Cproton.pn_condition_info(condition)))
-      end
-      return result
-    end
-
-    def object_to_condition(object, condition) # :nodoc:
-      Cproton.pn_condition_clear(condition)
-      unless object.nil?
-        Cproton.pn_condition_set_name(condition, object.name)
-        Cproton.pn_condition_set_description(condition, object.description)
-        if !object.info.nil?
-          info = Data.new(Cproton.pn_condition_info(condition))
-          info.object = object.info
-        end
-      end
-    end
-
-  end
-
-end


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


[06/12] qpid-proton git commit: PROTON-1064: [ruby] Messenger deprecation message

Posted by ac...@apache.org.
PROTON-1064: [ruby] Messenger deprecation message


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

Branch: refs/heads/master
Commit: 67c4baecf77dd9bfcbe092b039cbaf7461bc8054
Parents: f70764f
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Nov 21 15:41:29 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/messenger/messenger.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/67c4baec/proton-c/bindings/ruby/lib/messenger/messenger.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/messenger/messenger.rb b/proton-c/bindings/ruby/lib/messenger/messenger.rb
index 06ce031..aaeee1e 100644
--- a/proton-c/bindings/ruby/lib/messenger/messenger.rb
+++ b/proton-c/bindings/ruby/lib/messenger/messenger.rb
@@ -73,7 +73,7 @@ module Qpid::Proton::Messenger
     # * name - the name (def. nil)
     #
     def initialize(name = nil)
-      warn "[DEPRECATION] `Qpid::Proton::Messenger` is deprecated, use `Qpid::Proton::Container`"
+      deprecated 'Qpid::Proton::Messenger', 'Qpid::Proton::Container'
       @impl = Cproton.pn_messenger(name)
       @selectables = {}
       ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))


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


[04/12] qpid-proton git commit: PROTON-1064: [ruby] Move MessagingHandler to core

Posted by ac...@apache.org.
PROTON-1064: [ruby] Move MessagingHandler to core


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

Branch: refs/heads/master
Commit: 1f06e4bf9ca2f2d7cd130adb1494c0b18296345b
Parents: 15c804c
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 15:14:19 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Nov 30 16:36:26 2017 -0500

----------------------------------------------------------------------
 .../bindings/ruby/lib/core/messaging_handler.rb | 216 +++++++++++++++++++
 .../ruby/lib/handler/endpoint_state_handler.rb  |   2 +-
 .../lib/handler/incoming_message_handler.rb     |   2 +-
 .../ruby/lib/handler/messaging_handler.rb       | 216 -------------------
 .../lib/handler/outgoing_message_handler.rb     |   2 +-
 proton-c/bindings/ruby/lib/qpid_proton.rb       |  14 +-
 6 files changed, 227 insertions(+), 225 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/core/messaging_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/messaging_handler.rb b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
new file mode 100644
index 0000000..3babc05
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/core/messaging_handler.rb
@@ -0,0 +1,216 @@
+#--
+# 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::Proton
+
+  # A general purpose handler that simplifies processing events.
+  #
+  class MessagingHandler
+
+    attr_reader :handlers
+
+    # Creates a new instance.
+    #
+    # @param [Integer] prefetch
+    # @param [Boolean] auto_accept
+    # @param [Boolean] auto_settle
+    # @param [Boolean] peer_close_is_error
+    #
+    def initialize(prefetch = 10, auto_accept = true, auto_settle = true, peer_close_is_error = false)
+      @handlers = Array.new
+      @handlers << Handler::CFlowController.new(prefetch) unless prefetch.zero?
+      @handlers << Handler::EndpointStateHandler.new(peer_close_is_error, self)
+      @handlers << Handler::IncomingMessageHandler.new(auto_accept, self)
+      @handlers << Handler::OutgoingMessageHandler.new(auto_settle,self)
+    end
+
+    # Called when the peer closes the connection with an error condition.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_connection_error(event)
+      Handler::EndpointStateHandler.print_error(event.connection, "connection")
+    end
+
+      # Called when the peer closes the session with an error condition.
+      #
+      # @param event [Qpid:Proton::Event::Event] The event.
+      #
+    def on_session_error(event)
+      Handler::EndpointStateHandler.print_error(event.session, "session")
+      event.connection.close
+    end
+
+    # Called when the peer closes the link with an error condition.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_link_error(event)
+      Handler::EndpointStateHandler.print_error(event.link, "link")
+      event.connection.close
+    end
+
+    # Called when the event loop starts.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_reactor_init(event)
+      self.on_start(event)
+    end
+
+    # Called when the event loop starts.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_start(event)
+    end
+
+    # Called when the connection is closed.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_connection_closed(event)
+    end
+
+    # Called when the session is closed.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_session_closed(event)
+    end
+
+    # Called when the link is closed.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_link_closed(event)
+    end
+
+    # Called when the peer initiates the closing of the connection.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_connection_closing(event)
+    end
+
+    # Called when the peer initiates the closing of the session.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_session_closing(event)
+    end
+
+    # Called when the peer initiates the closing of the link.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_link_closing(event)
+    end
+
+    # Called when the socket is disconnected.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_disconnected(event)
+    end
+
+    # Called when the sender link has credit and messages can therefore
+    # be transferred.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_sendable(event)
+    end
+
+    # Called when the remote peer accepts an outgoing message.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_accepted(event)
+    end
+
+    # Called when the remote peer rejects an outgoing message.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_rejected(event)
+    end
+
+    # Called when the remote peer releases an outgoing message.
+    #
+    # Note that this may be in response to either the RELEASE or
+    # MODIFIED state as defined by the AMPQ specification.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_released(event)
+    end
+
+    # Called when the remote peer has settled hte outgoing message.
+    #
+    # This is the point at which it should never be retransmitted.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_settled(event)
+    end
+
+    # Called when a message is received.
+    #
+    # The message itself can be obtained as a property on the event. For
+    # the purpose of referring to this message in further actions, such as
+    # explicitly accepting it) the delivery should be used. This is also
+    # obtainable vi a property on the event.
+    #
+    # This method needs to be overridden.
+    #
+    # @param event [Qpid::Proton::Event::Event] The event.
+    #
+    def on_message(event)
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
index 8a1a16e..7f0c85b 100644
--- a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
@@ -32,7 +32,7 @@ module Qpid::Proton::Handler
   #
   # The same applies to close.
   #
-  class EndpointStateHandler < Qpid::Proton::BaseHandler
+  class EndpointStateHandler
 
     def initialize(peer_close_is_error = false, delegate = nil)
       @delegate = delegate

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
index ced84a2..ff59073 100644
--- a/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/incoming_message_handler.rb
@@ -22,7 +22,7 @@ module Qpid::Proton::Handler
   # A utility for simpler and more intuitive handling of delivery events
   # related to incoming messages.
   #
-  class IncomingMessageHandler < Qpid::Proton::BaseHandler
+  class IncomingMessageHandler
 
     include Acking
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/messaging_handler.rb b/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
deleted file mode 100644
index d97fe3d..0000000
--- a/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
+++ /dev/null
@@ -1,216 +0,0 @@
-#--
-# 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::Proton::Handler
-
-  # A general purpose handler that simplifies processing events.
-  #
-  class MessagingHandler < Qpid::Proton::BaseHandler
-
-    attr_reader :handlers
-
-    # Creates a new instance.
-    #
-    # @param [Integer] prefetch
-    # @param [Boolean] auto_accept
-    # @param [Boolean] auto_settle
-    # @param [Boolean] peer_close_is_error
-    #
-    def initialize(prefetch = 10, auto_accept = true, auto_settle = true, peer_close_is_error = false)
-      @handlers = Array.new
-      @handlers << CFlowController.new(prefetch) unless prefetch.zero?
-      @handlers << EndpointStateHandler.new(peer_close_is_error, self)
-      @handlers << IncomingMessageHandler.new(auto_accept, self)
-      @handlers << OutgoingMessageHandler.new(auto_settle,self)
-    end
-
-    # Called when the peer closes the connection with an error condition.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_error(event)
-      EndpointStateHandler.print_error(event.connection, "connection")
-    end
-
-      # Called when the peer closes the session with an error condition.
-      #
-      # @param event [Qpid:Proton::Event::Event] The event.
-      #
-    def on_session_error(event)
-      EndpointStateHandler.print_error(event.session, "session")
-      event.connection.close
-    end
-
-    # Called when the peer closes the link with an error condition.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_error(event)
-      EndpointStateHandler.print_error(event.link, "link")
-      event.connection.close
-    end
-
-    # Called when the event loop starts.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_reactor_init(event)
-      self.on_start(event)
-    end
-
-    # Called when the event loop starts.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_start(event)
-    end
-
-    # Called when the connection is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_closed(event)
-    end
-
-    # Called when the session is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_session_closed(event)
-    end
-
-    # Called when the link is closed.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_closed(event)
-    end
-
-    # Called when the peer initiates the closing of the connection.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_connection_closing(event)
-    end
-
-    # Called when the peer initiates the closing of the session.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_session_closing(event)
-    end
-
-    # Called when the peer initiates the closing of the link.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_link_closing(event)
-    end
-
-    # Called when the socket is disconnected.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_disconnected(event)
-    end
-
-    # Called when the sender link has credit and messages can therefore
-    # be transferred.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_sendable(event)
-    end
-
-    # Called when the remote peer accepts an outgoing message.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_accepted(event)
-    end
-
-    # Called when the remote peer rejects an outgoing message.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_rejected(event)
-    end
-
-    # Called when the remote peer releases an outgoing message.
-    #
-    # Note that this may be in response to either the RELEASE or
-    # MODIFIED state as defined by the AMPQ specification.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_released(event)
-    end
-
-    # Called when the remote peer has settled hte outgoing message.
-    #
-    # This is the point at which it should never be retransmitted.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_settled(event)
-    end
-
-    # Called when a message is received.
-    #
-    # The message itself can be obtained as a property on the event. For
-    # the purpose of referring to this message in further actions, such as
-    # explicitly accepting it) the delivery should be used. This is also
-    # obtainable vi a property on the event.
-    #
-    # This method needs to be overridden.
-    #
-    # @param event [Qpid::Proton::Event::Event] The event.
-    #
-    def on_message(event)
-    end
-
-  end
-
-end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
index 3f1f3f3..ee875b6 100644
--- a/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/outgoing_message_handler.rb
@@ -22,7 +22,7 @@ module Qpid::Proton::Handler
   # A utility for simpler and more intuitive handling of delivery events
   # related to outgoing messages.
   #
-  class OutgoingMessageHandler < Qpid::Proton::BaseHandler
+  class OutgoingMessageHandler
 
     def initialize(auto_settle = true, delegate = nil)
       @auto_settle = auto_settle

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1f06e4bf/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 62e308b..a733393 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -81,7 +81,6 @@ require "core/ssl_domain"
 require "core/ssl_details"
 require "core/ssl"
 require "core/transport"
-require "core/base_handler"
 require "core/url"
 require "core/connection_driver"
 
@@ -99,18 +98,21 @@ require "handler/endpoint_state_handler"
 require "handler/incoming_message_handler"
 require "handler/outgoing_message_handler"
 require "handler/c_flow_controller"
-require "handler/messaging_handler"
 
-# Core classes that depend on handlers and events
+# Core classes that depend on Handler
+require "core/messaging_handler"
 require "core/container"
 require "core/connection_driver"
 
-# Reactor classes for backwards compatibility
+# Backwards compatibility shims
 require "reactor/container"
 
-module Qpid::Proton
+module Qpid::Proton::Handler
+  # @deprecated alias for backwards compatibility
+  MessagingHandler = Qpid::Proton::MessagingHandler
+end
 
-  include Qpid::Proton::Handler
+module Qpid::Proton
   Tracker = Delivery
 
   # @private


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