You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by mc...@apache.org on 2015/05/18 17:34:56 UTC
[36/42] qpid-proton git commit: PROTON-799: Added the Event classes
to the Ruby engine APIs.
PROTON-799: Added the Event classes to the Ruby engine APIs.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d8a1dc51
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d8a1dc51
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d8a1dc51
Branch: refs/heads/ruby-engine-apis
Commit: d8a1dc517a7f67d5445496541f6e18fed7e4c95f
Parents: e0a204a
Author: Darryl L. Pierce <mc...@gmail.com>
Authored: Tue Feb 3 17:17:18 2015 -0500
Committer: Darryl L. Pierce <mc...@gmail.com>
Committed: Mon May 18 11:33:31 2015 -0400
----------------------------------------------------------------------
proton-c/bindings/ruby/lib/event/event.rb | 281 ++++++++++++++++++++
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/qpid_proton.rb | 3 +
4 files changed, 446 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d8a1dc51/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
new file mode 100644
index 0000000..de8f415
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event.rb
@@ -0,0 +1,281 @@
+#--
+# 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 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.each do |hndlr|
+ self.dispatch(hndlr)
+ end
+ end
+ end
+ end
+
+ # 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
+
+ # @private
+ def to_s
+ "#{self.type}(#{self.context})"
+ end
+
+ end
+
+ end
+
+end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d8a1dc51/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
new file mode 100644
index 0000000..6ae6959
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event_base.rb
@@ -0,0 +1,91 @@
+#--
+# 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/d8a1dc51/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
new file mode 100644
index 0000000..aa5944d
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/event/event_type.rb
@@ -0,0 +1,71 @@
+#--
+# 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/d8a1dc51/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 9060b54..58b95d0 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -51,6 +51,9 @@ 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
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org