diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /cpp/bindings/qpid/ruby | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-asyncstore.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/bindings/qpid/ruby')
43 files changed, 788 insertions, 834 deletions
diff --git a/cpp/bindings/qpid/ruby/CMakeLists.txt b/cpp/bindings/qpid/ruby/CMakeLists.txt index 9b32ff5728..564f5655c8 100644 --- a/cpp/bindings/qpid/ruby/CMakeLists.txt +++ b/cpp/bindings/qpid/ruby/CMakeLists.txt @@ -31,7 +31,9 @@ set(GEM_OUTPUT_FILE ${GEM_OUTPUT_PATH}/pkg/qpid-${qpidc_version}.0.gem) ##------------------------------------------------------ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ruby.i PROPERTIES CPLUSPLUS ON) -include_directories(${RUBY_INCLUDE_DIRS} ${qpid-cpp_SOURCE_DIR}/include) +include_directories(${RUBY_INCLUDE_DIRS} + ${qpid-cpp_SOURCE_DIR}/include + ${qpid-cpp_SOURCE_DIR}/bindings) swig_add_module(cqpid_ruby ruby ${CMAKE_CURRENT_SOURCE_DIR}/ruby.i) swig_link_libraries(cqpid_ruby qpidmessaging qpidtypes qmf2 ${RUBY_LIBRARY}) @@ -43,7 +45,7 @@ set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_F ##---------------------------------- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcqpid_ruby.so RENAME cqpid.so - DESTINATION ${RUBY_ARCH_DIR} + DESTINATION ${RUBY_PFX_ARCH_DIR} COMPONENT ${QPID_COMPONENT_CLIENT} ) diff --git a/cpp/bindings/qpid/ruby/ChangeLog b/cpp/bindings/qpid/ruby/ChangeLog new file mode 100644 index 0000000000..03813053d2 --- /dev/null +++ b/cpp/bindings/qpid/ruby/ChangeLog @@ -0,0 +1,4 @@ +Verison 0.22: + * Qpid::Messaging::Address can use an address string on creation. + * Qpid::Messaging::Message can use an address string for reply_to. + * Removed errors.rb and the KeyError and SessionNameException errors. diff --git a/cpp/bindings/qpid/ruby/LICENSE b/cpp/bindings/qpid/ruby/LICENSE index 232fd660d6..261eeb9e9f 100644 --- a/cpp/bindings/qpid/ruby/LICENSE +++ b/cpp/bindings/qpid/ruby/LICENSE @@ -1,7 +1,3 @@ -========================================================================= -== Apache License == -========================================================================= - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/cpp/bindings/qpid/ruby/Makefile.am b/cpp/bindings/qpid/ruby/Makefile.am index a2a5dd76bd..398449c7ed 100644 --- a/cpp/bindings/qpid/ruby/Makefile.am +++ b/cpp/bindings/qpid/ruby/Makefile.am @@ -19,7 +19,7 @@ if HAVE_RUBY_DEVEL -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src EXTRA_DIST = CMakeLists.txt ruby.i BUILT_SOURCES = cqpid.cpp @@ -27,7 +27,7 @@ SWIG_FLAGS = -w362,401 rubylibdir = $(RUBY_LIB) -cqpid.cpp: $(srcdir)/ruby.i $(srcdir)/../qpid.i $(srcdir)/../../swig_ruby_typemaps.i +cqpid.cpp: $(srcdir)/ruby.i $(SWIG) -ruby -c++ $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqpid.cpp $(srcdir)/ruby.i rubylibarchdir = $(RUBY_LIB_ARCH) diff --git a/cpp/bindings/qpid/ruby/README.rdoc b/cpp/bindings/qpid/ruby/README.rdoc index 5c60a15588..fce87ac3e1 100644 --- a/cpp/bindings/qpid/ruby/README.rdoc +++ b/cpp/bindings/qpid/ruby/README.rdoc @@ -1,45 +1,41 @@ -= Qpid - Open Source AMQP Messaging += Qpid - Ruby language bindings for the Qpid messaging framework. -Qpid is an cross-platform enterprise messaging system. - -Version :: 0.19.0 +Qpid is a cross-platform enterprise messaging system based on the open-source +AMQP protocol. = Links Documents :: http://qpid.apache.org/ -= Installation += Building The Gemfile + +== Prerequisites -You can install Qpid with the following command. +You need to have the Qpid client libraries installed along with the related +development files (headers, etc). To install them, please see: - $ gem install qpid +http://cwiki.apache.org/qpid/developer-pages.html -== Building The Native Code +== Gemfile Creation -The Qpid gem requires that you have available the Qpid libraries and -development header files. To install them, please see: +Simply type: -http://cwiki.apache.org/qpid/developer-pages.html + $ gem build qpid_messaging.gemspec -If you are building the gem within the Qpid development environment -itself, you can specify the location of the Qpid headers and -libraries with: +This will produce a gemfile name qpid_messaging-${VERSION}.gem. -$ ruby extconfig.rb --with-qpid-lib=[path to libqpidclient.so, etc.] -$ make +== Installation -== Examples +You can install Qpid with the following command: -Take a look at the integration tests for examples on how to leverage -the messaging capabilities of Qpid in your Ruby applications. + $ gem install qpid_messaging-${VERSION}.gem == License Licensed to the Apache Software Foundation (ASF) under one or more contributor licensing agreements. -Author:: Darryl L. Pierce (mailto:dpierce@redhat.com) -Copyright:: Copyright (c) 2011, Red Hat, Inc. +Author:: Apache Qpid Project Homepage:: http://qpid.apache.org License:: Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/cpp/bindings/qpid/ruby/Rakefile b/cpp/bindings/qpid/ruby/Rakefile deleted file mode 100644 index 99c3e13c83..0000000000 --- a/cpp/bindings/qpid/ruby/Rakefile +++ /dev/null @@ -1,137 +0,0 @@ -# Rakefile for Qpid -*- ruby -*- -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -task :noop - -# look for a root directory for out-of-tree builds - -OUTPUT_DIR=ENV["OUTPUT_DIR"] || "." - -require "rubygems" -require "rubygems/package_task" - -require "rake/clean" -require "rake/extensiontask" -require "rake/rdoctask" -require "rake/testtask" - -require "cucumber/rake/task" -require "spec/rake/spectask" - -CLOBBER.include("pkg") - -load "./lib/qpid/version.rb" - -#------------- -# Gem Details. -#------------- - -NAME = "qpid" -# VERSION = Qpid::VERSION -AUTHOR = "Darryl L. Pierce" -EMAIL = "dpierce@redhat.com" -HOMEPAGE = "http://qpid.apache.org" -SUMMARY = "Qpid is an enterprise messaging framework." - -desc "Default: run all tests." -task :default => :test - -desc "Runs all tests." -task :test => :"test:all" - -#--------------- -# Testing tasks. -#--------------- - -namespace :test do - - desc "Run RSpec tests." - Spec::Rake::SpecTask.new do |t| - t.ruby_opts = ['-rtest/unit'] - t.spec_files = FileList["spec/**/*_spec.rb"] - t.rcov = true - t.rcov_opts = [ - '--exclude', 'lib\/qpid.rb,spec\/,lib\/ruby', - ] - end - - desc "Run all tests (default)." - task :all => [:spec, :features] - - Cucumber::Rake::Task.new(:features) do |t| - t.libs = ["lib", "ext/nonblockio"] - t.cucumber_opts = "--format progress" - end - -end - -#--------------------- -# Documentation tasks. -#--------------------- - -Rake::RDocTask.new(:rdoc => "rdoc", - :clobber_rdoc => "rdoc:clean", - :rerdoc => "rdoc:force") do |rd| - rd.main = "README.rdoc" - rd.options << "--all" - rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") -end - -#----------------- -# Package the gem. -#----------------- - -spec = Gem::Specification.new do |s| - s.name = NAME - s.version = Qpid::VERSION - s.platform = Gem::Platform::RUBY - s.extra_rdoc_files = ["README.rdoc"] - s.summary = SUMMARY - s.description = s.summary - s.author = AUTHOR - s.email = EMAIL - s.homepage = HOMEPAGE - - s.extensions = FileList["ext/**/extconf.rb"] - - s.require_path = "lib" - # DEPRECATED s.autorequire = NAME - s.files = FileList["LICENSE", - "README.rdoc", - "Rakefile", - "TODO", - "lib/**/*.rb", - "test/**/*.rb", - "examples/**/*.rb", - "ext/**/*", - "features/**/*", - "spec/**/*"] -end - -Gem::PackageTask.new(spec) do |pkg| - pkg.package_dir = "#{OUTPUT_DIR}/pkg" -end - -#------------------ -# Build native code -#------------------ - -Rake::ExtensionTask.new("cqpid", spec) - diff --git a/cpp/bindings/qpid/ruby/TODO b/cpp/bindings/qpid/ruby/TODO index 454aac9200..db2aca0195 100644 --- a/cpp/bindings/qpid/ruby/TODO +++ b/cpp/bindings/qpid/ruby/TODO @@ -1,7 +1,12 @@ -TODO Items ------------------------------------------------------------------------------ +Qpid Ruby bindigns TODO List +============================================================================== -Version 0.11.0: - * Deliver the Ruby bindings as a gem. - * Rework the blocking tasks to not bring the main thread to a halt. +Beyond this simple laundry list, you can find the list of bugs and +enhancements to be fixed by going to the Apache Qpid JIRA instance: + http://issues.apache.org/jira/browse/QPID + + +Fixes & Improvements +============================================================================== +* Fix the threading issues with blocking I/O calls (Receiver get/fetch). diff --git a/cpp/bindings/qpid/ruby/examples/client.rb b/cpp/bindings/qpid/ruby/examples/client.rb index 86ec1b7254..f400acfd13 100644 --- a/cpp/bindings/qpid/ruby/examples/client.rb +++ b/cpp/bindings/qpid/ruby/examples/client.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' if __FILE__ == $0 broker = ARGV[1] || "amqp:tcp:localhost:5672" @@ -29,9 +29,7 @@ if __FILE__ == $0 connection.open session = connection.create_session sender = session.create_sender "service_queue" - response_queue = Qpid::Messaging::Address.new("#response-queue", "", - :create => :always, - :delete => :always) + response_queue = Qpid::Messaging::Address.new("#response-queue;{create:always}") receiver = session.create_receiver response_queue ["Twas brillig, and the slithy toves", diff --git a/cpp/bindings/qpid/ruby/examples/drain.rb b/cpp/bindings/qpid/ruby/examples/drain.rb index 9e8f699e8b..8e506ea5cd 100644 --- a/cpp/bindings/qpid/ruby/examples/drain.rb +++ b/cpp/bindings/qpid/ruby/examples/drain.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' require 'optparse' options = { diff --git a/cpp/bindings/qpid/ruby/examples/hello_world.rb b/cpp/bindings/qpid/ruby/examples/hello_world.rb index c014fb8bd5..1f4954dde9 100644 --- a/cpp/bindings/qpid/ruby/examples/hello_world.rb +++ b/cpp/bindings/qpid/ruby/examples/hello_world.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' # This is your classic Hello World application, written in # Ruby, that uses Qpid. It demonstrates how to send and diff --git a/cpp/bindings/qpid/ruby/examples/map_receiver.rb b/cpp/bindings/qpid/ruby/examples/map_receiver.rb index e08bd295ba..16704dd48e 100644 --- a/cpp/bindings/qpid/ruby/examples/map_receiver.rb +++ b/cpp/bindings/qpid/ruby/examples/map_receiver.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' broker = ARGV[0] || "amqp:tcp:127.0.0.1:5672" address = ARGV[1] || "message_queue; {create: always}" diff --git a/cpp/bindings/qpid/ruby/examples/map_sender.rb b/cpp/bindings/qpid/ruby/examples/map_sender.rb index 3fb7ca58e3..1908774c31 100644 --- a/cpp/bindings/qpid/ruby/examples/map_sender.rb +++ b/cpp/bindings/qpid/ruby/examples/map_sender.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' broker = ARGV[0] || "amqp:tcp:127.0.0.1:5672" address = ARGV[1] || "message_queue; {create: always}" diff --git a/cpp/bindings/qpid/ruby/examples/server.rb b/cpp/bindings/qpid/ruby/examples/server.rb index 0cc0e30216..a589bea799 100644 --- a/cpp/bindings/qpid/ruby/examples/server.rb +++ b/cpp/bindings/qpid/ruby/examples/server.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' if __FILE__ == $0 broker = ARGV[0] || "amqp:tcp:localhost:5672" diff --git a/cpp/bindings/qpid/ruby/examples/spout.rb b/cpp/bindings/qpid/ruby/examples/spout.rb index ecc47fb15a..71c04d8709 100644 --- a/cpp/bindings/qpid/ruby/examples/spout.rb +++ b/cpp/bindings/qpid/ruby/examples/spout.rb @@ -19,7 +19,7 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib") -require 'qpid' +require 'qpid_messaging' require 'optparse' options = { diff --git a/cpp/bindings/qpid/ruby/ext/cqpid/extconf.rb b/cpp/bindings/qpid/ruby/ext/cqpid/extconf.rb index 90292d4bec..fc9e65d562 100644 --- a/cpp/bindings/qpid/ruby/ext/cqpid/extconf.rb +++ b/cpp/bindings/qpid/ruby/ext/cqpid/extconf.rb @@ -26,9 +26,10 @@ require 'mkmf' # Setup the build environment. -$CFLAGS = "-fPIC -fno-inline -x c++" +$CFLAGS = "-fPIC -fno-inline -x c++ -lstdc++" REQUIRED_LIBRARIES = [ + 'stdc++', 'qpidclient', 'qpidcommon', 'qpidmessaging', diff --git a/cpp/bindings/qpid/ruby/features/creating_a_receiver.feature b/cpp/bindings/qpid/ruby/features/creating_a_receiver.feature index 1f758153af..def686f881 100644 --- a/cpp/bindings/qpid/ruby/features/creating_a_receiver.feature +++ b/cpp/bindings/qpid/ruby/features/creating_a_receiver.feature @@ -25,5 +25,5 @@ Feature: Creating a receiver Scenario: Using an Address object Given an open session - And an Address with the name "create-receiver-test" and subject "foo" and option "create" set to "always" and "delete" set to "always" + And an Address with the string "create-receiver-test;{create:always}" Then creating a receiver with an Address succeeds diff --git a/cpp/bindings/qpid/ruby/features/creating_a_sender.feature b/cpp/bindings/qpid/ruby/features/creating_a_sender.feature index 1c09ff837d..c12b10e054 100644 --- a/cpp/bindings/qpid/ruby/features/creating_a_sender.feature +++ b/cpp/bindings/qpid/ruby/features/creating_a_sender.feature @@ -21,5 +21,5 @@ Feature: Creating a sender Scenario: Using an Address object Given an open session - And an Address with the name "my-queue" and subject "my-subject" and option "create" set to "always" + And an Address with the string "my-queue/my-subject;{create:always}" Then creating a sender with an Address succeeds diff --git a/cpp/bindings/qpid/ruby/features/step_definitions/address_steps.rb b/cpp/bindings/qpid/ruby/features/step_definitions/address_steps.rb index 0531e5ee69..a7eca6f9ce 100644 --- a/cpp/bindings/qpid/ruby/features/step_definitions/address_steps.rb +++ b/cpp/bindings/qpid/ruby/features/step_definitions/address_steps.rb @@ -17,15 +17,6 @@ # under the License. # -Given /^an Address with the name "([^"]*)" and subject "([^"]*)" and option "([^"]*)" set to "([^"]*)"$/ do |name, subject, key, value| - options = Hash.new - options["#{key}"] = "#{value}" - @address = Qpid::Messaging::Address.new "#{name}", "#{subject}", options -end - -Given /^an Address with the name "([^"]*)" and subject "([^"]*)" and option "([^"]*)" set to "([^"]*)" and "([^"]*)" set to "([^"]*)"$/ do |name, subject, key1, value1, key2, value2| - options = Hash.new - options["#{key1}"] = "#{value1}" - options["#{key2}"] = "#{value2}" - @address = Qpid::Messaging::Address.new "#{name}", "#{subject}", options +Given /^an Address with the string "(.*?)"$/ do |address| + @address = Qpid::Messaging::Address.new "#{address}" end diff --git a/cpp/bindings/qpid/ruby/features/support/env.rb b/cpp/bindings/qpid/ruby/features/support/env.rb index 1d15f56fc9..cc0097ca8b 100644 --- a/cpp/bindings/qpid/ruby/features/support/env.rb +++ b/cpp/bindings/qpid/ruby/features/support/env.rb @@ -19,4 +19,4 @@ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../lib") -require 'qpid' +require 'qpid_messaging' diff --git a/cpp/bindings/qpid/ruby/lib/qpid.rb b/cpp/bindings/qpid/ruby/lib/qpid.rb deleted file mode 100644 index 1f00c136c1..0000000000 --- a/cpp/bindings/qpid/ruby/lib/qpid.rb +++ /dev/null @@ -1,29 +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. -# - -require 'qpid/errors' -require 'qpid/duration' -require 'qpid/address' -require 'qpid/encoding' -require 'qpid/message' -require 'qpid/sender' -require 'qpid/receiver' -require 'qpid/session' -require 'qpid/connection' - diff --git a/cpp/bindings/qpid/ruby/lib/qpid/connection.rb b/cpp/bindings/qpid/ruby/lib/qpid/connection.rb deleted file mode 100644 index 12669bc947..0000000000 --- a/cpp/bindings/qpid/ruby/lib/qpid/connection.rb +++ /dev/null @@ -1,162 +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. -# - -require 'cqpid' - -module Qpid - - module Messaging - - # Establishes a connection to a remote endpoint. - class Connection - - attr_reader :options # :nodoc: - - # Creates a connection object, but does not actually connect to - # the specified location. - # - # ==== Options - # - # :url - the URL for the broker (def. +"localhost"+) - # :options - connection options (def. +{}+) - # - # ==== Controlling Reconnect Behavior - # - # The following connection options can be used to configure - # the reconnection behavior for this connection. - # - # * :username - # * :password - # * :heartbeat - # * :tcp_nodelay - # * :sasl_mechanism - # * :sasl_service - # * :sasl_min_ssf - # * :sasl_max_ssf - # * :transport - # * :reconnect - +true+ or +false+; indicates wehtehr 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 - # - # conn = Qpid::Messaging::Connnection.new - # conn = Qpid::Messaging::Connection.new :url => "amqp:tcp:broker1.domain.com:5672" - # conn = Qpid::Messaging::Connection.new :options => {:username => "login", :password => "password"} - # - def initialize(opts = {}) - @url = opts[:url] || "localhost" - @options = convert_options(opts[:options] || {}) - @connection_impl = opts[:impl] || Cqpid::Connection.new(@url, @options) - end - - def connection_impl # :nodoc: - @connection_impl - end - - # Establishes the connection. - # - # ==== Examples - # - # conn.open unless conn.open? - # - def open - @connection_impl.open - end - - # Reports whether the connection is open. - # - # ==== Examples - # - # conn.close if conn.open? - # - def open?; true && !@connection_impl.nil? && @connection_impl.isOpen; end - - # Closes the connection. - 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 - # - # session = conn.create_session :name => "session1" - # 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 for the specified session name. - # - # ==== Examples - # - # begin - # session = conn.session "mysession" - # rescue SessionNameException => error - # puts "No such session." - # end - # - def session name - begin - session_impl = @connection_impl.getSession name - Qpid::Messaging::Session.new self, session_impl if session_impl - rescue - raise Qpid::Messaging::SessionNameException.new "No such session: #{name}" - end - end - - # Returns the username used to authenticate with the connection. - 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/errors.rb b/cpp/bindings/qpid/ruby/lib/qpid/errors.rb deleted file mode 100644 index c98eb1ac12..0000000000 --- a/cpp/bindings/qpid/ruby/lib/qpid/errors.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 - - module Messaging - - class KeyError < RuntimeError; end - - class SessionNameException < Exception - def initialize(msg); super(msg); end - end - - end - -end - diff --git a/cpp/bindings/qpid/ruby/lib/qpid/version.rb b/cpp/bindings/qpid/ruby/lib/qpid/version.rb deleted file mode 100644 index 39524e428f..0000000000 --- a/cpp/bindings/qpid/ruby/lib/qpid/version.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 - - module Version - - NUMBERS = [MAJOR = 0, - MINOR = 17, - BUILD = 0] - end - - VERSION = Version::NUMBERS.join('.') - -end diff --git a/cpp/bindings/qpid/ruby/lib/qpid_messaging.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging.rb new file mode 100644 index 0000000000..2b5348f298 --- /dev/null +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging.rb @@ -0,0 +1,82 @@ +#-- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +#++ + +require 'cqpid' +require 'qpid_messaging/duration' +require 'qpid_messaging/address' +require 'qpid_messaging/encoding' +require 'qpid_messaging/message' +require 'qpid_messaging/sender' +require 'qpid_messaging/receiver' +require 'qpid_messaging/session' +require 'qpid_messaging/connection' + +module Qpid + + # The Qpid Messaging framework is an enterprise messaging framework + # based on the open-source AMQP protocol. + # + # ==== Example Application + # + # Here is a simple example application. It creates a link to a broker located + # on a system named *broker.myqpiddomain.com*. It then creates a new messaging + # queue named "qpid-examples" and publishes a message to it. It then consumes + # that same message and closes the connection. + # + # require 'rubygems' + # gem 'qpid_messaging' + # require 'qpid_messaging' + # + # # create a connection, open it and then create a session named "session1" + # conn = Qpid::Messaging::Connection.new :name => "broker.myqpiddomain.com" + # conn.open + # session = conn.create_session "session1" + # + # # create a sender and a receiver + # # the sender marks the queue as one that is deleted when trhe sender disconnects + # send = session.create_sender "qpid-examples;{create:always,delete:always}" + # recv = session.create_receiver "qpid-examples" + # + # # create an outgoing message and send it + # outgoing = Qpid::Messaging::Message.new :content => "The time is #{Time.new}" + # sender.send outgoing + # + # # set the receiver's capacity to 10 and then check out many messages are pending + # recv.capacity = 10 + # puts "There are #{recv.available} messages waiting." # should report 1 message + # + # # get the nextwaiting message, which should be in the local queue now, + # # and output the contents + # incoming = recv.get Qpid::Messaging::Duration::IMMEDIATE + # puts "Received the following message: #{incoming.content}" + # # the output should be the text that was sent earlier + # + # # acknowledge the message, letting the sender know the message was received + # puts "The sender currently has #{send.unsettled} message(s) pending." + # # should report 1 unsettled message + # session.acknowledge incoming # acknowledge the received message + # puts "Now sender currently has #{send.unsettled} message(s) pending." + # # should report 0 unsettled messages + # + # # close the connection + # conn.close + # + module Messaging; end + +end diff --git a/cpp/bindings/qpid/ruby/lib/qpid/address.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb index 266d8668d6..0879f0fcd1 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/address.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/address.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,9 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' +#++ module Qpid @@ -26,13 +24,17 @@ module Qpid # Address represents an address to which messages can be sent or from # which they can be received. # - # An Address can be described using the following pattern: + # == 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 @@ -42,56 +44,49 @@ module Qpid # # The following are the list of supported options: # - # [:create] + # [create] # Indicates if the address should be created; values are *always*, # *never*, *sender* or *reciever*. # - # [:assert] + # [assert] # Indicates whether or not to assert any specified node properties; # values are *always*, *never*, *sender* or *receiver*. # - # [:delete] + # [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] + # [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. + # (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] + # [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] + # [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+ object. + # Creates a new +Address+ from an address string. # - # ==== Options + # ==== Attributes # - # * name - The name for the +Address+. - # * subject - The subject for the +Address+ - # * :create - See the class documentation. - # * :assert - See the class documentation. - # * :delete - See the class documentation. - # * :node - See the class documentation. - # * :link - See the class documentation. - # * :mode - See the class documentation. + # * +address+ - the address string # # ==== Examples # - # addr = Qpid::Messaging::Address.new "my-queue" - # addr = Qpid::Messaging::Address.new "my-queue", "testing", :create => :always + # # 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(name, subject, options = {}, _type = "", address_impl = nil) - @address_impl = address_impl || Cqpid::Address.new(name, subject, convert_options(options), _type) + def initialize(address, address_impl = nil) + @address_impl = address_impl || Cqpid::Address.new(address) end def address_impl # :nodoc: @@ -102,7 +97,10 @@ module Qpid # # ==== Examples # - # puts "The address name is #{addr.name}." + # # 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 @@ -110,6 +108,9 @@ module Qpid # # ==== 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 @@ -118,7 +119,8 @@ module Qpid # # ==== Examples # - # puts "The subject is #{addr.subject}." + # # creates a new address with the subject "bar" + # addr = Qpid::Messaging::Address.new "my-queue/bar;{create:always}" # def subject; @address_impl.getSubject; end @@ -126,30 +128,40 @@ module Qpid # # ==== Examples # - # addr.subject = "testing" + # # 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+. - # - # ==== Examples - # - # puts "The address is a #{address.address_type}." - # - #--- + #-- # 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. If no type is specified then it will be - # determined by querying the broker. + # 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 + # ==== Options + # + # * +type+ - the address type + # + # ==== Examples # - # * type - the address type + # # 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 @@ -163,6 +175,7 @@ module Qpid # ==== Examples # # addr.options = :create => :always + # addr.options = :create => :always, :delete => :always # def options=(options = {}); @address_impl.setOptions(convert_options(options)); 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/duration.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb index e1ddd79cb6..11c903dade 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/duration.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/duration.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,9 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' +#++ module Qpid @@ -25,19 +23,21 @@ module Qpid # A Duration represents a period of time in milliseconds # - # It defines the following named values as symbols: + # == Named Durations # - # [:FOREVER] + # The following named +Durations+ are available as symbols: + # + # [FOREVER] # The maximum integer value for the platform. Effectively this will wait # forever. # - # [:IMMEDIATE] + # [IMMEDIATE] # An alias for 0 milliseconds. # - # [:SECOND] + # [SECOND] # An alias for 1,000 milliseconds. # - # [:MINUTE] + # [MINUTE] # And alias for 60,000 millisecons. # class Duration @@ -46,12 +46,13 @@ module Qpid # # ==== Options # - # * length - The duration in milliseconds. + # * +length+ - The duration in +milliseconds+. # # ==== Examples # - # # Wait up to 10 seconds for an incoming message - # receiver.get Qpid::Messaging::Duration.new 10000 + # # 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 @@ -61,18 +62,50 @@ module Qpid @duration_impl end - # Returns the period of time in milliseconds + # Returns the period of time in +milliseconds+. # # ==== Examples # - # duration = Qpid::Messaging::Duration.new :length => 5000 - # puts "Waiting #{duration.milliseconds} ms for a message." - # msg = receiver.fetch duration + # # 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 diff --git a/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb index 2f20fab18e..ac0fbc32a7 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/encoding.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,45 +15,60 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' +#++ module Qpid module Messaging # Encodes the supplied content into the given message. - def self.encode content, message, encoding = nil - prepared = content - case content - when Hash - prepared = {} - content.each_pair do |key,value| - prepared[key.to_s] = value.to_s - end - Cqpid::encode prepared, message.message_impl - when Array - prepared = [] - content.each {|value| prepared << value.to_s} - Cqpid::encode prepared, message.message_impl - end + 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) - content_type = message.content_type unless content_type + def self.decode(message, content_type = nil) # :nodoc: + content_type = message.content_type if content_type.nil? case content_type when "amqp/map" - Cqpid.decodeMap message.message_impl + return Cqpid.decodeMap message.message_impl when "amqp/list" - Cqpid.decodeList message.message_impl + 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/message.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb index edef0ac2a0..e167800455 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/message.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/message.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,29 +15,26 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' +#++ module Qpid module Messaging # A +Message+ represents an routable piece of information. - # - # The content for a message is automatically encoded and decoded. - # class Message - # Creates a new instance of +Message+. + # Creates a +Message+. # # ==== Options # - # * :content - The content. + # * +: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 @@ -51,54 +48,48 @@ module Qpid @message_impl end - # Sets the address to which replies should be sent for the +Message+. + # Sets the reply-to address. # - # *NOTE:* The address must be an instance of Address. + # The address can either be an instance of Address or else and + # address string. # # ==== Options # - # * address - an instance of +Address+ + # * +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) - raise ArgumentError, "Agument must be an Address" unless address.is_a? Qpid::Messaging::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, nil, nil, nil, address_impl) if address_impl + Qpid::Messaging::Address.new(nil, address_impl) if address_impl end # Sets the subject for the +Message+. # # ==== Options # - # * subject - the subject - # - # ==== Examples - # - # msg.subject = "mysubject" - # + # * +subject+ - the subject def subject=(subject); @message_impl.setSubject subject; end # Returns the subject of the +Message+. - # - # ==== Options - # - # puts "The subject is #{msg.subject}" - # def subject; @message_impl.getSubject; end # Sets the content type for the +Message+. # - # This should be set by the sending applicaton and indicates to + # 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 @@ -107,23 +98,17 @@ module Qpid # # ==== Options # - # * content_type - the content type. - # - def content_type=(content_type); @message_impl.setContentType content_type; end - - # Returns the content type for the +Message+. + # * +content_type+ - the content type # # ==== Examples # - # case msg.content_type - # when "myapp/image" - # ctl.handle_image msg - # end - # when "myapp/audio" - # ctl.handle_audio msg - # end - # end + # # 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. @@ -133,16 +118,17 @@ module Qpid # # ==== Options # - # * id - the id + # * +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. - # - # See +message_id=+ for details. def message_id; @message_impl.getMessageId; end # Sets the user id for the +Message+. @@ -151,44 +137,38 @@ module Qpid # the connection itself, as the messaging infrastructure will verify # this. # - # See +Qpid::Messaging::Connection.authenticated_username+ + # 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 + # * +id+ - the id # def user_id=(user_id); @message_impl.setUserId user_id; end # Returns the user id for the +Message+. - # - # See +user_id=+ for details. - # 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 requestion-response pattern might require + # 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 + # 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 + # * +id+ - the id # def correlation_id=(correlation_id); @message_impl.setCorrelationId correlation_id; end # Returns the correlation id of the +Message+. - # - # *NOTE:* See +correlation_id=+ for details. - # def correlation_id; @message_impl.getCorrelationId; end # Sets the priority of the +Message+. @@ -202,19 +182,21 @@ module Qpid # # ==== Options # - # * priority - the priority + # * +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 + # * +duration+ - the number of milliseconds # def ttl=(duration) if duration.is_a? Qpid::Messaging::Duration @@ -231,16 +213,15 @@ module Qpid # # This is a hint to the messaging infrastructure that the message # should be persisted or otherwise stored. This helps to ensure - # that th emessage is not lost during to failures or a shutdown. + # that the message is not lost due to failures or a shutdown. # # ==== Options # - # * durable - the durability flag (def. false) + # * +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 @@ -249,17 +230,16 @@ module Qpid # # ==== Options # - # * redelivered - sets the redelivered state (def. false) + # * +redelivered+ - sets the redelivered state (def. false) # # ==== Examples # - # # processed is an array of processed message ids + # # 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. @@ -267,14 +247,13 @@ module Qpid # *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 + # * +name+ - the property name # # ==== Examples # @@ -285,44 +264,51 @@ module Qpid # Assigns a value to the named property. # - # *NOTE:* Both the key or the value may be a symbol, but they will - # both be converted to a +String+ for ease of transport. + # 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 - def []=(key, value); @message_impl.setProperty(key.to_s, value.to_s); end + # * +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 + # need to set their own content types (via content_type) in order to # specify how recipients should process the content. # # ==== Options # - # * content - the content + # * +content+ - the content # # ==== Examples # - # msg.content = "This is a simple message." # a simple message - # msg.content = {:foo => :bar} # content is automatically encoded + # # 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 = content + @content = Qpid::Messaging.stringify(content) case @content when Hash content_type = "amqp/map" - new_content = {} - content.each_pair{|key, value| new_content[key.to_s] = value.to_s} - @content = new_content when Array - new_content = [] content_type = "amqp/list" - content.each {|element| new_content << element.to_s} - @content = new_content end if content_type.nil? @message_impl.setContent @content @@ -356,8 +342,7 @@ module Qpid @content end - # Returns the content's size. - # + # Returns the content's size in bytes. def content_size; @message_impl.getContentSize; end end diff --git a/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb index 0ce16309ed..05ee925212 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/receiver.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,27 +15,32 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' - -require 'qpid/duration' +#++ module Qpid module Messaging - # Receiver is the entity through which messages are received. + # +Receiver+ is the entity through which messages are received. # - # An instance of Receiver can only be created using an active (not - # previously closed) Session. + # 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 - # receiver = session.create_receiver "my-sender-queue" + # + # # 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: @@ -50,27 +55,24 @@ module Qpid # Retrieves a message from the local queue, or waits for up to # the duration specified for one to become available. # - # If a block is given, then it will be invaked after the next message - # is received or the call times out, passing in the message or nil - # respectively. + # If no message is received within the specified time then a + # MessagingException is raised. # # ==== Options - # * duration - the timeout to wait (def. Duration::FOREVER) - # - # ==== Examples # - # msg = rcvr.get # Uses the default timeout of forever + # * duration - the timeout to wait # - # msg = rcvr.get Qpid::Messaging::Duration::IMMEDIATE # returns a message or exits immediately + # ==== Examples # - # # passes in a block to handle the received message - # rcvr.get Qpid::Messaging::Duration::SECOND do |message| - # if message.nil? - # puts "No message was received." - # else - # puts "Received this message: #{message.content}" - # end + # # 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? @@ -79,33 +81,35 @@ module Qpid # Retrieves a message from the receiver's subscription, or waits # for up to the duration specified for one to become available. # - # If a block is given, then it will be invaked after the next message - # is received or the call times out, passing in the message or nil - # respectively. + # If no message is fetched within the specified time then a + # MessagingException is raised. # # ==== Options + # # * duration - the timeout to wait (def. Duration::FOREVER) # # ==== Examples # - # msg = rcvr.fetch # Uses the default timeout of forever - # - # msg = rcvr.fetch Qpid::Messaging::Duration::IMMEDIATE # returns a message or exits immediately - # - # # passes in a block to handle the received message - # rcvr.fetch Qpid::Messaging::Duration::SECOND do |message| - # if message.nil? - # puts "No message was received." - # else - # puts "Received this message: #{message.content}" - # end + # # 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 for this +Receiver+. + # 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 # @@ -113,63 +117,50 @@ module Qpid # # ==== Examples # - # receiver.capacity = 50 # sets the incoming capacity to 50 messages + # # 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. - # - # - # The capacity is the numnber of incoming messages that can be held - # locally before being fetched. - # - # ==== Examples - # - # puts "The receiver can hold #{rcv.capacity} messages." - # def capacity; @receiver_impl.getCapacity; end - # Returns the number of slots for receiving messages. + # Returns the number of messages locally held. # - # This differs from +capacity+ in that it is the available slots in - # the capacity for holding incoming messages, where available <= capacity. + # The available is always 0 <= available <= capacity. + # + # If the #capacity is set to 0 then available will always be 0. # # ==== Examples # - # puts "You can receive #{rcv.available} messages before blocking." + # # 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. - # - # ==== Examples - # - # puts "You have #{rcv.unsettled} messages to be confirmed." - # def unsettled; @receiver_impl.getUnsettled; end # Closes this +Receiver+. # - # This does not affect the +Session+. + # This does not affect the owning Session or Connection. def close; @receiver_impl.close; end - # Returns whether the receiver is closed. - # - # ==== Examples - # - # recv.close unless recv.closed? - # + # Returns whether the +Receiver+ is closed. def closed?; @receiver_impl.isClosed; end # Returns the name of this +Receiver+. - # - # ==== Examples - # - # puts "Receiver: #{recv.name}" def name; @receiver_impl.getName; end - # Returns the Session for this +Receiver+. + # Returns the owning Session for this +Receiver+. def session; @session; end private diff --git a/cpp/bindings/qpid/ruby/lib/qpid/sender.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb index 97227622f5..4ce1393dc7 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/sender.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/sender.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,23 +15,39 @@ # 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 sent. + # +Sender+ is the entity through which messages are sent. # - # An instance of Sender can only be created using an active (not previously - # closed) Session. + # 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 # - # conn = Qpid::Messaging::Connection.new :url => "mybroker:5762" + # # create a connection + # conn = Qpid::Messaging::Connection.new "mybroker:5672" # conn.open - # session = conn.create_session - # sender = session.create_session "my-sender-queue;{create:always}" + # + # 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: @@ -43,15 +59,13 @@ module Qpid @sender_impl end - # Sends a message. - # - # If a block is given, then it will be invoked after the message - # is sent. + # Sends a message, optionally blocking until the message is received + # by the broker. # # ==== Options # - # * message - The message to send. - # * :sync - See note below on synching. + # * +message+ - The message to send. + # * +:sync+ - Block until received. See note below on synching. # # ==== Synching # @@ -61,9 +75,13 @@ module Qpid # # ==== Examples # - # sender.send message do |message| - # puts "Message sent: #{message.content}" - # end + # # 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 @@ -73,52 +91,27 @@ module Qpid # Closes this +Sender+. # - # This does not affect the +Session+. + # This does not affect the owning Session or Connection. def close; @sender_impl.close; end # Returns the human-readable name for this +Sender+. - # - # ==== Examples - # - # puts "Sender: #{sender.name}" - # 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 or receipt by the broker. + # pending confirmation of receipt by the broker. # # ==== Options # - # * capacity - the capacity - # - # ==== Examples - # - # sender.capacity = 50 # sets the outgoing capacity to 50 messages - # + # * +capacity+ - the capacity def capacity=(capacity); @sender_impl.setCapacity capacity; end # Returns the capacity. - # - # The capacity is the total number of outgoing messages that can be - # sent before a called to +send+ begins to block by default. - # - # ==== Examples - # - # puts "You can send a maximum of #{sender.capacity} messages." - # def capacity; @sender_impl.getCapacity; end # Returns the number of messages sent that are pending receipt # confirmation by the broker. - # - # ==== Examples - # - # if sender.unsettled > 0 - # puts "There are #{sender.unsettled} messages pending." - # end - # def unsettled; @sender_impl.getUnsettled; end # Returns the available slots for sending messages. @@ -127,21 +120,11 @@ module Qpid # the senders capacity for holding outgoing messages. The difference # between capacity and available is the number of messages that # have not been delivered yet. - # - # ==== Examples - # - # puts "You can send #{sender.available} messages before blocking." - # def available @sender_impl.getAvailable end - # Returns the +Session+ for this sender. - # - # ==== Examples - # - # recv.session.close if done - # + # Returns the Session for this sender. def session; @session; end end diff --git a/cpp/bindings/qpid/ruby/lib/qpid/session.rb b/cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb index feb8aa5bb4..7e6e11f654 100644 --- a/cpp/bindings/qpid/ruby/lib/qpid/session.rb +++ b/cpp/bindings/qpid/ruby/lib/qpid_messaging/session.rb @@ -1,4 +1,4 @@ -# +#-- # 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 @@ -15,48 +15,41 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# - -require 'cqpid' - -require 'qpid/errors' +#++ module Qpid module Messaging - # A Session represents a distinct conversation between end points. + # 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 - @senders = Hash.new - @receivers = Hash.new end def session_impl # :nodoc: @session_impl end - # Returns the +Connection+ associated with this session. + # 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 a - # string that describes an address endpoint. + # The address can either be an instance Address or else an + # address string. # # ==== Arguments # - # * +address+ The end point address. - # - # ==== Examples - # - # sender = session.create_sender "my-queue;{create:always}" - # + # * +address+ - the end point address. def create_sender(address) _address = address @@ -67,43 +60,28 @@ module Qpid sender_impl = @session_impl.createSender(_address) sender_name = sender_impl.getName - @senders[sender_name] = Qpid::Messaging::Sender.new(self, sender_impl) - - @senders[sender_name] + Qpid::Messaging::Sender.new(self, sender_impl) end - # Retrieves the +Sender+ with the specified name. + # Retrieves the Sender with the specified name. # - # The +Sender+ must have been previously created using - # the +create_sender+ method. + # Raises an exception if no such Sender exists. # # ==== Arguments # - # * +name+ The +Sender+ name. - # - # ==== Examples - # - # sender = session.sender "my-queue" - # + # * +name+ - the name of the Sender def sender(name) - raise Qpid::Messaging::KeyError, "No such sender: #{name}" unless @senders.has_key? name - - @senders[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 a - # string that describes an address endpoint. + # The +address+ can either be an instance Address or else an + # address string. # # ==== Arguments # - # * +address+ The end point address. - # - # ==== Examples - # - # receiver = session.create_receiver "my-queue" - # + # * +address+ - the end point address. def create_receiver(address) result = nil receiver_impl = nil @@ -115,36 +93,24 @@ module Qpid receiver_impl = @session_impl.createReceiver(address) end - receiver_name = receiver_impl.getName - - @receivers[receiver_name] = Qpid::Messaging::Receiver.new self, receiver_impl - - @receivers[receiver_name] + Qpid::Messaging::Receiver.new self, receiver_impl end - # Retrieves the +Receiver+ with the specified name. - # - # The +Receiver+ must have been previously created using - # the +create_receiver+ method. + # Retrieves the +Receiver+ with the specified name, or nil if no such + # Receiver exists. # # ==== Arguments # - # * +name+ The +Receiver+ name. - # - # ==== Examples - # - # receiver = session.receiver "my-queue" - # + # * +name+ - the name of the Receiver def receiver(name) - raise Qpid::Messaging::KeyError, "No such receiver: #{name}" unless @receivers.has_key? name - - @receivers[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. + # *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. @@ -158,21 +124,30 @@ module Qpid # # ==== Arguments # - # * :message - if specified, then only the +Message+ specified is acknowledged - # * :sync - if true then the call will block until processed by the server (def. false) + # * +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 # - # session.acknowledge # acknowledges all received messages - # session.acknowledge :message => message # acknowledge one message - # session.acknowledge :sync => true # blocks until the call completes + # # 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(args = {}) - sync = args[:sync] || false - message = args[:message] if args[:message] + def acknowledge(options = {}) + sync = options[:sync] || false + message = options[:message] if options[:message] unless message.nil? @session_impl.acknowledge message.message_impl, sync @@ -193,11 +168,15 @@ module Qpid # NOTE: A message connot be released once it has been acknowled. def release(message); @session_impl.release message.message_impl; end - # Requests synchronization with the server. + # Requests synchronization with the broker. # # ==== Arguments # - # * :block - if true then the call blocks until the server acknowledges it (def. false) + # * +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. @@ -208,26 +187,43 @@ module Qpid end # Returns the total number of receivable messages, and messages already - # received, by +Receiver+ instances associated with this +Session+. + # 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 server. + # 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 +Receiver+ for the next message. + # 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 - time to wait for a +Receiver+ before timing out + # * +timeout+ - the duration # # ==== Examples # - # recv = session.next_receiver # wait forever for the next +Receiver+ - # # execute a block on the next receiver - # session.next_receiver do |recv| - # msg = recv.get - # puts "Received message: #{msg.content}" + # 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) @@ -241,10 +237,6 @@ module Qpid end # Returns true if there were exceptions on this session. - # - # ==== Examples - # - # puts "There were session errors." if @session.errors? def errors?; @session_impl.hasError; end # If the +Session+ has been rendered invalid due to some exception, @@ -254,6 +246,7 @@ module Qpid # # ==== Examples # + # # show any errors that occurred during the Session # if @session.errors? # begin # @session.errors diff --git a/cpp/bindings/qpid/ruby/qpid_messaging.gemspec b/cpp/bindings/qpid/ruby/qpid_messaging.gemspec new file mode 100644 index 0000000000..06e3f48cb8 --- /dev/null +++ b/cpp/bindings/qpid/ruby/qpid_messaging.gemspec @@ -0,0 +1,28 @@ +# -*- encoding: utf-8 -*- +lib = File.expand_path('lib/', __FILE__) +$:.unshift lib unless $:.include?(lib) + +# Generate the Swig wrapper +system "swig -ruby -c++ -I../../../include -I../../ -o ext/cqpid/cqpid.cpp ruby.i" + +Gem::Specification.new do |s| + s.name = "qpid_messaging" + s.version = "0.22.0" + s.platform = Gem::Platform::RUBY + s.authors = "Apache Qpid Project" + s.email = "dev@qpid.apache.org" + s.homepage = "http://qpid.apache.org" + s.summary = "Qpid is an enterprise messaging framework." + s.description = s.summary + + s.extensions = "ext/cqpid/extconf.rb" + s.files = Dir["LICENSE", + "ChangeLog", + "README.rdoc", + "TODO", + "lib/**/*.rb", + "ext/**/*", + ] + s.require_path = 'lib' +end + diff --git a/cpp/bindings/qpid/ruby/ruby.i b/cpp/bindings/qpid/ruby/ruby.i index 76463f7ddd..3d686c2ddb 100644 --- a/cpp/bindings/qpid/ruby/ruby.i +++ b/cpp/bindings/qpid/ruby/ruby.i @@ -18,8 +18,10 @@ */ %module cqpid +/* Ruby doesn't have a != operator*/ +#pragma SWIG nowarn=378 %include "std_string.i" -%include "../../swig_ruby_typemaps.i" +%include "qpid/swig_ruby_typemaps.i" /* Define the general-purpose exception handling */ %exception { @@ -32,5 +34,5 @@ } } -%include "../qpid.i" +%include "qpid/qpid.i" diff --git a/cpp/bindings/qpid/ruby/spec/qpid/address_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/address_spec.rb index 784fb6fe77..05c97ddf30 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/address_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/address_spec.rb @@ -26,7 +26,7 @@ module Qpid describe Address do before(:each) do - @address = Qpid::Messaging::Address.new "my-name", "my-subject", :create => :always + @address = Qpid::Messaging::Address.new "my-name/my-subject;{create:always}" end it "stores the name, subject and options when created" do @@ -72,7 +72,7 @@ module Qpid end it "can return a string representation" do - address = Qpid::Messaging::Address.new "foo", "bar", :create => :always, :link => :durable + address = Qpid::Messaging::Address.new "foo/bar:{create:always,link:durable}" result = address.to_s result.should =~ /foo\/bar/ diff --git a/cpp/bindings/qpid/ruby/spec/qpid/connection_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/connection_spec.rb index a2f5b7e898..811abf36e9 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/connection_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/connection_spec.rb @@ -37,7 +37,7 @@ module Qpid connection = Qpid::Messaging::Connection.new :options => {:username => "foo"} connection.options.should include("username") - }.should_not raise_error + }.to_not raise_error end it "returns the underlying implementation" do diff --git a/cpp/bindings/qpid/ruby/spec/qpid/duration_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/duration_spec.rb index 4980b6ffe7..202332d232 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/duration_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/duration_spec.rb @@ -49,6 +49,33 @@ module Qpid milliseconds.should == 1000 end + it "raises an error when multiplied by a negative" do + expect { + twomin = Qpid::Messaging::Duration::MINUTE * -2 + }.to raise_error + end + + it "returns IMMEDIATE if the factor is zero" do + result = Qpid::Messaging::Duration::MINUTE * 0 + result.should be(Qpid::Messaging::Duration::IMMEDIATE) + end + + it "fractional factors return a reduced duration" do + factor = rand(1) + first = Qpid::Messaging::Duration::MINUTE + second = first * factor + + second.milliseconds.should == ((first.milliseconds * factor).floor) + end + + it "can return a multiple of its duration" do + factor = rand(10).floor + first = Qpid::Messaging::Duration.new(rand(10).floor * 10000) + second = first * factor + + second.milliseconds.should == first.milliseconds * factor + end + end end diff --git a/cpp/bindings/qpid/ruby/spec/qpid/encoding_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/encoding_spec.rb index 58b8447278..58b8447278 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/encoding_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/encoding_spec.rb diff --git a/cpp/bindings/qpid/ruby/spec/qpid/message_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/message_spec.rb index e34e58f563..be19b3591e 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/message_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/message_spec.rb @@ -36,7 +36,7 @@ module Qpid end it "can set the reply to address" do - address = Qpid::Messaging::Address.new "my-queue", "" + address = Qpid::Messaging::Address.new "my-queue;{create:always}" @message.reply_to = address @@ -45,6 +45,19 @@ module Qpid reply_to.name.should == address.name end + it "can set the reply to from an address string" do + name = "my-queue" + subject = "responses" + address = "#{name}/#{subject}" + + @message.reply_to = address + + reply_to = @message.reply_to + + reply_to.name.should == name + reply_to.subject.should == subject + end + it "should store the content when created" do content = @message.content diff --git a/cpp/bindings/qpid/ruby/spec/qpid/receiver_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/receiver_spec.rb index 81ae935dcb..81ae935dcb 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/receiver_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/receiver_spec.rb diff --git a/cpp/bindings/qpid/ruby/spec/qpid/sender_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/sender_spec.rb index fa3a2a5b1f..fa3a2a5b1f 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/sender_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/sender_spec.rb diff --git a/cpp/bindings/qpid/ruby/spec/qpid/session_spec.rb b/cpp/bindings/qpid/ruby/spec/qpid_messaging/session_spec.rb index 0b103a31e6..754e2ca88f 100644 --- a/cpp/bindings/qpid/ruby/spec/qpid/session_spec.rb +++ b/cpp/bindings/qpid/ruby/spec/qpid_messaging/session_spec.rb @@ -46,7 +46,7 @@ module Qpid end it "creates a Sender from an Address" do - address = Qpid::Messaging::Address.new "my-queu", "", :create => :always + address = Qpid::Messaging::Address.new "my-queue;{create:always}" @session_impl.should_receive(:createSender). with(address.address_impl). diff --git a/cpp/bindings/qpid/ruby/spec/spec_helper.rb b/cpp/bindings/qpid/ruby/spec/spec_helper.rb index 90084963f4..865e60e0e2 100644 --- a/cpp/bindings/qpid/ruby/spec/spec_helper.rb +++ b/cpp/bindings/qpid/ruby/spec/spec_helper.rb @@ -17,5 +17,4 @@ # under the License. # -require 'qpid' -require 'cqpid' +require 'qpid_messaging' |