summaryrefslogtreecommitdiff
path: root/cpp/bindings/qpid/ruby/lib/qpid_messaging
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/bindings/qpid/ruby/lib/qpid_messaging')
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb200
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/connection.rb189
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb128
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb75
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb353
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb177
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb135
-rw-r--r--cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb264
8 files changed, 1521 insertions, 0 deletions
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb
new file mode 100644
index 0000000000..0879f0fcd1
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb
@@ -0,0 +1,200 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # Address represents an address to which messages can be sent or from
+ # which they can be received.
+ #
+ # == The +Address+ String
+ #
+ # An +Address+ can be described using the following pattern:
+ #
+ # <address> [ / <subject> ] ; [ { <key> : <value> , ... } ]
+ #
+ # where *address* is a simple name and *subject* is a subject or subject
+ # pattern.
+ #
+ # === Options
+ #
+ # The options, enclosed in curly braces, are key:value pairs delimited by
+ # a comma. The values can be nested maps also enclosed in curly braces.
+ # Or they can be lists of values, where they are contained within square
+ # brackets but still comma delimited, such as:
+ #
+ # [value1,value2,value3]
+ #
+ # The following are the list of supported options:
+ #
+ # [create]
+ # Indicates if the address should be created; values are *always*,
+ # *never*, *sender* or *reciever*.
+ #
+ # [assert]
+ # Indicates whether or not to assert any specified node properties;
+ # values are *always*, *never*, *sender* or *receiver*.
+ #
+ # [delete]
+ # Indicates whether or not to delete the addressed node when a sender
+ # or receiver is cancelled; values are *always*, *never*, *sender* or
+ # *receiver*.
+ #
+ # [node]
+ # A nested map describing properties for the addressed node. Properties
+ # are *type* (*topic* or *queue*), *durable* (a boolean), *x-declare*
+ # (a nested map of amqp 0.10-specific options) and *x-bindings* (nested
+ # list which specifies a queue, exchange or a binding key and arguments).
+ #
+ # [link]
+ # A nested map through which properties of the link can be specified;
+ # properties are *durable*, *reliability*, *x-declare*, *x-subscribe*
+ # and *x-bindings*.
+ #
+ # [mode]
+ # (*For receivers only*) indicates whether the receiver should consume
+ # or browse messages; values are *consume* (the default) and *browse*.
+ class Address
+
+ # Creates a new +Address+ from an address string.
+ #
+ # ==== Attributes
+ #
+ # * +address+ - the address string
+ #
+ # ==== Examples
+ #
+ # # create a new address for a queue named "my-queue" that will
+ # # be created if it doesn't already exist
+ # addr = Qpid::Messaging::Address.new "my-queue;{create:always}"
+ #
+ def initialize(address, address_impl = nil)
+ @address_impl = address_impl || Cqpid::Address.new(address)
+ end
+
+ def address_impl # :nodoc:
+ @address_impl
+ end
+
+ # Returns the name for the +Address+.
+ #
+ # ==== Examples
+ #
+ # # display the name of the address
+ # addr = Qpid::Messaging::Address.new "foo;{create:always}"
+ # # outputs the word 'foo'
+ # puts addr.name
+ #
+ def name; @address_impl.getName; end
+
+ # Sets the name for the +Address+.
+ #
+ # ==== Examples
+ #
+ # # create a new address with the name "my-queue"
+ # addr = Qpid::Messaging::Address.new "my-queue/my-subject;{create:always}"
+ # # changes the name to "my-new-queue"
+ # addr.name = "my-new-queue"
+ #
+ def name=(name); @address_impl.setName name; end
+
+ # Returns the subject for the +Address+.
+ #
+ # ==== Examples
+ #
+ # # creates a new address with the subject "bar"
+ # addr = Qpid::Messaging::Address.new "my-queue/bar;{create:always}"
+ #
+ def subject; @address_impl.getSubject; end
+
+ # Sets the subject for the +Address+.
+ #
+ # ==== Examples
+ #
+ # # creates an address with the subject "example"
+ # addr = Qpid::Messaging::Address.new "my-queue/example;{create:always}"
+ # # changes the subject to "test"
+ # addr.subject = "test"
+ #
+ def subject=(subject); @address_impl.setSubject(subject); end
+
+ # Returns the type for the +Address+.
+ #--
+ # We cannot use "type" since that clashes with the Ruby object.type
+ # identifier.
+ #++
+ def address_type; @address_impl.getType; end
+
+ # Sets the type for the +Address+.
+ #
+ # The type of the address determines how +Sender+ and +Receiver+ objects
+ # are constructed for it. It also affects how a reply-to address is
+ # encoded.
+ #
+ # If no type is specified then it will be determined by querying the
+ # broker. Explicitly setting the type prevents this.
+ #
+ # Values are either *queue* or *topic*.
+ #
+ # ==== Options
+ #
+ # * +type+ - the address type
+ #
+ # ==== Examples
+ #
+ # # creates an queue address
+ # addr = Qpid::Messaging::Address.new "my-queue;{create:always}"
+ # addr.address_type = "queue"
+ #
+ def address_type=(type); @address_impl.setType(type); end
+
+ # Returns the options.
+ def options; @address_impl.getOptions; end
+
+ # Sets the options for the address.
+ #
+ # *NOTE:* See the class documentation for more details on options.
+ #
+ # ==== Examples
+ #
+ # addr.options = :create => :always
+ # addr.options = :create => :always, :delete => :always
+ #
+ def options=(options = {}); @address_impl.setOptions(convert_options(options)); end
+
+ def to_s # :nodoc:
+ @address_impl.str
+ end
+
+ private
+
+ def convert_options(options)
+ result = {}
+ options.each_pair {|key, value| result[key.to_s] = value.to_s}
+
+ return result
+ end
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/connection.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/connection.rb
new file mode 100644
index 0000000000..6d637a1665
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/connection.rb
@@ -0,0 +1,189 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # A +Connection+ represents a network connection to a remote endpoint.
+ class Connection
+
+ attr_reader :options # :nodoc:
+
+ # Creates a connection object. Raises a MessagingError if an invalid
+ # connection option is used.
+ #
+ # == Options
+ #
+ # * +:url+ - the URL for the broker
+ # * +:options+ - connection options
+ #
+ # == Controlling Reconnect Behavior
+ #
+ # The following connection options can be used to configure
+ # the reconnection behavior for this connection.
+ #
+ # * +:username+ - the authentication username
+ # * +:password+ - the authentication password
+ # * +:heartbeat+
+ # * +:tcp_nodelay+
+ # * +:sasl_mechanism+
+ # * +:sasl_service+
+ # * +:sasl_min_ssf+
+ # * +:sasl_max_ssf+
+ # * +:transport+
+ # * +:reconnect+ - indicates whether to attempt reconnections
+ # * +:reconnect_timeout+ - the number of seconds to attempt reconnecting
+ # * +:reconnect_limit+ - the number of retries before reporting failure
+ # * +:reconnect_interval_min+ - initial delay, in seconds, before attempting a reconnection
+ # * +:reconnect_interval_max+ - number of seconds to wait before additional reconnect attempts
+ # * +:reconnect_interval+ - shorthand for setting both min and max values
+ # * +:reconnect_urls+ - a list of alternate URLs to use for reconnection attempts
+ #
+ # == Examples
+ #
+ # # creates a connection to the broker running local *localhost*
+ # conn = Qpid::Messaging::Connnection.new
+ # # creates a connection to *broker1.domain.com* on port *5672*
+ # conn = Qpid::Messaging::Connection.new :url => "amqp:tcp:broker1.domain.com:5672"
+ # # creates a connection to localhost with the specified authentication credentials
+ # conn = Qpid::Messaging::Connection.new :options => {:username => "login", :password => "password"}
+ #
+ def initialize(opts = {})
+ @url = opts[:url] || "localhost"
+ @options = Qpid::Messaging.stringify(opts[:options] || {})
+ @connection_impl = opts[:impl] || Cqpid::Connection.new(@url, @options)
+ end
+
+ def connection_impl # :nodoc:
+ @connection_impl
+ end
+
+ # Establishes the connection.
+ #
+ # == Examples
+ #
+ # # open a connection if it's not already open
+ # conn.open unless conn.open?
+ #
+ def open
+ @connection_impl.open
+ end
+
+ # Reports whether the connection is open.
+ #
+ # == Examples
+ #
+ # # close the connection if it's not already closed
+ # conn.close if conn.open?
+ #
+ def open?; true && !@connection_impl.nil? && @connection_impl.isOpen; end
+
+ # Closes the connection.
+ #
+ # == Examples
+ #
+ # # close a connection
+ # conn.close
+ #
+ def close; @connection_impl.close; end
+
+ # Creates a new session.
+ #
+ # == Arguments
+ #
+ # * +:name+ - specifies the name for this session
+ # * +:transactional+ - if +true+ then a creates a transaction session (def. +false+)
+ #
+ # == Examples
+ #
+ # # create a session named 'session1'
+ # session = conn.create_session :name => "session1"
+ # # create a transactional session
+ # session = conn.create_session :transaction => true
+ #
+ def create_session(args = {})
+ name = args[:name] || ""
+ if open?
+ if args[:transactional]
+ session = @connection_impl.createTransactionalSession name
+ else
+ session = @connection_impl.createSession name
+ end
+ return Session.new(self, session)
+ else
+ raise RuntimeError.new "No connection available."
+ end
+ end
+
+ # Returns a Session with the given name. Raises an exception if no
+ # session with the given name exists.
+ #
+ # == Options
+ #
+ # * +name+ - the existing session's name
+ #
+ # == Examples
+ #
+ # # retrieve a session named 'mysession' from the current connection
+ # name = "my-session"
+ # # if no such session exists then catchh the exception raised
+ # begin
+ # session = conn.session name
+ # rescue MessagingException => error
+ # puts "No such session: #{name}."
+ # end
+ #
+ def session name
+ session_impl = @connection_impl.getSession name
+ Qpid::Messaging::Session.new self, session_impl if session_impl
+ end
+
+ # Returns the username used to authenticate with the connection.
+ #
+ # If the connection did not user authentication credentials, then the
+ # username returned is "anonymous".
+ #
+ # == Examples
+ #
+ # # create a new connection for user "qpiduser"
+ # conn = Qpid::Messaging::Connection.new :username => "qpiduser"
+ # conn.open
+ # # displays the authenticate username
+ # puts "Connected as #{conn.authenticated_username}" # should say 'qpiduser'
+ #
+ def authenticated_username; @connection_impl.getAuthenticatedUsername if open?; end
+
+ private
+
+ def convert_options(options)
+ result = {}
+ unless options.nil? || options.empty?
+ options.each_pair {|key, value| result[key.to_s] = value.to_s}
+ end
+
+ return result
+ end
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb
new file mode 100644
index 0000000000..11c903dade
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb
@@ -0,0 +1,128 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # A Duration represents a period of time in milliseconds
+ #
+ # == Named Durations
+ #
+ # The following named +Durations+ are available as symbols:
+ #
+ # [FOREVER]
+ # The maximum integer value for the platform. Effectively this will wait
+ # forever.
+ #
+ # [IMMEDIATE]
+ # An alias for 0 milliseconds.
+ #
+ # [SECOND]
+ # An alias for 1,000 milliseconds.
+ #
+ # [MINUTE]
+ # And alias for 60,000 millisecons.
+ #
+ class Duration
+
+ # Creates a Duration with the specified length, in milliseconds.
+ #
+ # ==== Options
+ #
+ # * +length+ - The duration in +milliseconds+.
+ #
+ # ==== Examples
+ #
+ # # creates a duration of 15 seconds
+ # # REMEMBER: Duration deals in milliseconds
+ # delay = Qpid::Messaging::Duration.new 15000
+ #
+ def initialize length
+ @duration_impl = Cqpid::Duration.new length
+ end
+
+ def duration_impl # :nodoc:
+ @duration_impl
+ end
+
+ # Returns the period of time in +milliseconds+.
+ #
+ # ==== Examples
+ #
+ # # doubling growth in waiting for messages in a loop
+ # do loop
+ # set the base duration waiting length
+ # timeout = Qpid::Messaging::Duration::SECOND
+ # msg = nil
+ # # loop until we receive a message
+ # while msg.nil?
+ # puts "Waiting #{timeout.milliseconds}ms"
+ # msg = recv.get timeout
+ # # if nothing was received, double the duration
+ # if msg.nil?
+ # # double out timeout
+ # timeout = timeout * 2
+ # else
+ # # do something with the message
+ # puts "Received: #{msg.content}"
+ # end
+ # end
+ # end
+ #
+ def milliseconds
+ @duration_impl.getMilliseconds
+ end
+
+ # Multiplies the duration of the +Duration+ and returns a new instance.
+ #
+ # Raises exceptions on a negative factor. Returns
+ # Qpid::Messaging::Duration::IMMEDIATE when the factor is 0.
+ #
+ # ==== Examples
+ #
+ # # return a duration that is 2 minutes (120,000 ms)
+ # twominutes = Qpid::Messaging::Duration::MINUTE * 2
+ #
+ def *(factor)
+ raise TypeError.new "Factors must be non-zero positive values" if factor < 0
+ return Qpid::Messaging::Duration::IMMEDIATE if factor.zero?
+ Qpid::Messaging::Duration.new((self.milliseconds * factor).floor)
+ end
+
+ def self.add_item(key, value) # :nodoc:
+ @hash ||= {}
+ @hash[key] = Duration.new value
+ end
+
+ def self.const_missing(key) # :nodoc:
+ @hash[key]
+ end
+
+ self.add_item :FOREVER, Cqpid::Duration.FOREVER.getMilliseconds
+ self.add_item :IMMEDIATE, Cqpid::Duration.IMMEDIATE.getMilliseconds
+ self.add_item :SECOND, Cqpid::Duration.SECOND.getMilliseconds
+ self.add_item :MINUTE, Cqpid::Duration.MINUTE.getMilliseconds
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb
new file mode 100644
index 0000000000..ac0fbc32a7
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb
@@ -0,0 +1,75 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # Encodes the supplied content into the given message.
+ def self.encode content, message, encoding = nil # :nodoc:
+ Cqpid::encode content, message.message_impl, encoding
+ end
+
+ # Decodes and returns the message's content.
+ def self.decode(message, content_type = nil) # :nodoc:
+ content_type = message.content_type if content_type.nil?
+
+ case content_type
+ when "amqp/map"
+ return Cqpid.decodeMap message.message_impl
+ when "amqp/list"
+ return Cqpid.decodeList message.message_impl
+ end
+
+ message.content
+ end
+
+ # Takes as input any type and converts anything that's a symbol
+ # into a string.
+ def self.stringify(value) # :nodoc:
+ # set the default value
+ result = value
+
+ case value
+
+ when Symbol
+ result = value.to_s
+
+ when Hash
+ result = {}
+ value.each_pair do |key, value|
+ result[stringify(key)] = stringify(value)
+ end
+
+ when Array
+ result = []
+ value.each do |element|
+ result << stringify(element)
+ end
+
+ end
+
+ return result
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb
new file mode 100644
index 0000000000..e167800455
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb
@@ -0,0 +1,353 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # A +Message+ represents an routable piece of information.
+ class Message
+
+ # Creates a +Message+.
+ #
+ # ==== Options
+ #
+ # * +:content+ - the content
+ #
+ # ==== Examples
+ #
+ # # create a simple message and sends it
+ # message = Qpid::Messaging::Message.new :content => "This is a message."
+ # sender.send message
+ #
+ def initialize(args = {})
+ @message_impl = (args[:impl] if args[:impl]) || nil
+ @message_impl = Cqpid::Message.new if @message_impl.nil?
+ @content = nil
+ args = {} if args.nil?
+ self.content = args[:content] if args[:content]
+ end
+
+ def message_impl # :nodoc:
+ @message_impl
+ end
+
+ # Sets the reply-to address.
+ #
+ # The address can either be an instance of Address or else and
+ # address string.
+ #
+ # ==== Options
+ #
+ # * +address+ - the address
+ #
+ # ==== Examples
+ #
+ # # set replies using an Address
+ # msg.reply_to = Qpid:Messaging::Address.new "my-responses"
+ # # set replies using an address string
+ # msg.reply_to = "my-feed/responses"
+ #
+ def reply_to=(address)
+ address = Qpid::Messaging::Address.new "#{address}" if !address.is_a? Qpid::Messaging::Address
+
+ @message_impl.setReplyTo address.address_impl
+ end
+
+ # Returns the reply to address for the +Message+.
+ def reply_to
+ address_impl = @message_impl.getReplyTo
+ # only return an address if a reply to was specified
+ Qpid::Messaging::Address.new(nil, address_impl) if address_impl
+ end
+
+ # Sets the subject for the +Message+.
+ #
+ # ==== Options
+ #
+ # * +subject+ - the subject
+ def subject=(subject); @message_impl.setSubject subject; end
+
+ # Returns the subject of the +Message+.
+ def subject; @message_impl.getSubject; end
+
+ # Sets the content type for the +Message+.
+ #
+ # This should be set by the sending application and indicates to the
+ # recipients of the message how to interpret or decode the content.
+ #
+ # By default, only dictionaries and maps are automatically given a content
+ # type. If this content type is replaced then retrieving the content will
+ # not behave correctly.
+ #
+ # ==== Options
+ #
+ # * +content_type+ - the content type
+ #
+ # ==== Examples
+ #
+ # # send base64 encoded data in a mesage
+ # msg = Qpid::Messaging::Message.new :content = "UXBpZCBSdWxlcyEK"
+ # msg.content_type = "application/base64"
+ #
+ def content_type=(content_type); @message_impl.setContentType content_type; end
+
+ # Returns the content type for the +Message+.
+ def content_type; @message_impl.getContentType; end
+
+ # Sets the message id.
+ #
+ # *NOTE:* this field must be a UUID type currently. A non-UUID value will
+ # be converted to a zero UUID, though a blank ID will be left untouched.
+ #
+ # ==== Options
+ #
+ # * +id+ - the id
+ #
+ # ==== Examples
+ #
+ # # this example only works in Ruby >= 1.9, for 1.8 use a UUID library
+ # require 'SecureRandom'
+ # msg.message_id = SecureRandom.uuid
+ #
+ def message_id=(message_id); @message_impl.setMessageId message_id.to_s; end
+
+ # Returns the message id.
+ def message_id; @message_impl.getMessageId; end
+
+ # Sets the user id for the +Message+.
+ #
+ # This should in general be the user-id which was used when authenticating
+ # the connection itself, as the messaging infrastructure will verify
+ # this.
+ #
+ # See Qpid::Messaging::Connection.authenticated_username
+ #
+ # *NOTE:* If the id is not a +String+ then the id is set using
+ # the object's string representation.
+ #
+ # ==== Options
+ #
+ # * +id+ - the id
+ #
+ def user_id=(user_id); @message_impl.setUserId user_id; end
+
+ # Returns the user id for the +Message+.
+ def user_id; @message_impl.getUserId; end
+
+ # Sets the correlation id of the +Message+.
+ #
+ # The correlation id can be used as part of a protocol for message
+ # exchange patterns; e.g., a request-response pattern might require
+ # the correlation id of the request and the response to match, or it
+ # might use the message id of the request as the correlation id on
+ # the response.
+ #
+ # *NOTE:* If the id is not a +String+ then the id is setup using
+ # the object's string representation.
+ #
+ # ==== Options
+ #
+ # * +id+ - the id
+ #
+ def correlation_id=(correlation_id); @message_impl.setCorrelationId correlation_id; end
+
+ # Returns the correlation id of the +Message+.
+ def correlation_id; @message_impl.getCorrelationId; end
+
+ # Sets the priority of the +Message+.
+ #
+ # This may be used by the messaging infrastructure to prioritize
+ # delivery of messages with higher priority.
+ #
+ # *NOTE:* If the priority is not an integer type then it is set using
+ # the object's integer representation. If the integer value is greater
+ # than 8-bits then only the first 8-bits are used.
+ #
+ # ==== Options
+ #
+ # * +priority+ - the priority
+ #
+ def priority=(priority); @message_impl.setPriority priority; end
+
+ # Returns the priority for the +Message+.
+ def priority; @message_impl.getPriority; end
+
+ # Sets the time-to-live in milliseconds.
+ #
+ # This can be used by the messaging infrastructure to discard messages
+ # that are no longer of relevance.
+ #
+ # ==== Options
+ #
+ # * +duration+ - the number of milliseconds
+ #
+ def ttl=(duration)
+ if duration.is_a? Qpid::Messaging::Duration
+ @message_impl.setTtl duration.duration_impl
+ else
+ @message_impl.setTtl Cqpid::Duration.new duration.to_i
+ end
+ end
+
+ # Returns the time-to-live in milliseconds.
+ def ttl; Qpid::Messaging::Duration.new @message_impl.getTtl.getMilliseconds; end
+
+ # Sets the durability of the +Message+.
+ #
+ # This is a hint to the messaging infrastructure that the message
+ # should be persisted or otherwise stored. This helps to ensure
+ # that the message is not lost due to failures or a shutdown.
+ #
+ # ==== Options
+ #
+ # * +durable+ - the durability flag (def. false)
+ #
+ def durable=(durable); @message_impl.setDurable durable; end
+
+ # Returns the durability for the +Message+.
+ def durable; @message_impl.getDurable; end
+
+ # This is a hint to the messaging infrastructure that if de-duplication
+ # is required, that this message should be examined to determine if it
+ # is a duplicate.
+ #
+ # ==== Options
+ #
+ # * +redelivered+ - sets the redelivered state (def. false)
+ #
+ # ==== Examples
+ #
+ # # processed is a collection of messages already received
+ # msg.redelivered = true if processed.include? msg.message_id
+ #
+ def redelivered=(redelivered); @message_impl.setRedelivered redelivered; end
+
+ # Returns whether the +Message+ has been marked as redelivered.
+ def redelivered; @message_impl.getRedelivered; end
+
+ # Returns all named properties.
+ #
+ # *NOTE:* It is recommended to use the []= method for
+ # retrieving and setting properties. Using this method may
+ # result in non-deterministic behavior.
+ def properties; @message_impl.getProperties; end
+
+ # Returns the value for the named property.
+ #
+ # ==== Options
+ #
+ # * +name+ - the property name
+ #
+ # ==== Examples
+ #
+ # # use of message properties to mark a message as digitally signed
+ # verify(msg) if msg[:signed]
+ #
+ def [](key); self.properties[key.to_s]; end
+
+ # Assigns a value to the named property.
+ #
+ # A property's name or value, if a symbol, will be converted to a string
+ # representation. However, you will still be able to access them using
+ # a symbol for the name.
+ #
+ # ==== Options
+ #
+ # * +name+ - the property name
+ # * +value+ - the property value
+ #
+ # ==== Examples
+ #
+ # # set the signed attribute on a message and then retrieve it
+ # msg[:signed] = true # sets "signed" => true
+ # puts "It's signed" if msg["signed"] # outputs "It's signed"
+ #
+ def []=(key, value)
+ @message_impl.setProperty(key.to_s,
+ Qpid::Messaging.stringify(value))
+ end
+
+ # Sets the content for the +Message+.
+ #
+ # Content is automatically encoded for Array and Hash types. Other types
+ # need to set their own content types (via content_type) in order to
+ # specify how recipients should process the content.
+ #
+ # ==== Options
+ #
+ # * +content+ - the content
+ #
+ # ==== Examples
+ #
+ # # set a simple content for a message
+ # msg.content = "This is a simple message."
+ # # sets content that is automatically encoded
+ # msg.content = {:foo => :bar}
+ #
+ def content=(content)
+ content_type = nil
+ @content = Qpid::Messaging.stringify(content)
+ case @content
+ when Hash
+ content_type = "amqp/map"
+ when Array
+ content_type = "amqp/list"
+ end
+ if content_type.nil?
+ @message_impl.setContent @content
+ else
+ Qpid::Messaging.encode @content, self, content_type
+ end
+ end
+
+ # Returns the content of the +Message+.
+ #
+ # Content is automatically decoded based on the specified content type.
+ # If the content type is application-specific, then no decoding is
+ # performed and the content is returnedas a +String+ representation.
+ #
+ # For example, if an array of integers are sent, then the receiver will
+ # find the message content to be an array of String objects, where each
+ # String is a representation of the sent integer value.
+ #
+ def content
+ if @content.nil?
+ @content = @message_impl.getContent
+
+ # decode the content is necessary if it
+ # has an encoded content type
+ if ["amqp/list", "amqp/map"].include? @message_impl.getContentType
+ @content = Qpid::Messaging.decode(self,
+ @message_impl.getContentType)
+ end
+
+ end
+ @content
+ end
+
+ # Returns the content's size in bytes.
+ def content_size; @message_impl.getContentSize; end
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb
new file mode 100644
index 0000000000..05ee925212
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb
@@ -0,0 +1,177 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # +Receiver+ is the entity through which messages are received.
+ #
+ # An instance of +Receiver+ can only be created using an active (i.e., not
+ # previously closed) Session. See Qpid::Messaging::Session.create_receiver
+ # for more details.
+ #
+ # ==== Example
+ #
+ # # create a connection and a session
+ # conn = Qpid::Messaging::Connection.new :url => "mybroker:5762"
+ # conn.open
+ # session = conn.create_session
+ #
+ # # create a receiver that listens on the "updates" topic of "alerts"
+ # receiver = session.create_receiver "alerts/updates"
+ #
+ # # wait for an incoming message and process it
+ # incoming = receiver.get Qpid::Messaging::Duration::FOREVER
+ # process(incoming)
+ #
+ class Receiver
+
+ def initialize(session, receiver_impl) # :nodoc:
+ @session = session
+ @receiver_impl = receiver_impl
+ end
+
+ def receiver_impl # :nodoc:
+ @receiver_impl
+ end
+
+ # Retrieves a message from the local queue, or waits for up to
+ # the duration specified for one to become available.
+ #
+ # If no message is received within the specified time then a
+ # MessagingException is raised.
+ #
+ # ==== Options
+ #
+ # * duration - the timeout to wait
+ #
+ # ==== Examples
+ #
+ # # retrieves a message, also handles exceptions raised on no messages
+ # begin
+ # # checks for a message, returning immediately
+ # msg = recv.get Qpid::Messaging::Duration::IMMEDIATE
+ # puts "Received this message: #{message.content}"
+ # rescue
+ # puts "No messages available.
+ # end
+ #
+ def get(duration = Qpid::Messaging::Duration::FOREVER)
+ message_impl = @receiver_impl.get duration.duration_impl
+ create_message_wrapper message_impl unless message_impl.nil?
+ end
+
+ # Retrieves a message from the receiver's subscription, or waits
+ # for up to the duration specified for one to become available.
+ #
+ # If no message is fetched within the specified time then a
+ # MessagingException is raised.
+ #
+ # ==== Options
+ #
+ # * duration - the timeout to wait (def. Duration::FOREVER)
+ #
+ # ==== Examples
+ #
+ # # retrieves a message, also handles exceptions raised on no messages
+ # begin
+ # # checks for a message, times out after one second
+ # msg = recv.fetch Qpid::Messaging::Duration::SECOND
+ # puts "Fetched this message: #{message.content}"
+ # rescue
+ # puts "No messages available.
+ # end
+ #
+ def fetch(duration = Qpid::Messaging::Duration::FOREVER)
+ message_impl = @receiver_impl.fetch duration.duration_impl
+ create_message_wrapper message_impl unless message_impl.nil?
+ end
+
+ # Sets the capacity.
+ #
+ # The capacity of a +Receiver+ is the number of Messages that can be
+ # pre-fetched from the broker and held locally. If capacity is 0 then
+ # messages will never be pre-fetched and all messages must instead be
+ # retrieved using #fetch.
+ #
+ # ==== Options
+ #
+ # * capacity - the capacity
+ #
+ # ==== Examples
+ #
+ # # create a receiver and give it a capacity of 50
+ # recv = session.create_receiver "alerts/minor"
+ # recv.capacity = 50
+ #
+ def capacity=(capacity); @receiver_impl.setCapacity capacity; end
+
+ # Returns the capacity.
+ def capacity; @receiver_impl.getCapacity; end
+
+ # Returns the number of messages locally held.
+ #
+ # The available is always 0 <= available <= capacity.
+ #
+ # If the #capacity is set to 0 then available will always be 0.
+ #
+ # ==== Examples
+ #
+ # # output the number of messages waiting while processing
+ # loop do
+ # puts "There are #{recv.available} messages pending..."
+ # # wait forever (the default) for the next message
+ # msg = recv.get
+ # # process the message
+ # dispatch_message msg
+ # end
+ #
+ def available; @receiver_impl.getAvailable; end
+
+ # Returns the number of messages that have been received and acknowledged
+ # but whose acknowledgements have not been confirmed by the sender.
+ def unsettled; @receiver_impl.getUnsettled; end
+
+ # Closes this +Receiver+.
+ #
+ # This does not affect the owning Session or Connection.
+ def close; @receiver_impl.close; end
+
+ # Returns whether the +Receiver+ is closed.
+ def closed?; @receiver_impl.isClosed; end
+
+ # Returns the name of this +Receiver+.
+ def name; @receiver_impl.getName; end
+
+ # Returns the owning Session for this +Receiver+.
+ def session; @session; end
+
+ private
+
+ def create_message_wrapper message_impl # :nodoc:
+ Qpid::Messaging::Message.new(:impl => message_impl)
+ end
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb
new file mode 100644
index 0000000000..4ce1393dc7
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb
@@ -0,0 +1,135 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # +Sender+ is the entity through which messages are sent.
+ #
+ # An instance of +Sender+ can only be created using an active (not previously
+ # closed) Session. See Qpid::Messaging::Session.create_sender for more details.
+ #
+ # ==== Examples
+ #
+ # # create a connection
+ # conn = Qpid::Messaging::Connection.new "mybroker:5672"
+ # conn.open
+ #
+ # if conn.open?
+ #
+ # # create a session
+ # session = conn.create_session
+ #
+ # # create a sender that posts messages to the "updates" queue
+ # sender = session.create_sender "updates;{create:always}
+ #
+ # # begin sending updates
+ # loop do
+ # # wait for the next event content then send it
+ # content = wait_for_event
+ # sender.send Qpid::Messaging::Message.new :content => content
+ # end
+ # end
+ #
+ class Sender
+
+ def initialize(session, sender_impl) # :nodoc:
+ @session = session
+ @sender_impl = sender_impl
+ end
+
+ def sender_impl # :nodoc:
+ @sender_impl
+ end
+
+ # Sends a message, optionally blocking until the message is received
+ # by the broker.
+ #
+ # ==== Options
+ #
+ # * +message+ - The message to send.
+ # * +:sync+ - Block until received. See note below on synching.
+ #
+ # ==== Synching
+ #
+ # If :sync => true, then the call will block until the broker confirms
+ # receipt of the message. Otherwise it will only block for available
+ # capacity; i.e., until pending is equal to capacity.
+ #
+ # ==== Examples
+ #
+ # # send a message
+ # outgoing = Qpid::Messaging::Message.new :content => content
+ # sender.send outgoing
+ #
+ # # send a message, wait for confirmation from the broker
+ # outgoing = Qpid::Messaging::Message.new :content => content
+ # sender.send outgoing, :sync => true
+ #
+ def send(message, args = {}, &block)
+ sync = args[:sync] || false
+ @sender_impl.send message.message_impl, sync
+ block.call message unless block.nil?
+ end
+
+ # Closes this +Sender+.
+ #
+ # This does not affect the owning Session or Connection.
+ def close; @sender_impl.close; end
+
+ # Returns the human-readable name for this +Sender+.
+ def name; @sender_impl.getName; end
+
+ # Sets the capacity for this +Sender+.
+ #
+ # The capacity is the number of outgoing messages that can be held
+ # pending confirmation of receipt by the broker.
+ #
+ # ==== Options
+ #
+ # * +capacity+ - the capacity
+ def capacity=(capacity); @sender_impl.setCapacity capacity; end
+
+ # Returns the capacity.
+ def capacity; @sender_impl.getCapacity; end
+
+ # Returns the number of messages sent that are pending receipt
+ # confirmation by the broker.
+ def unsettled; @sender_impl.getUnsettled; end
+
+ # Returns the available slots for sending messages.
+ #
+ # This differs from +capacity+ in that it is the available slots in
+ # the senders capacity for holding outgoing messages. The difference
+ # between capacity and available is the number of messages that
+ # have not been delivered yet.
+ def available
+ @sender_impl.getAvailable
+ end
+
+ # Returns the Session for this sender.
+ def session; @session; end
+
+ end
+
+ end
+
+end
+
diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb
new file mode 100644
index 0000000000..7e6e11f654
--- /dev/null
+++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb
@@ -0,0 +1,264 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid
+
+ module Messaging
+
+ # A +Session+ represents a distinct conversation between end points. They are
+ # created from an active (i.e., not closed) Connection.
+ #
+ # A +Session+ is used to acknowledge individual or all messages that have
+ # passed through it
+ class Session
+
+ def initialize(connection, session) # :nodoc:
+ @connection = connection
+ @session_impl = session
+ end
+
+ def session_impl # :nodoc:
+ @session_impl
+ end
+
+ # Returns the Connection associated with this session.
+ def connection
+ @connection
+ end
+
+ # Creates a new endpoint for sending messages.
+ #
+ # The address can either be an instance Address or else an
+ # address string.
+ #
+ # ==== Arguments
+ #
+ # * +address+ - the end point address.
+ def create_sender(address)
+ _address = address
+
+ if address.class == Qpid::Messaging::Address
+ _address = address.address_impl
+ end
+
+ sender_impl = @session_impl.createSender(_address)
+ sender_name = sender_impl.getName
+
+ Qpid::Messaging::Sender.new(self, sender_impl)
+ end
+
+ # Retrieves the Sender with the specified name.
+ #
+ # Raises an exception if no such Sender exists.
+ #
+ # ==== Arguments
+ #
+ # * +name+ - the name of the Sender
+ def sender(name)
+ Qpid::Messaging::Sender.new self, @session_impl.getSender(name)
+ end
+
+ # Creates a new endpoint for receiving messages.
+ #
+ # The +address+ can either be an instance Address or else an
+ # address string.
+ #
+ # ==== Arguments
+ #
+ # * +address+ - the end point address.
+ def create_receiver(address)
+ result = nil
+ receiver_impl = nil
+
+ if address.class == Qpid::Messaging::Address
+ address_impl = address.address_impl
+ receiver_impl = @session_impl.createReceiver address_impl
+ else
+ receiver_impl = @session_impl.createReceiver(address)
+ end
+
+ Qpid::Messaging::Receiver.new self, receiver_impl
+ end
+
+ # Retrieves the +Receiver+ with the specified name, or nil if no such
+ # Receiver exists.
+ #
+ # ==== Arguments
+ #
+ # * +name+ - the name of the Receiver
+ def receiver(name)
+ Qpid::Messaging::Receiver.new self, @session_impl.getReceiver(name)
+ end
+
+ # Closes the +Session+ and all associated +Sender+ and +Receiver+ instances.
+ #
+ # *NOTE:* All +Session+ instances for a Connection are closed when the
+ # Connection is closed. But closing a +Session+ does not affect the
+ # owning Connection.
+ def close; @session_impl.close; end
+
+ # Commits any pending transactions for a transactional session.
+ def commit; @session_impl.commit; end
+
+ # Rolls back any uncommitted transactions on a transactional session.
+ def rollback; @session_impl.rollback; end
+
+ # Acknowledges one or more outstanding messages that have been received
+ # on this session.
+ #
+ # ==== Arguments
+ #
+ # * +options+ - the set of options
+ #
+ # ==== Options
+ #
+ # * :message - if specified, then only that Message is acknowledged
+ # * :sync - if true, the call will block until processed by the broker
+ #
+ # ==== Examples
+ #
+ # # acknowledge all received messages
+ # session.acknowledge
+ #
+ # # acknowledge a single message
+ # session.acknowledge :message => message
+ #
+ # # acknowledge all messages, wait until the call finishes
+ # session.acknowledge :sync => true
+ #
+ #--
+ # TODO: Add an optional block to be used for blocking calls.
+ #++
+ def acknowledge(options = {})
+ sync = options[:sync] || false
+ message = options[:message] if options[:message]
+
+ unless message.nil?
+ @session_impl.acknowledge message.message_impl, sync
+ else
+ @session_impl.acknowledge sync
+ end
+ end
+
+ # Rejects the specified message. A rejected message will not be
+ # redelivered.
+ #
+ # NOTE: A message cannot be rejected once it has been acknowledged.
+ def reject(message); @session_impl.reject message.message_impl; end
+
+ # Releases the message, which allows the broker to attempt to
+ # redeliver it.
+ #
+ # NOTE: A message connot be released once it has been acknowled.
+ def release(message); @session_impl.release message.message_impl; end
+
+ # Requests synchronization with the broker.
+ #
+ # ==== Arguments
+ #
+ # * +options+ - the list of options
+ #
+ # ==== Options
+ #
+ # * +:block+ - if true, the call blocks until the broker acknowledges it
+ #
+ #--
+ # TODO: Add an optional block to be used for blocking calls.
+ #++
+ def sync(args = {})
+ block = args[:block] || false
+ @session_impl.sync block
+ end
+
+ # Returns the total number of receivable messages, and messages already
+ # received, by Receiver instances associated with this +Session+.
+ def receivable; @session_impl.getReceivable; end
+
+ # Returns the number of messages that have been acknowledged by this
+ # +Session+ whose acknowledgements have not been confirmed as processed
+ # by the broker.
+ def unsettled_acks; @session_impl.getUnsettledAcks; end
+
+ # Fetches the next Receiver with a message pending. Waits the specified
+ # number of milliseconds before timing out.
+ #
+ # For a Receiver to be returned, it must have a capacity > 0 and have
+ # Messages locally queued.
+ #
+ # If no Receiver is found within the time out period, then a MessageError
+ # is raised.
+ #
+ # ==== Arguments
+ #
+ # * +timeout+ - the duration
+ #
+ # ==== Examples
+ #
+ # loop do
+ #
+ # begin
+ # # wait a maximum of one minute for the next receiver to be ready
+ # recv = session.next_receiver Qpid::Messaging::Duration::MINUTE
+ #
+ # # get and dispatch the message
+ # msg = recv.get
+ # dispatch_message msg
+ #
+ # rescue
+ # puts "No receivers were returned"
+ # end
+ #
+ # end
+ def next_receiver(timeout = Qpid::Messaging::Duration::FOREVER, &block)
+ receiver_impl = @session_impl.nextReceiver(timeout.duration_impl)
+
+ unless receiver_impl.nil?
+ recv = Qpid::Messaging::Receiver.new self, receiver_impl
+ block.call recv unless block.nil?
+ end
+
+ return recv
+ end
+
+ # Returns true if there were exceptions on this session.
+ def errors?; @session_impl.hasError; end
+
+ # If the +Session+ has been rendered invalid due to some exception,
+ # this method will result in that exception being raised.
+ #
+ # If none have occurred, then no exceptions are raised.
+ #
+ # ==== Examples
+ #
+ # # show any errors that occurred during the Session
+ # if @session.errors?
+ # begin
+ # @session.errors
+ # rescue Exception => error
+ # puts "An error occurred: #{error}"
+ # end
+ # end
+ def errors; @session_impl.checkError; end
+
+ end
+
+ end
+
+end
+