diff options
Diffstat (limited to 'qpid/cpp/bindings')
43 files changed, 3973 insertions, 89 deletions
diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am b/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am index 84207d43c4..062fbd0a85 100644 --- a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am +++ b/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am @@ -21,7 +21,7 @@ INCLUDE = -I$(top_srcdir)/include AM_CPPFLAGS = $(INCLUDE) -noinst_PROGRAMS=agent list_agents print_events +noinst_PROGRAMS=agent event_driven_list_agents list_agents print_events agent_SOURCES=agent.cpp agent_LDADD=$(top_builddir)/src/libqmf2.la @@ -29,5 +29,8 @@ agent_LDADD=$(top_builddir)/src/libqmf2.la list_agents_SOURCES=list_agents.cpp list_agents_LDADD=$(top_builddir)/src/libqmf2.la +event_driven_list_agents_SOURCES=event_driven_list_agents.cpp +event_driven_list_agents_LDADD=$(top_builddir)/src/libqmf2.la + print_events_SOURCES=print_events.cpp print_events_LDADD=$(top_builddir)/src/libqmf2.la diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp b/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp new file mode 100644 index 0000000000..c288aa6bdd --- /dev/null +++ b/qpid/cpp/bindings/qmf2/examples/cpp/event_driven_list_agents.cpp @@ -0,0 +1,107 @@ +/* + * 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. + */ + +#include <sys/select.h> +#include <time.h> + +#include <qpid/messaging/Connection.h> +#include <qpid/messaging/Duration.h> +#include <qmf/Agent.h> +#include <qmf/ConsoleEvent.h> +#include <qmf/ConsoleSession.h> +#include <qpid/types/Variant.h> +#include "qmf/posix/EventNotifier.h" + +#include <string> +#include <iostream> + +using namespace std; +using namespace qmf; +using qpid::types::Variant; +using qpid::messaging::Duration; + +int main(int argc, char** argv) +{ + string url("localhost"); + string connectionOptions; + string sessionOptions; + + if (argc > 1) + url = argv[1]; + if (argc > 2) + connectionOptions = argv[2]; + if (argc > 3) + sessionOptions = argv[3]; + + qpid::messaging::Connection connection(url, connectionOptions); + connection.open(); + + ConsoleSession session(connection, sessionOptions); + session.open(); + session.setAgentFilter(""); + + posix::EventNotifier notifier(session); + + int fd(notifier.getHandle()); + time_t lastUpdate; + bool ftl = false; + + time(&lastUpdate); + + while (true) { + fd_set rfds; + struct timeval tv; + int nfds, retval; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + nfds = fd + 1; + tv.tv_sec = 10; + tv.tv_usec = 0; + + retval = select(nfds, &rfds, NULL, NULL, &tv); + + if (retval > 0 && FD_ISSET(fd, &rfds)) { + ConsoleEvent event; + while (session.nextEvent(event, Duration::IMMEDIATE)) { + string eventType = ""; + switch(event.getType()) { + case CONSOLE_AGENT_ADD: eventType = "Added"; break; + case CONSOLE_AGENT_DEL: eventType = "Deleted"; break; + case CONSOLE_AGENT_RESTART: eventType = "Restarted"; break; + case CONSOLE_AGENT_SCHEMA_UPDATE: eventType = "Schema Updated"; break; + case CONSOLE_AGENT_SCHEMA_RESPONSE: eventType = "Schema Response"; break; + case CONSOLE_EVENT: eventType = "Event"; break; + case CONSOLE_QUERY_RESPONSE: eventType = "Query Response"; break; + case CONSOLE_METHOD_RESPONSE: eventType = "Method Response"; break; + case CONSOLE_EXCEPTION: eventType = "Exception"; break; + case CONSOLE_SUBSCRIBE_ADD: eventType = "Subscription Added"; break; + case CONSOLE_SUBSCRIBE_UPDATE: eventType = "Subscription Updated"; break; + case CONSOLE_SUBSCRIBE_DEL: eventType = "Subscription Deleted" ; break; + case CONSOLE_THREAD_FAILED: eventType = "Thread Failure"; break; + default: eventType = "[UNDEFINED]"; + } + cout << "Agent " << eventType << ": " << event.getAgent().getName() << endl; + } + } else { + cout << "No message received within waiting period." << endl; + } + } +} + diff --git a/qpid/cpp/bindings/qpid/dotnet/configure-windows.ps1 b/qpid/cpp/bindings/qpid/dotnet/configure-windows.ps1 index 34395911b9..23fc742e07 100644 --- a/qpid/cpp/bindings/qpid/dotnet/configure-windows.ps1 +++ b/qpid/cpp/bindings/qpid/dotnet/configure-windows.ps1 @@ -24,29 +24,32 @@ # This script configures a qpid\cpp developer build environment under Windows
# to enable working with cpp\bindings\qpid\dotnet binding source code.
#
+# * Supports multiple versions of Visual Studio (VS2008, VS2010) as CMake
+# generator.
+#
# * Supports 32-bit and/or 64-bit development platforms.
#
# * User chooses in-source or out-of-source build directories.
#
# - 'In-source' builds happen when CMake is run from directory qpid\cpp.
-# Hundreds of CMake-generated output files are placed in qpid\cpp\src.
+# Hundreds of CMake-generated output files are placed in qpid\cpp\src.
# These files go right on top of files that are part of the source tree
# in qpid\cpp\src.
-# In-source builds support only one platform.
+# In-source builds support only one platform.
# Choose only a 32-bit or a 64-bit platform but not both.
#
# - Out-of-source builds happen when the user chooses another directory
# under qpid in which to run CMake. Out-of-source builds are required
-# in order to build both x86 and x64 targets using the same source tree.
+# in order to build both x86 and x64 targets using the same source tree.
# For each build platform (32-bit x86 or Win32, or 64-bit x64) the user
-# specifies a build directory and a specific version of Boost.
+# specifies a build directory and a specific version of Boost.
# Many platform/Boost-version directories may reside side by side.
#
# * User chooses to run CMake or not.
#
# - When a new build directory is created then the user is given the
-# option of running CMake in that directory. Running CMake is a
-# necessary step as CMake creates important source, solution, and
+# option of running CMake in that directory. Running CMake is a
+# necessary step as CMake creates important source, solution, and
# project files.
#
# - If a directory "looks like" is has already had CMake run in it
@@ -63,7 +66,7 @@ # 3. CMake 2.8 (or later) must be installed. The cmake\bin directory
# must be in the user's path.
# 4. Boost library specifications may or may not be in the user's path.
-# The script author recommeds not to have Boost in the path and only
+# The script author recommeds not to have Boost in the path and only
# allow the Boost path to be specified by generated command procedures.
# 5. Visual Studio build environment must be installed.
#
@@ -90,7 +93,7 @@ # In this example the build dirs are new. The script will prompt
# asking if CMake is to run in the build directories. User chooses Yes.
#
-# Now this script runs CMake twice, once each with the 32-bit and 64-bit
+# Now this script runs CMake twice, once each with the 32-bit and 64-bit
# generators.
# * This step creates qpid-cpp.sln and related project files.
# C:\svn\qpid\build32\qpid-cpp.sln
@@ -107,7 +110,7 @@ # C:\svn\qpid\build64\setenv-messaging-x64-64bit.bat
#
# Next the user compiles solution qpid\build32\qpid-cpp.sln.
-#
+#
# Using the generated scripts:
#
# Case 1. Run an executable in 32-bit mode.
@@ -142,6 +145,11 @@ $global:txtPath = '$env:PATH' $global:txtQR = '$env:QPID_BUILD_ROOT'
$global:txtWH = 'Write-Host'
+#############################
+# Visual Studio version selection dialog items and choice
+#
+[array]$global:VsVersionCmakeChoiceList = "Visual Studio 10", "Visual Studio 9 2008"
+$global:cmakeGenerator = ''
#############################
# Select-Folder
@@ -168,7 +176,7 @@ function AskYesOrNo ($Question="No question?", $Title="No Title?") [Windows.Forms.MessageBoxIcon]::Question)
$result = $dlg -eq [Windows.Forms.DialogResult]::Yes
-
+
$result
}
@@ -188,7 +196,7 @@ function SanityCheckBoostPath ($path=0) $toTest = ('include', 'lib')
foreach ($pattern in $toTest) {
- $target = Join-Path $path $pattern
+ $target = Join-Path $path $pattern
if (!(Test-Path -path $target)) {
$result = $false
}
@@ -196,7 +204,7 @@ function SanityCheckBoostPath ($path=0) } else {
$result = $false
}
-
+
if (! $result) {
Write-Host "The path ""$displayPath"" does not appear to be a Boost root path."
}
@@ -219,7 +227,7 @@ function SanityCheckBuildPath ($path=0) $toTest = ('CMakeFiles', 'docs', 'etc', 'examples', 'include',
'managementgen', 'src')
foreach ($pattern in $toTest) {
- $target = Join-Path $path $pattern
+ $target = Join-Path $path $pattern
if (!(Test-Path -path $target)) {
$result = $false
}
@@ -313,7 +321,7 @@ function WriteDotnetBindingEnvSetupBat $out = @("@ECHO OFF
REM
-REM Call this command procedure from a command prompt to set up a $vsPlatform ($nBits-bit)
+REM Call this command procedure from a command prompt to set up a $vsPlatform ($nBits-bit)
REM $slnName environment
REM
REM > call $outfileName
@@ -329,6 +337,56 @@ ECHO Environment set for $slnName $vsPlatform $nBits-bit development. $out | Out-File "$buildRoot\$outfileName" -encoding ASCII
}
+#############################
+# Return the SelectedItem from the dropdown list and close the form.
+#
+function Return-DropDown {
+ if ($DropDown.SelectedItem -ne $null) {
+ $global:cmakeGenerator = $DropDown.SelectedItem.ToString()
+ $Form.Close()
+ Write-Host "Selected generator: $global:cmakeGenerator"
+ }
+}
+
+#############################
+# Create the CMake generator form and launch it
+#
+function SelectCMakeGenerator {
+
+ $Form = New-Object System.Windows.Forms.Form
+
+ $Form.width = 350
+ $Form.height = 150
+ $Form.Text = ”Select CMake Generator”
+
+ $DropDown = new-object System.Windows.Forms.ComboBox
+ $DropDown.Location = new-object System.Drawing.Size(120,10)
+ $DropDown.Size = new-object System.Drawing.Size(150,30)
+
+ ForEach ($Item in $global:VsVersionCmakeChoiceList) {
+ $DropDown.Items.Add($Item)
+ }
+ $DropDown.SelectedIndex = 0
+
+ $Form.Controls.Add($DropDown)
+
+ $DropDownLabel = new-object System.Windows.Forms.Label
+ $DropDownLabel.Location = new-object System.Drawing.Size(10,10)
+ $DropDownLabel.size = new-object System.Drawing.Size(100,20)
+ $DropDownLabel.Text = "CMake generators"
+ $Form.Controls.Add($DropDownLabel)
+
+ $Button = new-object System.Windows.Forms.Button
+ $Button.Location = new-object System.Drawing.Size(120,50)
+ $Button.Size = new-object System.Drawing.Size(120,20)
+ $Button.Text = "Select a generator"
+ $Button.Add_Click({Return-DropDown})
+ $form.Controls.Add($Button)
+
+ $Form.Add_Shown({$Form.Activate()})
+ $Form.ShowDialog()
+}
+
#############################
# Main
@@ -341,6 +399,12 @@ ECHO Environment set for $slnName $vsPlatform $nBits-bit development. [string] $cppDir = Resolve-Path (Join-Path $curDir "..\..\..")
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
+[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
+
+#############################
+# User dialog to select a version of Visual Studio as CMake generator
+#
+SelectCMakeGenerator
#############################
# User dialog to get optional 32-bit boost and build paths
@@ -412,7 +476,7 @@ if ($make32) { $env:BOOST_ROOT = "$boost32"
cd "$build32"
Write-Host "Running 32-bit CMake in $build32 ..."
- CMake -G "Visual Studio 9 2008" "-DCMAKE_INSTALL_PREFIX=install_x86" $cppDir
+ CMake -G "$global:cmakeGenerator" "-DCMAKE_INSTALL_PREFIX=install_x86" $cppDir
} else {
Write-Host "Skipped 32-bit CMake."
}
@@ -424,7 +488,7 @@ if ($make64) { $env:BOOST_ROOT = "$boost64"
cd "$build64"
Write-Host "Running 64-bit CMake in $build64"
- CMake -G "Visual Studio 9 2008 Win64" "-DCMAKE_INSTALL_PREFIX=install_x64" $cppDir
+ CMake -G "$global:cmakeGenerator Win64" "-DCMAKE_INSTALL_PREFIX=install_x64" $cppDir
} else {
Write-Host "Skipped 64-bit CMake."
}
@@ -437,7 +501,7 @@ if ($make64) { if ($defined32) {
Write-Host "Writing 32-bit scripts..."
-
+
###########
# Powershell script to launch org.apache.qpid.messaging.sln
#
@@ -448,8 +512,8 @@ if ($defined32) { -vsPlatform "x86" `
-nBits "32" `
-outfileName "start-devenv-messaging-x86-32bit.ps1"
-
-
+
+
###########
# Batch script (that you doubleclick) to launch powershell script
# that launches org.apache.qpid.messaging.sln.
@@ -482,7 +546,7 @@ if ($defined32) { if ($defined64) {
Write-Host "Writing 64-bit scripts..."
-
+
###########
# Powershell script to launch org.apache.qpid.messaging.sln
#
@@ -493,8 +557,8 @@ if ($defined64) { -vsPlatform "x64" `
-nBits "64" `
-outfileName "start-devenv-messaging-x64-64bit.ps1"
-
-
+
+
###########
# Batch script (that you doubleclick) to launch powershell script
# that launches org.apache.qpid.messaging.sln.
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.receiver/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.receiver/Properties/AssemblyInfo.cs index abe35cf053..6976be5d02 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.receiver/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.receiver/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ * 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
@@ -23,7 +23,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("csharp.direct.receiver")]
@@ -31,12 +31,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.direct.receiver")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -46,11 +46,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.sender/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.sender/Properties/AssemblyInfo.cs index 18502a0666..12368def8e 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.sender/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.direct.sender/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ * 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
@@ -23,7 +23,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("csharp.direct.sender")]
@@ -31,12 +31,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.direct.sender")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -46,11 +46,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.receiver/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.receiver/Properties/AssemblyInfo.cs index a87f92ccdf..459130ec6c 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.receiver/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.receiver/Properties/AssemblyInfo.cs @@ -20,7 +20,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("csharp.map.callback.receiver")]
@@ -28,12 +28,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.map.callback.receiver")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -43,11 +43,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.sender/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.sender/Properties/AssemblyInfo.cs index e633f76673..2be4011f19 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.sender/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.callback.sender/Properties/AssemblyInfo.cs @@ -28,7 +28,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.map.callback.sender")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.receiver/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.receiver/Properties/AssemblyInfo.cs index 694d6b9ce1..f11ce8c220 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.receiver/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.receiver/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ * 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
@@ -23,7 +23,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("csharp.map.receiver")]
@@ -31,12 +31,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.map.receiver")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -46,11 +46,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.sender/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.sender/Properties/AssemblyInfo.cs index ea29ac2417..ee09057f18 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.sender/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/examples/csharp.map.sender/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ * 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
@@ -23,7 +23,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("csharp.map.sender")]
@@ -31,12 +31,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("csharp.map.sender")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -46,11 +46,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/dotnet/examples/visualbasic.example.client/MyProject/AssemblyInfo.vb b/qpid/cpp/bindings/qpid/dotnet/examples/visualbasic.example.client/MyProject/AssemblyInfo.vb index d0727fe9fa..469d6ed5cf 100644 --- a/qpid/cpp/bindings/qpid/dotnet/examples/visualbasic.example.client/MyProject/AssemblyInfo.vb +++ b/qpid/cpp/bindings/qpid/dotnet/examples/visualbasic.example.client/MyProject/AssemblyInfo.vb @@ -6,9 +6,9 @@ ' 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
@@ -21,34 +21,34 @@ Imports System Imports System.Reflection
Imports System.Runtime.InteropServices
-' General Information about an assembly is controlled through the following
+' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
' Review the values of the assembly attributes
-<Assembly: AssemblyTitle("visualbasic.example.client")>
-<Assembly: AssemblyDescription("")>
-<Assembly: AssemblyCompany("Microsoft")>
-<Assembly: AssemblyProduct("visualbasic.example.client")>
-<Assembly: AssemblyCopyright("Copyright © Microsoft 2010")>
-<Assembly: AssemblyTrademark("")>
+<Assembly: AssemblyTitle("visualbasic.example.client")>
+<Assembly: AssemblyDescription("")>
+<Assembly: AssemblyCompany("")>
+<Assembly: AssemblyProduct("visualbasic.example.client")>
+<Assembly: AssemblyCopyright("Copyright 2011")>
+<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'The following GUID is for the ID of the typelib if this project is exposed to COM
-<Assembly: Guid("ec9df8cf-c1d4-4938-9e72-93fb81d55700")>
+<Assembly: Guid("ec9df8cf-c1d4-4938-9e72-93fb81d55700")>
' Version information for an assembly consists of the following four values:
'
' Major Version
-' Minor Version
+' Minor Version
' Build Number
' Revision
'
-' You can specify all the values or you can default the Build and Revision Numbers
+' You can specify all the values or you can default the Build and Revision Numbers
' by using the '*' as shown below:
-' <Assembly: AssemblyVersion("1.0.*")>
+' <Assembly: AssemblyVersion("1.0.*")>
-<Assembly: AssemblyVersion("1.0.0.0")>
-<Assembly: AssemblyFileVersion("1.0.0.0")>
+<Assembly: AssemblyVersion("1.0.0.0")>
+<Assembly: AssemblyFileVersion("1.0.0.0")>
diff --git a/qpid/cpp/bindings/qpid/dotnet/org.apache.qpid.messaging.sessionreceiver.sln b/qpid/cpp/bindings/qpid/dotnet/org.apache.qpid.messaging.sessionreceiver.sln index 90e98a4bbe..edf8af4808 100644 --- a/qpid/cpp/bindings/qpid/dotnet/org.apache.qpid.messaging.sessionreceiver.sln +++ b/qpid/cpp/bindings/qpid/dotnet/org.apache.qpid.messaging.sessionreceiver.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
-#
+#
# 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
@@ -8,9 +8,9 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # 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
diff --git a/qpid/cpp/bindings/qpid/dotnet/test/messaging.test/Properties/AssemblyInfo.cs b/qpid/cpp/bindings/qpid/dotnet/test/messaging.test/Properties/AssemblyInfo.cs index cf50e88200..81a89ce393 100644 --- a/qpid/cpp/bindings/qpid/dotnet/test/messaging.test/Properties/AssemblyInfo.cs +++ b/qpid/cpp/bindings/qpid/dotnet/test/messaging.test/Properties/AssemblyInfo.cs @@ -7,9 +7,9 @@ * 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
@@ -23,7 +23,7 @@ using System.Reflection; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("messaging.test")]
@@ -31,12 +31,12 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("messaging.test")]
-[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
@@ -46,11 +46,11 @@ using System.Runtime.InteropServices; // Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/qpid/cpp/bindings/qpid/python/python.i b/qpid/cpp/bindings/qpid/python/python.i index bf61cb10b7..9d45bf54ee 100644 --- a/qpid/cpp/bindings/qpid/python/python.i +++ b/qpid/cpp/bindings/qpid/python/python.i @@ -21,21 +21,357 @@ %include "std_string.i" %include "../../swig_python_typemaps.i" +/* Needed for get/setPriority methods. Surprising SWIG 1.3.40 doesn't + * convert uint8_t by default. */ +%apply unsigned char { uint8_t }; + + +/* + * Exceptions + * + * The convention below is that exceptions in _cqpid.so have the same + * names as in the C++ library. They get renamed to their Python + * equivalents when brought into the Python wrapping + */ +%{ +static PyObject* pNoMessageAvailable; +static PyObject* pTargetCapacityExceeded; +static PyObject* pNotFound; +static PyObject* pTransportFailure; +%} + +%init %{ + pNoMessageAvailable = PyErr_NewException( + "_cqpid.NoMessageAvailable", NULL, NULL); + Py_INCREF(pNoMessageAvailable); + PyModule_AddObject(m, "NoMessageAvailable", pNoMessageAvailable); + + pTargetCapacityExceeded = PyErr_NewException( + "_cqpid.TargetCapacityExceeded", NULL, NULL); + Py_INCREF(pTargetCapacityExceeded); + PyModule_AddObject(m, "TargetCapacityExceeded", pTargetCapacityExceeded); + + pNotFound = PyErr_NewException( + "_cqpid.NotFound", NULL, NULL); + Py_INCREF(pNotFound); + PyModule_AddObject(m, "NotFound", pNotFound); + + pTransportFailure = PyErr_NewException( + "_cqpid.TransportFailure", NULL, NULL); + Py_INCREF(pTransportFailure); + PyModule_AddObject(m, "TransportFailure", pTransportFailure); +%} + +%pythoncode %{ + Empty = _cqpid.NoMessageAvailable + TargetCapacityExceeded = _cqpid.TargetCapacityExceeded + NotFound = _cqpid.NotFound + ConnectError = _cqpid.TransportFailure +%} + /* Define the general-purpose exception handling */ %exception { + PyObject * pExceptionType = NULL; std::string error; Py_BEGIN_ALLOW_THREADS; try { $action + } catch (qpid::messaging::NoMessageAvailable & ex) { + pExceptionType = pNoMessageAvailable; + error = ex.what(); + } catch (qpid::messaging::TargetCapacityExceeded & ex) { + pExceptionType = pTargetCapacityExceeded; + error = ex.what(); + } catch (qpid::messaging::NotFound & ex) { + pExceptionType = pNotFound; + error = ex.what(); + } catch (qpid::messaging::TransportFailure & ex) { + pExceptionType = pTransportFailure; + error = ex.what(); } catch (qpid::types::Exception& ex) { + pExceptionType = PyExc_RuntimeError; error = ex.what(); } Py_END_ALLOW_THREADS; if (!error.empty()) { - PyErr_SetString(PyExc_RuntimeError, error.c_str()); + PyErr_SetString(pExceptionType, error.c_str()); return NULL; } } + +/* This only renames the non-const version (I believe). Then again, I + * don't even know why there is a non-const version of the method. */ +%rename(opened) qpid::messaging::Connection::isOpen(); +%rename(receiver) qpid::messaging::Session::createReceiver; +%rename(sender) qpid::messaging::Session::createSender; +%rename(_acknowledge_all) qpid::messaging::Session::acknowledge(bool); +%rename(_acknowledge_msg) qpid::messaging::Session::acknowledge( + Message &, bool); + +%rename(_fetch) qpid::messaging::Receiver::fetch; +%rename(unsettled) qpid::messaging::Receiver::getUnsettled; +%rename(available) qpid::messaging::Receiver::getAvailable; + +%rename(unsettled) qpid::messaging::Sender::getUnsettled; +%rename(available) qpid::messaging::Sender::getAvailable; +%rename(_send) qpid::messaging::Sender::send; + +%rename(_getReplyTo) qpid::messaging::Message::getReplyTo; +%rename(_setReplyTo) qpid::messaging::Message::setReplyTo; +%rename(_getTtl) qpid::messaging::Message::getTtl; +%rename(_setTtl) qpid::messaging::Message::setTtl; + + %include "../qpid.i" +%extend qpid::messaging::Connection { + %pythoncode %{ + # Handle the different options by converting underscores to hyphens. + # Also, the sasl_mechanisms option in Python has no direct + # equivalent in C++, so we will translate them to sasl_mechanism + # when possible. + def __init__(self, url=None, **options): + args = [url] if url else [] + if options : + if "sasl_mechanisms" in options : + if ' ' in options.get("sasl_mechanisms",'') : + raise Exception( + "C++ Connection objects are unable to handle " + "multiple sasl-mechanisms") + options["sasl_mechanism"] = options.pop("sasl_mechanisms") + args.append(options) + this = _cqpid.new_Connection(*args) + try: self.this.append(this) + except: self.this = this + %} + + /* Return a pre-existing session with the given name, if one + * exists, otherwise return a new one. (Note that if a + * pre-existing session exists, the transactional argument is + * ignored, and the returned session might not satisfy the desired + * setting. */ + qpid::messaging::Session _session(const std::string & name, + bool transactional) { + if (!name.empty()) { + try { + return self->getSession(name); + } + catch (const qpid::messaging::KeyError &) { + } + } + if (transactional) { + return self->createTransactionalSession(name); + } + else { + return self->createSession(name); + } + } + + %pythoncode %{ + def session(self, name=None, transactional=False) : + if name is None : + name = '' + return self._session(name, transactional) + %} + + %pythoncode %{ + @staticmethod + def establish(url=None, **options) : + conn = Connection(url, **options) + conn.open() + return conn + %} +} + +%extend qpid::messaging::Session { + %pythoncode %{ + def acknowledge(self, message=None, disposition=None, sync=True) : + if disposition : + raise Exception("SWIG does not support dispositions yet. Use " + "Session.reject and Session.release instead") + if message : + self._acknowledge_msg(message, sync) + else : + self._acknowledge_all(sync) + + __swig_getmethods__["connection"] = getConnection + if _newclass: connection = _swig_property(getConnection) + %} +} + + +%extend qpid::messaging::Receiver { + %pythoncode %{ + __swig_getmethods__["capacity"] = getCapacity + __swig_setmethods__["capacity"] = setCapacity + if _newclass: capacity = _swig_property(getCapacity, setCapacity) + + __swig_getmethods__["session"] = getSession + if _newclass: session = _swig_property(getSession) + %} + + %pythoncode %{ + def fetch(self, timeout=None) : + if timeout is None : + return self._fetch() + else : + # Python API uses timeouts in seconds, + # but C++ API uses milliseconds + return self._fetch(Duration(int(1000*timeout))) + %} +} + +%extend qpid::messaging::Sender { + %pythoncode %{ + def send(self, object, sync=True) : + if isinstance(object, Message): + message = object + else: + message = Message(object) + return self._send(message, sync) + + __swig_getmethods__["capacity"] = getCapacity + __swig_setmethods__["capacity"] = setCapacity + if _newclass: capacity = _swig_property(getCapacity, setCapacity) + + __swig_getmethods__["session"] = getSession + if _newclass: session = _swig_property(getSession) + %} +} + + +%extend qpid::messaging::Message { + %pythoncode %{ + # UNSPECIFIED was module level before, but I do not + # know how to insert python code at the top of the module. + # (A bare "%pythoncode" inserts at the end. + UNSPECIFIED=object() + def __init__(self, content=None, content_type=UNSPECIFIED, id=None, + subject=None, user_id=None, reply_to=None, + correlation_id=None, durable=None, priority=None, + ttl=None, properties=None): + this = _cqpid.new_Message('') + try: self.this.append(this) + except: self.this = this + if content : + self.content = content + if content_type != UNSPECIFIED : + self.content_type = content_type + if id is not None : + self.id = id + if subject is not None : + self.subject = subject + if user_id is not None : + self.user_id = user_id + if reply_to is not None : + self.reply_to = reply_to + if correlation_id is not None : + self.correlation_id = correlation_id + if durable is not None : + self.durable = durable + if priority is not None : + self.priority = priority + if ttl is not None : + self.ttl = ttl + if properties is not None : + # Can't set properties via (inst).getProperties, because + # the typemaps make a copy of the underlying properties. + # Instead, set via setProperty for the time-being + for k, v in properties.iteritems() : + self.setProperty(k, v) + + def _get_content(self) : + if self.content_type == "amqp/list" : + return decodeList(self) + if self.content_type == "amqp/map" : + return decodeMap(self) + return self.getContent() + def _set_content(self, content) : + if isinstance(content, basestring) : + self.setContent(content) + elif isinstance(content, list) or isinstance(content, dict) : + encode(content, self) + else : + # Not a type we can handle. Try setting it anyway, + # although this will probably lead to a swig error + self.setContent(content) + __swig_getmethods__["content"] = _get_content + __swig_setmethods__["content"] = _set_content + if _newclass: content = _swig_property(_get_content, _set_content) + + __swig_getmethods__["content_type"] = getContentType + __swig_setmethods__["content_type"] = setContentType + if _newclass: content_type = _swig_property(getContentType, + setContentType) + + __swig_getmethods__["id"] = getMessageId + __swig_setmethods__["id"] = setMessageId + if _newclass: id = _swig_property(getMessageId, setMessageId) + + __swig_getmethods__["subject"] = getSubject + __swig_setmethods__["subject"] = setSubject + if _newclass: subject = _swig_property(getSubject, setSubject) + + __swig_getmethods__["priority"] = getPriority + __swig_setmethods__["priority"] = setPriority + if _newclass: priority = _swig_property(getPriority, setPriority) + + def getTtl(self) : + return self._getTtl().getMilliseconds()/1000.0 + def setTtl(self, duration) : + self._setTtl(Duration(int(1000*duration))) + __swig_getmethods__["ttl"] = getTtl + __swig_setmethods__["ttl"] = setTtl + if _newclass: ttl = _swig_property(getTtl, setTtl) + + __swig_getmethods__["user_id"] = getUserId + __swig_setmethods__["user_id"] = setUserId + if _newclass: user_id = _swig_property(getUserId, setUserId) + + __swig_getmethods__["correlation_id"] = getCorrelationId + __swig_setmethods__["correlation_id"] = setCorrelationId + if _newclass: correlation_id = _swig_property(getCorrelationId, + setCorrelationId) + + __swig_getmethods__["redelivered"] = getRedelivered + __swig_setmethods__["redelivered"] = setRedelivered + if _newclass: redelivered = _swig_property(getRedelivered, + setRedelivered) + + __swig_getmethods__["durable"] = getDurable + __swig_setmethods__["durable"] = setDurable + if _newclass: durable = _swig_property(getDurable, setDurable) + + __swig_getmethods__["properties"] = getProperties + if _newclass: properties = _swig_property(getProperties) + + def getReplyTo(self) : + return self._getReplyTo().str() + def setReplyTo(self, address_str) : + self._setReplyTo(Address(address_str)) + __swig_getmethods__["reply_to"] = getReplyTo + __swig_setmethods__["reply_to"] = setReplyTo + if _newclass: reply_to = _swig_property(getReplyTo, setReplyTo) + + def __repr__(self): + args = [] + for name in ["id", "subject", "user_id", "reply_to", + "correlation_id", "priority", "ttl", + "durable", "redelivered", "properties", + "content_type"] : + value = getattr(self, name) + if value : args.append("%s=%r" % (name, value)) + if self.content is not None: + if args: + args.append("content=%r" % self.content) + else: + args.append(repr(self.content)) + return "Message(%s)" % ", ".join(args) + %} +} + +%pythoncode %{ +# Bring into module scope +UNSPECIFIED = Message.UNSPECIFIED +%} diff --git a/qpid/cpp/bindings/qpid/ruby/README.rdoc b/qpid/cpp/bindings/qpid/ruby/README.rdoc new file mode 100644 index 0000000000..960fdf6107 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/README.rdoc @@ -0,0 +1,27 @@ += Qpid - Open Source AMQP Messaging + +Qpid is an cross-platform enterprise messaging system. + +Version :: 0.10.0.alpha.0 + += Links + +Documents :: http://qpid.apache.org/ + += Installation + +You can install Qpid with the following command. + + $ gem install qpid + +== Examples + +Take a look at the integration tests for examples on how to leverage +the messaging capabilities of Qpid in your Ruby applications. + +== License + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor licensing agreements. + + diff --git a/qpid/cpp/bindings/qpid/ruby/Rakefile b/qpid/cpp/bindings/qpid/ruby/Rakefile new file mode 100644 index 0000000000..ef2b158eba --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/Rakefile @@ -0,0 +1,74 @@ +# 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 + +require 'rubygems' +require 'rake/clean' +require 'rake/rdoctask' +require 'rake/testtask' + +CLOBBER.include('pkg') + +load './lib/qpid/version.rb' + +desc 'Default: run all tests.' +task :default => :'test:all' + +#--------------- +# Testing tasks. +#--------------- + +desc 'Run all tests (alias for test:all).' +task :test => :'test:all' + +namespace :test do + desc "Run all tests (default)." + task :all => [:units, :integrations] + + desc "Run unit tests." + Rake::TestTask.new(:units) do |t| + t.libs << '.' + t.pattern = 'test/test*.rb' + t.verbose = true + end + + desc "Run integration tests." + Rake::TestTask.new(:integrations) do |t| + t.libs << '.' + t.pattern = 'test/integration/*.rb' + t.verbose = true + 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 diff --git a/qpid/cpp/bindings/qpid/ruby/examples/client.rb b/qpid/cpp/bindings/qpid/ruby/examples/client.rb new file mode 100644 index 0000000000..f42f25cfc9 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/client.rb @@ -0,0 +1,50 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +if __FILE__ == $0 + broker = ARGV[1] || "amqp:tcp:localhost:5672" + options = ARGV[2] || "" + + connection = Qpid::Messaging::Connection.new broker, options + connection.open + session = connection.create_session + sender = session.create_sender "service_queue" + response_queue = Qpid::Messaging::Address.new("#response-queue", "", + :create => :always, + :delete => :always) + receiver = session.create_receiver response_queue + + ["Twas brillig, and the slithy toves", + "Did gire and gymble in the wabe.", + "All mimsy were the borogroves,", + "And the mome raths outgrabe."].each do |line| + request = Qpid::Messaging::Message.new :content => line + request.reply_to = response_queue + sender.send request + response = receiver.fetch + puts "#{request.content} -> #{response.content}" + end + + connection.close +end + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/drain.rb b/qpid/cpp/bindings/qpid/ruby/examples/drain.rb new file mode 100644 index 0000000000..a6cf35e189 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/drain.rb @@ -0,0 +1,111 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' +require 'optparse' + +options = { + :broker => "localhost", + :timeout => Qpid::Messaging::Duration::IMMEDIATE, + :count => 1, + :forever => false, + :connection_options => "" +} + +opts = OptionParser.new do |opts| + opts.banner = "Usage: drain.rb [OPTIONS] ADDRESS" + + opts.separator "" + opts.separator "Drains messages from the specified address" + opts.separator "" + + opts.on("-h", "--help", + "show this message") do + puts opts + exit + end + + opts.on("-b", "--broker VALUE", + "url of broker to connect to") do |broker| + options[:broker] = broker + end + + opts.on("-t", "--timeout VALUE", Integer, + "timeout in seconds to wait before exiting") do |timeout| + options[:timeout] = Qpid::Messaging::Duration.new timeout * 1000 + end + + opts.on("-f", "--forever", + "ignore timeout and wait forever") do + options[:forever] = true + end + + opts.on("--connection-options VALUE", + "connection options string in the form {name1:value,name2:value2}") do |conopts| + options[:connection_options] = conopts + end + + opts.on("-c", "--count VALUE", Integer, + "number of messages to read before exiting") do |count| + options[:count] = count + end +end + +opts.parse!(ARGV) + +options[:address] = ARGV[0] || "" + +connection = Qpid::Messaging::Connection.new options[:broker], options[:connection_options] +connection.open + +def render_map map + print "{" + map.keys.sort.each_with_index {|key,index| print "#{index > 0 ? ', ' : ''}#{key}:#{map[key]}"} + print "}" +end + +begin + session = connection.create_session + receiver = session.create_receiver options[:address] + done = false + count = 0 + options[:timeout] = Qpid::Messaging::Duration::FOREVER if options[:forever] + + while !done && (count < options[:count]) + message = receiver.fetch(options[:timeout]) + print "Message(properties=" + render_map message.properties + print ", content=" + if message.content_type == "amqp/map" + print "'#{render_map message.content}')" + else + print "'#{message.content}'" + end + print ")\n" + session.acknowledge message + count += 1 + end +rescue Exception => error + puts "Exception: #{error.to_s}" +end + +connection.close + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/hello_world.rb b/qpid/cpp/bindings/qpid/ruby/examples/hello_world.rb new file mode 100644 index 0000000000..703febeba1 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/hello_world.rb @@ -0,0 +1,49 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +# This is your classic Hello World application, written in +# Ruby, that uses Qpid. It demonstrates how to send and +# also receive messages. +# +if __FILE__ == $0 + broker = ARGV[0] || "localhost:5672" + address = ARGV[1] || "amq.topic" + options = ARGV[2] || "" + + connection = Qpid::Messaging::Connection.new broker + connection.open + session = connection.create_session + receiver = session.create_receiver address + sender = session.create_sender address + + # Send a simple message + sender.send Qpid::Messaging::Message.new :content => "Hello world!" + + # Now receive the message + message = receiver.fetch Qpid::Messaging::Duration::SECOND + puts "#{message.content}" + session.acknowledge + + connection.close +end + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/map_receiver.rb b/qpid/cpp/bindings/qpid/ruby/examples/map_receiver.rb new file mode 100644 index 0000000000..805943a0a4 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/map_receiver.rb @@ -0,0 +1,63 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +broker = ARGV[0] || "amqp:tcp:127.0.0.1:5672" +address = ARGV[1] || "message_queue; {create: always}" +options = ARGV[2] || "" + +connection = Qpid::Messaging::Connection.new broker, options +connection.open + +def display_value value + case value + when Array + result = "" + value.each_with_index {|element, index| result += "#{', ' if index > 0}#{element}"} + return "[#{result}]" + end + + value.to_s +end + +begin + session = connection.create_session + receiver = session.create_receiver address + + message = receiver.fetch + content = message.content + + print "content-type:#{message.content_type}" + print "{" + content.keys.sort.each_with_index do |key, index| + print "#{', ' if index > 0}#{key}:#{display_value content[key]}" + end + print "}\n" + + session.acknowledge + +rescue Exception => error + puts "Exception: #{error.message}" +end + +connection.close + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/map_sender.rb b/qpid/cpp/bindings/qpid/ruby/examples/map_sender.rb new file mode 100644 index 0000000000..fa0c6e4562 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/map_sender.rb @@ -0,0 +1,52 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +broker = ARGV[0] || "amqp:tcp:127.0.0.1:5672" +address = ARGV[1] || "message_queue; {create: always}" +options = ARGV[2] || [] + +connection = Qpid::Messaging::Connection.new broker, options +connection.open + +begin + session = connection.create_session + sender = session.create_sender address + message = Qpid::Messaging::Message.new + + content = { + :id => 987654321, + :name => "Widget", + :percent => 0.99, + :colors => ["red", "green", "blue"] + } + + message.content = content + + sender.send message + +rescue Exception => error + puts "Exception: #{error.message}" +end + +connection.close + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/server.rb b/qpid/cpp/bindings/qpid/ruby/examples/server.rb new file mode 100644 index 0000000000..ead9d58472 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/server.rb @@ -0,0 +1,51 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +if __FILE__ == $0 + broker = ARGV[0] || "amqp:tcp:localhost:5672" + options = ARGV[1] || "" + + connection = Qpid::Messaging::Connection.new broker, options + connection.open + session = connection.create_session + receiver = session.create_receiver "service_queue; {create:always}" + + loop do + request = receiver.fetch + address = request.reply_to + + if !address.nil? + sender = session.create_sender address + response = Qpid::Messaging::Message.new :content => request.content.upcase + sender.send response + puts "Processed request: #{request.content} -> #{response.content}" + session.acknowledge + else + puts "Error: no reply address specified for request: #{request.content}" + session.reject request + end + end + + connection.close +end + diff --git a/qpid/cpp/bindings/qpid/ruby/examples/spout.rb b/qpid/cpp/bindings/qpid/ruby/examples/spout.rb new file mode 100644 index 0000000000..c012e31f9d --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/examples/spout.rb @@ -0,0 +1,126 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' +require 'optparse' + +options = { + :broker => "127.0.0.1", + :address => "", + :timeout => 0, + :count => 1, + :properties => {}, + :content => nil, + :mapped => {} +} + +opts = OptionParser.new do |opts| + opts.banner = "Usage: spout.rb [OPTIONS] ADDRESS" + + opts.on("-h", "--help", + "show this message") do |help| + puts opts + exit + end + + opts.on("-b","--broker VALUE", + "url of broker to connect to ") do |broker| + options[:broker] = broker + end + + opts.on("-t", "--timeout VALUE", Integer, + "exit after the specified time") do |timeout| + options[:timeout] = Qpid::Messaging::Duration.new timeout * 1000 + end + + opts.on("-c", "--count VALUE", Integer, + "stop after count messages have been sent, zero disables") do |count| + options[:count] = count + end + + opts.on("-i", "--id VALUE", + "use the supplied id instead of generating one") do |id| + options[:id] = id + end + + opts.on("--reply-to VALUE", + "specify reply-to address") do |replyto| + options[:replyto] = replyto + end + + opts.on("-P", "--property VALUE", + "specify message property") do |property| + name = property.split(/=/)[0] + value = property.split(/=/)[1] + options[:properties][name] = value + end + + opts.on("-M", "--map VALUE", + "specify entry for map content") do |mapped| + name = mapped.split(/=/)[0] + value = mapped.split(/=/)[1] + options[:mapped][name] = value + end + + opts.on("--content VALUE", + "specify textual content") do |content| + options[:content] = content + end + + opts.on(nil, "--connection-options VALUE", + "connection options string in the form {name1:value1, name2:value2}") do |conopts| + options[:connection_options] = conopts + end +end + +begin + opts.parse!(ARGV) +rescue => error + opts.parse(["-h"]) +end + +# now get the non-arg options +options[:address] = ARGV[0] unless ARGV[0].nil? + +connection = Qpid::Messaging::Connection.new options[:broker], options[:connection_options] +connection.open +session = connection.create_session +sender = session.create_sender options[:address] +message = Qpid::Messaging::Message.new + +options[:properties].each_key {|key| message.properties[key] = options[:properties][key]} + +(1..options[:count]).each do |count| + if !options[:mapped].keys.empty? + message.content = options[:mapped] + elsif options[:content] + message.content = options[:content] + end + message.content = options[:content] unless options[:content].nil? + message.properties["spout-id"] = "#{count}" + message.reply_to = options[:replyto] unless options[:replyto].nil? || options[:replyto].empty? + sender.send message +end + +# session.sync + +connection.close + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb new file mode 100644 index 0000000000..1f00c136c1 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb @@ -0,0 +1,29 @@ +# +# 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/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb new file mode 100644 index 0000000000..73b61bb1c7 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb @@ -0,0 +1,125 @@ +# +# 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 + + # 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: + # + # <address> [ / <subject> ] ; [ { <key> : <value> , ... } ] + # + # where *address* is a simple name and *subject* is a subject or subject + # pattern. + # + # 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 + + def initialize(name, subject, options = {}, _type = "", address_impl = nil) + @address_impl = address_impl || Cqpid::Address.new(name, subject, convert_options(options), _type) + end + + def address_impl # :nodoc: + @address_impl + end + + # Returns the name. + def name; @address_impl.getName; end + + # Sets the name. + def name=(name); @address_impl.setName name; end + + # Returns the subject. + def subject; @address_impl.getSubject; end + + # Sets the subject. + def subject=(subject); @address_impl.setSubject(subject); end + + # Returns the type. + #--- + # We cannot use "type" since that clashes with the Ruby object.type + # identifier. + def _type; @address_impl.getType; end + + # Sets the type. + # + # 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. + def _type=(_type); @address_impl.setType(_type); end + + # Returns the options. + def options; @address_impl.getOptions; end + + # Sets the options for the address. + # Any symbols are converted to strings. + def options=(options); @address_impl.setOptions(convert_options(options)); end + + def to_s; @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/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb new file mode 100644 index 0000000000..5c56c1f5d0 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb @@ -0,0 +1,134 @@ +# +# 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 + + # Connection allows for establishing connections to a remote endpoint. + class Connection + + # The following general options are supported (as strings or symbols): + # + # username:: + # password:: + # heartbeat:: + # tcp_nodelay:: + # sasl_mechanism:: + # sasl_service:: + # sasl_min_ssf:: + # sasl_max_ssf:: + # transport:: + # + # The following options specifically control reconnection behavior: + # + # reconnect:: *true* or *false*; 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 reconnecting + # reconnect_interval_max:: number of seconds to wait before additional reconnect attempts + # reconnect_interval:: shorthand for setting box min and max values + # reconnect_urls:: a list of alternate URLs to use for reconnection attempts + def initialize(url, options = {}, connection_impl = nil) + @url = url + @connection_impl = connection_impl + @options = options + end + + def connection_impl # :nodoc: + @connection_impl + end + + # Opens the connection. + def open + @connection_impl = Cqpid::Connection.new(@url, convert_options) + @connection_impl.open + end + + # Reports whether the connection is open. + def open?; false || (@connection_impl.isOpen if @connection_impl); end + + # Closes the connection. + def close; @connection_impl.close if open?; end + + # Creates a new session. + # + # If :transactional => true then a transactional session is created. + # Otherwise a standard session is created. + 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(session) + else + raise RuntimeError.new "No connection available." + end + end + + # Returns a session for the specified session name. + def session name + session_impl = @connection_impl.getSession name + Qpid::Messaging::Session.new session_impl if session_impl + end + + # Returns the username used to authenticate with the connection. + def authenticated_username; @connection_impl.getAuthenticatedUsername if open?; end + + # inherited from Handle + + # Returns whether the underlying handle is valid; i.e., not null. + def valid? + @connection_impl.isValid + end + + # Returns whether the underlying handle is null. + def null? + @connection_impl.isNull + end + + # Swaps the underlying connection handle. + def swap connection + @connection_impl.swap connection.connection_impl + end + + private + + def convert_options + result = {} + # map only those options defined in the C++ layer + # TODO when new options are added, this needs to be updated. + 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/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb new file mode 100644 index 0000000000..c1f44e9281 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb @@ -0,0 +1,63 @@ +# +# 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 + + # A Duration represents a period of time in milliseconds + # + # It defines the following named values as symbols: + # + # :FOREVER :: the maximum integer value for the platform + # :IMMEDIATE :: an alias for 0 + # :SECOND :: 1,000ms + # :MINUTE :: 60,000ms + class Duration + + def initialize duration # :nodoc: + @duration_impl = Cqpid::Duration.new duration + end + + def duration_impl # :nodoc: + @duration_impl + 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/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb new file mode 100644 index 0000000000..c8b843b597 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb @@ -0,0 +1,56 @@ +# +# 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 + + # 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 + end + + # Decodes and returns the message's content. + def self.decode(message, content_type = nil) + content_type = message.content_type unless content_type + + case content_type + when "amqp/map": Cqpid.decodeMap message.message_impl + when "amqp/list": Cqpid.decodeList message.message_impl + end + end + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb new file mode 100644 index 0000000000..7a16d08d84 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb @@ -0,0 +1,30 @@ +# +# 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 + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb new file mode 100644 index 0000000000..9b1b68c7c3 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb @@ -0,0 +1,157 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +require 'cqpid' + +module Qpid + + module Messaging + + # Message represents a message. + class Message + + def initialize(args = {}, message_impl = nil) + @message_impl = message_impl + @message_impl = Cqpid::Message.new if @message_impl.nil? + @message_impl.setContent args[:content].to_s if args[:content] + @content = nil + end + + def message_impl # :nodoc: + @message_impl + end + + # Assigns the reply to address. + # The address must be an instance of Address. + def reply_to=(address); @message_impl.setReplyTo address.address_impl; end + + # Returns the reply to address for the message as an instance of +Address+. + 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 + end + + # Sets the subject. + def subject=(subject); @message_impl.setSubject subject; end + + # Returns the subject. + def subject; @message_impl.getSubject; end + + # Sets the content type. + def content_type=(content_type); @message_impl.setContentType content_type; end + + # Returns the content type. + def content_type; @message_impl.getContentType; end + + # Sets the message id. + 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. + def user_id=(user_id); @message_impl.setUserId user_id; end + + # Returns the user id. + def user_id; @message_impl.getUserId; end + + # Sets the correlation id. + def correlation_id=(correlation_id); @message_impl.setCorrelationId correlation_id; end + + # Returns the correlation id. + def correlation_id; @message_impl.getCorrelationId; end + + # Sets the priority. + def priority=(priority); @message_impl.setPriority priority; end + + # Returns the priority. + def priority; @message_impl.getPriority; end + + # Sets the time-to-live in milliseconds. + def ttl=(duration); @message_impl.setTtl duration; end + + # Returns the time-to-live in milliseconds. + def ttl; @message_impl.getTtl; end + + # Sets the durability. + def durable=(durable); @message_impl.setDurable durable; end + + # Returns the durability. + def durable; @message_impl.getDurable; end + + # Allows marking the message as redelivered. + def redelivered=(redelivered); @message_impl.setRedelivered redelivered; end + + # Returns if the message was redelivered. + def redelivered; @message_impl.getRedelivered; end + + # Returns all named properties. + # *NOTE:* It is recommended to use the +foo[key]+ method for + # retrieving properties. + def properties; @message_impl.getProperties; end + + # Returns the value for the named property. + def [](key); self.properties[key.to_s]; end + + # Assigns a value to the named property. + def []=(key, value); @message_impl.setProperty(key.to_s, value.to_s); end + + # Sets the content. + def content=(content) + content_type = nil + @content = 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. + 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. + def content_size; @message_impl.getContentSize; end + + end + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb new file mode 100644 index 0000000000..d498aa922b --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb @@ -0,0 +1,102 @@ +# +# 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/duration' + +module Qpid + + module Messaging + + # Receiver defines a type for receiving messages. + class Receiver + + def initialize(receiver_impl) # :nodoc: + @receiver_impl = receiver_impl + end + + def receiver_impl # :nodoc: + @receiver_impl + end + + # Retrieves a message from the receiver's local queue, or waits + # for up to the duration specified for one to become available. + 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. + 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 for a receiver determines the number of messages that + # can be held in the receiver before being fetched. + def capacity=(capacity); @receiver_impl.setCapacity capacity; end + + # Returns the capacity. + def capacity; @receiver_impl.getCapacity; end + + # Returns the number of available messages waiting to be fetched. + 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 + + # Cancels the reciever. + def close; @receiver_impl.close; end + + # Returns whether the receiver is closed. + def closed?; @receiver_impl.isClosed; end + + # Returns the name of the receiver + def name; @receiver_impl.getName; end + + # Returns the Session for this receiver. + def session; Qpid::Messaging::Session.new(@receiver_impl.getSession); end + + # Returns whether the underlying handle is valid. + def valid?; @receiver_impl.isValid; end + + # Returns whether the underlying handle is null. + def null?; @receiver_impl.isNull; end + + def swap receiver + @receiver_impl.swap receiver.receiver_impl + end + + private + + def create_message_wrapper message_impl + Qpid::Messaging::Message.new({}, message_impl) + end + + end + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb new file mode 100644 index 0000000000..5d59c20d7e --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.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. +# + +module Qpid + + module Messaging + + # Sender defines a type for sending messages. + class Sender + + def initialize(sender_impl) # :nodoc: + @sender_impl = sender_impl + end + + def sender_impl # :nodoc: + @sender_impl + end + + # Sends a message. + def send(message, args = {}) + block = args[:block] || false + @sender_impl.send message.message_impl, block + end + + # Closes the sender. + def close; @sender_impl.close; end + + # Returns the name for the sender. + def name; @sender_impl.getName; end + + # Sets the capacity for the sender, which is the number of outgoing + # messages that can be held pending confirmation or receipt by + # the broker. + 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 capacity for sending messages. + def available + @sender_impl.getAvailable + end + + # Returns the Session for this sender. + def session; Qpid::Messaging::Session.new @sender_impl.getSession; end + + # Returns if the underlying sender is valid. + def valid?; @sender_impl.isValid; end + + # Returns if the underlying sender is null. + def null?; @sender_impl.isNull; end + + def swap sender + @sender_impl.swap sender.sender_impl + end + + end + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb new file mode 100644 index 0000000000..543c26cc70 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb @@ -0,0 +1,186 @@ +# +# 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/errors' + +module Qpid + + module Messaging + + # A Session represents a distinct conversation between end points. + class Session + + def initialize(session) # :nodoc: + @session_impl = session + end + + def session_impl # :nodoc: + @session_impl + end + + # Returns the +Connection+ for the +Session+. + def connection + connection_impl = @session_impl.getConnection + Qpid::Messaging::Connection.new "", {}, connection_impl + end + + # Creates a new endpoint for sending messages. + def create_sender(address) + _address = address + + if address.class == Qpid::Messaging::Address + _address = address.address_impl + end + + Qpid::Messaging::Sender.new(@session_impl.createSender(_address)) + end + + # Retrieves the +Sender+ with the specified name. + def sender(name) + result = nil + + begin + sender_impl = @session_impl.getSender name + result = Sender.for_impl sender_impl + rescue + # treat any error as a key error + end + + raise Qpid::Messaging::KeyError, "No such sender: #{name}" if result.nil? + result + end + + # Retrieves the +Receiver+ with the specified name. + def receiver(name) + result = nil + + begin + receiver_impl = @session_impl.getReceiver name + result = Receiver.for_impl receiver_impl + rescue + # treat any error as a key error + end + + raise Qpid::Messaging::KeyError, "No such receiver: #{name}" if result.nil? + result + end + + # Creates a new endpoint for receiving messages. + def create_receiver(address) + result = nil + + if address.class == Qpid::Messaging::Address + address_impl = address.address_impl + result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address_impl)) + else + result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address)) + end + + return result + end + + # Closes the Session and all associated Senders and Receivers. + # All Sessions are closed when the associated Connection is closed. + 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. + # + # If a message is submitted (:message => something_message) then only + # that message is acknowledged. Otherwise all messsages are acknowledged. + # + # If :sync => true then the call will block until the server completes + # processing the acknowledgements. + # If :sync => true then the call will block until processed by the server (def. false) + def acknowledge(args = {}) + sync = args[:sync] || false + message = args[:message] if args[: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 server. + # + # If :block => true then the call will block until the server acknowledges. + # + # If :block => false (default) then the call will complete and the server + # will send notification on completion. + def sync(args = {}) + block = args[:block] || false + @session_impl.sync block + end + + # Returns the total number of receivable messages, and messages already received, + # by Receivers 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. + def unsettled_acks; @session_impl.getUnsettledAcks; end + + # Fetches the receiver for the next message. + def next_receiver(timeout = Qpid::Messaging::Duration::FOREVER) + receiver_impl = @session_impl.nextReceiver(timeout.duration_impl) + Qpid::Messaging::Receiver.new receiver_impl + end + + # Returns whether there are errors on this session. + def error?; @session_impl.hasError; end + + def check_error; @session_impl.checkError; end + + # Returns if the underlying session is valid. + def valid?; @session_impl.isValid; end + + # Returns if the underlying session is null. + def null?; @session_impl.isNull; end + + def swap session + @session_impl.swap session.session_impl + end + + end + + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb new file mode 100644 index 0000000000..a791b1638c --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb @@ -0,0 +1,31 @@ +# +# 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 = 10, + BUILD = 0] + end + + VERSION = Version::NUMBERS.join('.') + +end diff --git a/qpid/cpp/bindings/qpid/ruby/test/lib/setup.rb b/qpid/cpp/bindings/qpid/ruby/test/lib/setup.rb new file mode 100644 index 0000000000..c4901ed907 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/lib/setup.rb @@ -0,0 +1,29 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'qpid' + +def create_session url, session_name + conn = Qpid::Messaging::Connection.new url + conn.open + conn.create_session session_name +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_address.rb b/qpid/cpp/bindings/qpid/ruby/test/test_address.rb new file mode 100644 index 0000000000..f54e93aa3d --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_address.rb @@ -0,0 +1,39 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'cqpid' +require 'qpid/address' + +class TestAddress < Test::Unit::TestCase + + def test_constructor + result = Qpid::Messaging::Address.new "name", "subject", {:foo => :bar}, "type" + + assert_equal "name", result.name + assert_equal "subject", result.subject + assert_equal "type", result._type + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb b/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb new file mode 100644 index 0000000000..648fb0588a --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb @@ -0,0 +1,257 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'cqpid' +require 'qpid/connection' + +class TestConnection < Test::Unit::TestCase + + def setup + @connection_impl = flexmock("connection_impl") + @other_connection = flexmock("other_connection") + @other_connection_impl = flexmock("other_connection_impl") + @cqpid_connection = flexmock(Cqpid::Connection) + + @session = flexmock("session") + @session_name = "test-session" + + @url = "localhost" + @options = {} + + @connection = Qpid::Messaging::Connection.new(@url, @options, @connection_impl) + end + + def test_create_with_username_and_password + @cqpid_connection. + should_receive(:new). + once.with("localhost", + {"username" => "username", + "password" => "password"}). + and_return(@connection_impl) + @connection_impl. + should_receive(:open). + once + + result = Qpid::Messaging::Connection.new("localhost", + :username => "username", + :password => "password") + result.open + + assert_same @connection_impl, result.connection_impl + end + + def test_create_with_hostname + result = Qpid::Messaging::Connection.new("localhost") + + assert_not_nil result + end + + def test_open + @cqpid_connection. + should_receive(:new). + once. + with(@url, {}). + and_return(@connection_impl) + @connection_impl. + should_receive(:open). + once + + @connection.open + + assert_same @connection_impl, @connection.connection_impl + end + + def test_check_open_when_open + @connection_impl. + should_receive(:isOpen). + once. + and_return(true) + + assert @connection.open? + end + + def test_check_open_before_connection + result = Qpid::Messaging::Connection.new("hostname") + + assert !result.open? + end + + def test_check_open_when_closed + @connection_impl. + should_receive(:isOpen). + once. + and_return(false) + + assert !@connection.open? + end + + def test_close_an_unopened_session + @connection_impl. + should_receive(:isOpen). + once. + and_return(false) + + @connection.close + end + + def test_close + @connection_impl. + should_receive(:isOpen). + once. + and_return(true). + should_receive(:close). + once + + @connection.close + end + + def test_create_session_without_name + @connection_impl. + should_receive(:isOpen). + once. + and_return(true). + should_receive(:createSession). + once. + with(""). + and_return(@session) + + result = @connection.create_session + + assert_not_nil result + assert_same @session, result.session_impl + end + + def test_create_session + @connection_impl. + should_receive(:isOpen). + once. + and_return(true). + should_receive(:createSession). + once. + with(@session_name). + and_return(@session) + + result = @connection.create_session :name => @session_name + + assert_not_nil result + assert_same @session, result.session_impl + end + + def test_create_session_raises_exception_when_closed + @connection_impl. + should_receive(:isOpen). + once. + and_return(false) + + assert_raise(RuntimeError) {@connection.create_session @session_name} + end + + def test_create_transactional_session + @connection_impl. + should_receive(:isOpen). + once. + and_return(true). + should_receive(:createTransactionalSession). + once. + with(""). + and_return(@session) + + result = @connection.create_session :transactional => true + + assert_not_nil result + assert_same @session, result.session_impl + end + + def test_authenticated_username_when_not_connected + @connection_impl. + should_receive(:isOpen). + once. + and_return(false) + + result = @connection.authenticated_username + + assert_nil result + end + + def test_authenticated_username + @connection_impl. + should_receive(:isOpen). + once. + and_return(true). + should_receive(:getAuthenticatedUsername). + once. + and_return("farkle") + + result = @connection.authenticated_username + + assert_equal "farkle", result + end + + def test_get_session_with_invalid_name + @connection_impl. + should_receive(:getSession). + once. + with(@session_name). + and_return(nil) + + result = @connection.session @session_name + + assert_nil result + end + + # APIs inherited from Handle + + def test_is_valid + @connection_impl. + should_receive(:isValid). + once. + and_return(true) + + assert @connection.valid? + end + + def test_is_null + @connection_impl. + should_receive(:isNull). + once. + and_return(false) + + assert !@connection.null? + end + + def test_swap + @other_connection. + should_receive(:connection_impl). + once. + and_return(@other_connection_impl) + @connection_impl. + should_receive(:swap). + once. + with(@other_connection_impl) + + @connection.swap @other_connection + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb b/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb new file mode 100644 index 0000000000..060975a1d5 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb @@ -0,0 +1,146 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'cqpid' +require 'qpid/encoding' + +class TestEncoding < Test::Unit::TestCase + + def setup + @cqpid = flexmock(Cqpid) + + @message = flexmock("message") + @message_impl = flexmock("message_impl") + + @encoded = {"foo" => "bar"} + end + + def test_encode_map_with_symbols + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:encode). + once. + with({"foo" => "bar"}, @message_impl). + and_return(@encoded) + + result = Qpid::Messaging.encode({:foo => :bar}, @message) + + assert_same @encoded, result + end + + def test_encode_list_with_symbols + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:encode). + once. + with(["foo", "bar"], @message_impl). + and_return(@encoded) + + result = Qpid::Messaging.encode([:foo, :bar], @message) + + assert_same @encoded, result + end + + def test_encode_with_content_type + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:encode). + once. + with({"foo" => "bar"}, @message_impl). + and_return(@encoded) + + result = Qpid::Messaging.encode({:foo => :bar}, @message) + + assert_same @encoded, result + end + + def test_encode + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:encode). + once. + with({"foo" => "bar"}, @message_impl). + and_return(@encoded) + + result = Qpid::Messaging.encode({"foo" => "bar"}, @message) + + assert_same @encoded, result + end + + def test_decode_for_map + decoded = {"foo" => "bar"} + @message. + should_receive(:content_type). + once. + and_return("amqp/map") + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:decodeMap). + once. + with(@message_impl). + and_return(decoded) + + result = Qpid::Messaging.decode(@message) + + assert_same decoded, result + end + + def test_decode_for_list + decoded = ["foo", "bar"] + @message. + should_receive(:content_type). + once. + and_return("amqp/list") + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @cqpid. + should_receive(:decodeList). + once. + with(@message_impl). + and_return(decoded) + + result = Qpid::Messaging.decode(@message) + + assert_same decoded, result + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_message.rb b/qpid/cpp/bindings/qpid/ruby/test/test_message.rb new file mode 100644 index 0000000000..3fc705bf7e --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'qpid' + +class TestMessage < Test::Unit::TestCase + + def setup + @address = flexmock("address") + @address_impl = flexmock("address_impl") + + @messaging = flexmock(Qpid::Messaging) + @message_impl = flexmock("message") + @message = Qpid::Messaging::Message.new({}, @message_impl) + end + + def test_message_impl + assert_same @message_impl, @message.message_impl + end + + def test_set_reply_to + @address. + should_receive(:address_impl). + once. + and_return(@address_impl) + @message_impl. + should_receive(:setReplyTo). + once. + with(@address_impl) + + @message.reply_to = @address + end + + def test_get_reply_to + @message_impl. + should_receive(:getReplyTo). + once. + and_return(@address_impl) + + result = @message.reply_to + + assert_not_nil result + assert_same @address_impl, result.address_impl + end + + def test_set_subject + @message_impl. + should_receive(:setSubject). + once. + with("New Subject") + + @message.subject = "New Subject" + end + + def test_get_subject + @message_impl. + should_receive(:getSubject). + once. + and_return("Old Subject") + + assert_equal "Old Subject", @message.subject + end + + def test_set_content_type + @message_impl. + should_receive(:setContentType). + once. + and_return("amqp/map") + + @message.content_type = "amqp/map" + end + + def test_get_content_type + @message_impl. + should_receive(:getContentType). + once. + and_return("amqp/list") + + assert_equal "amqp/list", @message.content_type + end + + def test_set_message_id + @message_impl. + should_receive(:setMessageId). + once. + with("717") + + @message.message_id = "717" + end + + def test_get_message_id + @message_impl. + should_receive(:getMessageId). + once. + and_return("1965") + + assert_equal "1965", @message.message_id + end + + def test_set_user_id + @message_impl. + should_receive(:setUserId). + once. + with("129") + + @message.user_id = "129" + end + + def test_get_user_id + @message_impl. + should_receive(:getUserId). + once. + and_return("1971") + + assert_equal "1971", @message.user_id + end + + def test_set_correlation_id + @message_impl. + should_receive(:setCorrelationId). + once. + with("320") + + @message.correlation_id = "320" + end + + def test_get_correlation_id + @message_impl. + should_receive(:getCorrelationId). + once. + and_return("1996") + + assert_equal "1996", @message.correlation_id + end + + def test_set_priority + @message_impl. + should_receive(:setPriority). + once. + with(9) + + @message.priority = 9 + end + + def test_get_priority + @message_impl. + should_receive(:getPriority). + once. + and_return(21) + + assert_equal 21, @message.priority + end + + def test_set_ttl + @message_impl. + should_receive(:setTtl). + once. + with(Qpid::Messaging::Duration::FOREVER) + + @message.ttl = Qpid::Messaging::Duration::FOREVER + end + + def test_get_ttl + @message_impl. + should_receive(:getTtl). + once. + and_return(Qpid::Messaging::Duration::SECOND) + + assert_equal Qpid::Messaging::Duration::SECOND, @message.ttl + end + + def test_set_durable + @message_impl. + should_receive(:setDurable). + once. + with(true) + + @message.durable = true + end + + def test_set_not_durable + @message_impl. + should_receive(:setDurable). + once. + with(false) + + @message.durable = false + end + + def test_get_durable + @message_impl. + should_receive(:getDurable). + once. + and_return(true) + + assert @message.durable + end + + def test_set_redelivered + @message_impl. + should_receive(:setRedelivered). + once. + with(true) + + @message.redelivered = true + end + + def test_set_not_redelivered + @message_impl. + should_receive(:setRedelivered). + once. + with(false) + + @message.redelivered = false + end + + def test_get_redelivered + @message_impl. + should_receive(:getRedelivered). + once. + and_return(false) + + assert !@message.redelivered + end + + def test_get_properties + properties = {"foo" => "bar"} + @message_impl. + should_receive(:getProperties). + once. + and_return(properties) + + result = @message.properties + + assert_equal properties, result + end + + def test_get_property + @message_impl. + should_receive(:getProperties). + once. + and_return({"foo" => "bar"}) + + result = @message["foo"] + + assert_equal "bar", result + end + + def test_set_property + @message_impl. + should_receive(:setProperty). + once. + with("foo", "bar") + + @message["foo"] = "bar" + end + + def test_set_content + @message_impl. + should_receive(:setContent). + once. + with("foo") + + @message.content = "foo" + assert_equal "foo", @message.content + end + + def test_set_content_with_array + content = ["one", "two", "three"] + + @messaging. + should_receive(:encode). + once. + with(content, @message, "amqp/list") + + @message.content = content + assert_same content, @message.content + end + + def test_set_content_with_map + content = {:foo => "bar", :dog => "cat"} + + @messaging. + should_receive(:encode). + once. + with(content, @message, "amqp/map") + + @message.content = content + assert_same content, @message.content + end + + def test_get_content + @message_impl. + should_receive(:getContent). + and_return("foo") + @message_impl. + should_receive(:getContentType). + and_return(String) + + assert_equal "foo", @message.content + end + + def test_get_content_with_array + decoded = ["foo", "bar"] + + @message_impl. + should_receive(:getContent). + and_return("[foo,bar]") + @message_impl. + should_receive(:getContentType). + and_return("amqp/list") + @messaging. + should_receive(:decode). + once. + with(@message, "amqp/list"). + and_return(decoded) + + result = @message.content + assert_same decoded, result + end + + def test_get_content_size + @message_impl. + should_receive(:getContentSize). + once. + and_return(68) + + assert_equal 68, @message.content_size + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb b/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb new file mode 100644 index 0000000000..61a4db17f2 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb @@ -0,0 +1,238 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'qpid/receiver' + +class TestReceiver < Test::Unit::TestCase + + def setup + @session_impl = flexmock("session") + + @Message_class = flexmock(Qpid::Messaging::Message) + @Messaging_module = flexmock(Qpid::Messaging) + @message_impl = flexmock("message_impl") + @message = flexmock("message") + + @receiver_impl = flexmock("receiver") + @other_receiver = flexmock("other_receiver") + @other_receiver_impl = flexmock("other_receiver_impl") + @receiver = Qpid::Messaging::Receiver.new @receiver_impl + end + + def test_receiver_impl + assert_same @receiver_impl, @receiver.receiver_impl + end + + def test_get + @receiver_impl. + should_receive(:get). + once. + with_any_args. + and_return(@message_impl) + + result = @receiver.get + + assert_not_nil result + assert_same @message_impl, result.message_impl + end + + def test_get_with_duration + @receiver_impl. + should_receive(:get). + once. + with_any_args. + and_return(@message_impl) + + result = @receiver.get Qpid::Messaging::Duration::MINUTE + + assert_not_nil result + assert_same @message_impl, result.message_impl + end + + def test_get_with_no_message_received + @receiver_impl. + should_receive(:get). + once. + with_any_args. + and_return(nil) + + result = @receiver.get Qpid::Messaging::Duration::SECOND + + assert_nil result + end + + def test_fetch + @receiver_impl. + should_receive(:fetch). + once. + with_any_args. + and_return(@message_impl) + + result = @receiver.fetch + + assert_not_nil result + assert_same @message_impl, result.message_impl + end + + def test_fetch_with_duration + @receiver_impl. + should_receive(:fetch). + once. + with_any_args. + and_return(@message_impl) + + result = @receiver.fetch Qpid::Messaging::Duration::MINUTE + + assert_not_nil result + assert_same @message_impl, result.message_impl + end + + def test_fetch_with_no_message_received + @receiver_impl. + should_receive(:fetch). + once. + with_any_args. + and_return(nil) + + result = @receiver.fetch Qpid::Messaging::Duration::SECOND + + assert_nil result + end + + def test_set_capacity + @receiver_impl. + should_receive(:setCapacity). + once. + with(15) + + @receiver.capacity = 15 + end + + def test_get_capacity + @receiver_impl. + should_receive(:getCapacity). + once. + and_return(17) + + assert_equal 17, @receiver.capacity + end + + def test_get_available + @receiver_impl. + should_receive(:getAvailable). + once. + and_return(2) + + assert_equal 2, @receiver.available + end + + def test_get_unsettled + @receiver_impl. + should_receive(:getUnsettled). + once. + and_return(12) + + assert_equal 12, @receiver.unsettled + end + + def test_close + @receiver_impl. + should_receive(:close). + once + + @receiver.close + end + + def test_closed_when_open + @receiver_impl. + should_receive(:isClosed). + once. + and_return(false) + + assert !@receiver.closed? + end + + def test_closed + @receiver_impl. + should_receive(:isClosed). + once. + and_return(true) + + assert @receiver.closed? + end + + def test_get_name + @receiver_impl. + should_receive(:getName). + once. + and_return("my-queue") + + assert_equal "my-queue", @receiver.name + end + + def test_get_session + @receiver_impl. + should_receive(:getSession). + once. + and_return(@session_impl) + + result = @receiver.session + + assert_not_nil result + assert_same @session_impl, result.session_impl + end + + def test_is_valid + @receiver_impl. + should_receive(:isValid). + once. + and_return(false) + + assert !@receiver.valid? + end + + def test_is_null + @receiver_impl. + should_receive(:isNull). + once. + and_return(true) + + assert @receiver.null? + end + + def test_swap + @other_receiver. + should_receive(:receiver_impl). + once. + and_return(@other_receiver_impl) + @receiver_impl. + should_receive(:swap). + once. + with(@other_receiver_impl) + + @receiver.swap @other_receiver + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb b/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb new file mode 100644 index 0000000000..64348b9f72 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb @@ -0,0 +1,183 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'qpid/sender' + +class TestSender < Test::Unit::TestCase + + def setup + @messaging = flexmock(Qpid::Messaging) + @message = flexmock("message") + + @session_impl = flexmock("session_impl") + + @sender_impl = flexmock("sender_impl") + @other_sender_impl = flexmock("other_sender_impl") + @sender = Qpid::Messaging::Sender.new @sender_impl + @other_sender = flexmock("other_sender") + end + + def test_send + message_impl = "message_impl" + content = {:foo => :bar} + @message. + should_receive(:message_impl). + once. + and_return(message_impl) + @sender_impl. + should_receive(:send). + once. + with(message_impl, false) + + @sender.send @message + end + + def test_send_and_dont_block + message_impl = "message_impl" + content = {:foo => :bar} + @message. + should_receive(:message_impl). + once. + and_return(message_impl) + @sender_impl. + should_receive(:send). + once. + with(message_impl, false) + + @sender.send @message, :block => false + end + + def test_send_and_block + message_impl = "message_impl" + content = {:foo => :bar} + @message. + should_receive(:message_impl). + once. + and_return(message_impl) + @sender_impl. + should_receive(:send). + once. + with(message_impl, true) + + @sender.send @message, :block => true + end + + def test_close + @sender_impl. + should_receive(:close). + once + + @sender.close + end + + def test_set_capacity + @sender_impl. + should_receive(:setCapacity). + once. + with(17) + + @sender.capacity = 17 + end + + def test_get_capacity + @sender_impl. + should_receive(:getCapacity). + once. + and_return(12) + + assert_equal 12, @sender.capacity + end + + def test_unsettled + @sender_impl. + should_receive(:getUnsettled). + once. + and_return(5) + + assert_equal 5, @sender.unsettled + end + + def test_available + @sender_impl. + should_receive(:getAvailable). + once. + and_return(15) + + assert_equal 15, @sender.available + end + + def test_name + @sender_impl. + should_receive(:getName). + once. + and_return("myname") + + assert_equal "myname", @sender.name + end + + def test_session + @sender_impl. + should_receive(:getSession). + once. + and_return(@session_impl) + + result = @sender.session + + assert_not_nil result + assert_same @session_impl, result.session_impl + end + + def test_is_valid + @sender_impl. + should_receive(:isValid). + once. + and_return(true) + + assert @sender.valid? + end + + def test_is_null + @sender_impl. + should_receive(:isNull). + once. + and_return(false) + + assert !@sender.null? + end + + def test_swap + @other_sender. + should_receive(:sender_impl). + once. + and_return(@other_sender_impl) + @sender_impl. + should_receive(:swap). + once. + with(@other_sender_impl) + + @sender.swap @other_sender + end + +end + diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_session.rb b/qpid/cpp/bindings/qpid/ruby/test/test_session.rb new file mode 100644 index 0000000000..20f055967b --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/test_session.rb @@ -0,0 +1,445 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'flexmock/test_unit' + +require 'qpid/errors' +require 'qpid/duration' +require 'qpid/session' + +class TestSession < Test::Unit::TestCase + + def setup + @session_impl = flexmock("session_impl") + @other_session = flexmock("other_session") + @other_session_impl = flexmock("other_session_impl") + @sender = flexmock("sender") + + @Connection_class = flexmock(Qpid::Messaging::Connection) + @connection_impl = flexmock("connection_impl") + @connection = flexmock("connection") + + @Receiver_class = flexmock(Qpid::Messaging::Receiver) + @receiver = flexmock("receiver") + @receiver_impl = flexmock("receiver_impl") + + @address = flexmock("address") + @address_impl = flexmock("address_impl") + + @Sender_class = flexmock(Qpid::Messaging::Sender) + @sender = flexmock("sender") + @sender_impl = flexmock("sender_impl") + + @message = flexmock("message") + @message_impl = flexmock("message_impl") + + @duration = flexmock("duration") + @duration_impl = flexmock("duration_impl") + + @session = Qpid::Messaging::Session.new(@session_impl) + end + + def test_create_sender_with_Address + @address. + should_receive(:class). + once. + and_return(Qpid::Messaging::Address). + should_receive(:address_impl). + once. + and_return(@address_impl) + @session_impl. + should_receive(:createSender). + once. + with(@address_impl). + and_return(@sender_impl) + + result = @session.create_sender @address + + assert_not_nil result + end + + def test_create_sender + @session_impl. + should_receive(:createSender). + once. + with_any_args. + and_return(@sender_impl) + + result = @session.create_sender("my-queue") + + assert_not_nil result + end + + def test_create_sender_with_address_string + @session_impl. + should_receive(:createSender). + once. + with("my-queue;{create:always}"). + and_return(@sender_impl) + + result = @session.create_sender "my-queue;{create:always}" + + assert_same @sender_impl, result.sender_impl + end + + def test_create_receiver + @address. + should_receive(:class). + once. + and_return(Qpid::Messaging::Address). + should_receive(:address_impl). + once. + and_return(@address_impl) + @session_impl. + should_receive(:createReceiver). + once. + with(@address_impl). + and_return(@receiver_impl) + + result = @session.create_receiver(@address) + + assert_equal @receiver_impl, result.receiver_impl + end + + def test_create_receiver_with_address_string + @session_impl. + should_receive(:createReceiver). + once. + with("my-queue"). + and_return(@receiver_impl) + + result = @session.create_receiver("my-queue") + + assert_same @receiver_impl, result.receiver_impl + end + + def test_close + @session_impl. + should_receive(:close). + once + + @session.close + end + + def test_commit + @session_impl. + should_receive(:commit). + once + + @session.commit + end + + def test_rollback + @session_impl. + should_receive(:rollback). + once + + @session.rollback + end + + def test_acknowledge_with_no_args + @session_impl. + should_receive(:acknowledge). + once. + with(false) + + @session.acknowledge + end + + def test_acknowledge_and_sync + @session_impl. + should_receive(:acknowledge). + once. + with(true) + + @session.acknowledge :sync => true + end + + def test_acknowledge_and_dont_sync + @session_impl. + should_receive(:acknowledge). + once. + with(false) + + @session.acknowledge :sync => false + end + + def test_acknowledge_message_without_sync + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @session_impl. + should_receive(:acknowledge). + once. + with(@message_impl, false) + + @session.acknowledge :message => @message + end + + def test_acknowledge_message_and_sync + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @session_impl. + should_receive(:acknowledge). + once. + with(@message_impl, true) + + @session.acknowledge :message => @message, :sync => true + end + + def test_acknowledge_message_and_dont_sync + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @session_impl. + should_receive(:acknowledge). + once. + with(@message_impl, false) + + @session.acknowledge :message => @message, :sync => false + end + + def test_reject_message + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @session_impl. + should_receive(:reject). + once. + with(@message_impl) + + @session.reject @message + end + + def test_release_message + @message. + should_receive(:message_impl). + once. + and_return(@message_impl) + @session_impl. + should_receive(:release). + once. + with(@message_impl) + + @session.release @message + end + + def test_sync_without_block + @session_impl. + should_receive(:sync). + once + + @session.sync + end + + def test_sync_and_block + @session_impl. + should_receive(:sync). + once. + with(true) + + @session.sync :block => true + end + + def test_sync_and_dont_block + @session_impl. + should_receive(:sync). + once. + with(false) + + @session.sync :block => false + end + + def test_receivable + @session_impl. + should_receive(:getReceivable). + once. + and_return(5) + + assert_equal 5, @session.receivable + end + + def test_unsettled_acks + @session_impl. + should_receive(:getUnsettledAcks). + once. + and_return(17) + + assert_equal 17, @session.unsettled_acks + end + + def test_next_receiver_with_no_duration + @session_impl. + should_receive(:nextReceiver). + once. + with(Qpid::Messaging::Duration::FOREVER.duration_impl). + and_return(@receiver_impl) + + result = @session.next_receiver + + assert_same @receiver_impl, result.receiver_impl + end + + def test_next_receiver_with_duration + @duration. + should_receive(:duration_impl). + once. + and_return(@duration_impl) + @session_impl. + should_receive(:nextReceiver). + once. + with(@duration_impl). + and_return(@receiver_impl) + + result = @session.next_receiver @duration + + assert_same @receiver_impl, result.receiver_impl + end + + def test_sender + @session_impl. + should_receive(:getSender). + once. + with("farkle"). + and_return(@sender_impl) + @Sender_class. + should_receive(:for_impl). + once. + with(@sender_impl). + and_return(@sender) + + result = @session.sender "farkle" + + assert_same @sender, result + end + + def test_sender_with_invalid_name + @session_impl. + should_receive(:getSender). + once. + with("farkle"). + and_throw(RuntimeError) + + assert_raise(Qpid::Messaging::KeyError) {@session.sender "farkle"} + end + + def test_receiver + @session_impl. + should_receive(:getReceiver). + once. + with("farkle"). + and_return(@receiver_impl) + @Receiver_class. + should_receive(:for_impl). + once. + with(@receiver_impl). + and_return(@receiver) + + result = @session.receiver "farkle" + + assert_same @receiver, result + end + + def test_receiver_with_invalid_name + @session_impl. + should_receive(:getReceiver). + once. + with("farkle"). + and_throw(RuntimeError) + + assert_raise(Qpid::Messaging::KeyError) {@session.receiver "farkle"} + end + + def test_connection + @session_impl. + should_receive(:getConnection). + once. + and_return(@connection_impl) + + result = @session.connection + + assert_same @connection_impl, result.connection_impl + end + + def test_error_with_none + @session_impl. + should_receive(:hasError). + once. + and_return(false) + + assert !@session.error? + end + + def test_error + @session_impl. + should_receive(:hasError). + once. + and_return(true) + + assert @session.error? + end + + def test_check_error + @session_impl. + should_receive(:checkError). + once + + @session.check_error + end + + def test_is_valid + @session_impl. + should_receive(:isValid). + once. + and_return(false) + + assert !@session.valid? + end + + def test_is_null + @session_impl. + should_receive(:isNull). + once. + and_return(false) + + assert !@session.null? + end + + def test_swap + @other_session. + should_receive(:session_impl). + once. + and_return(@other_session_impl) + @session_impl. + should_receive(:swap). + once. + with(@other_session_impl) + + @session.swap @other_session + end + +end diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb new file mode 100644 index 0000000000..7aa410c8f8 --- /dev/null +++ b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb @@ -0,0 +1,30 @@ +# +# 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. +# + +$:.unshift File.join(File.dirname(__FILE__), "..", "lib") + +require 'test/unit' +require 'test_encoding' +require 'test_address' +require 'test_message' +require 'test_sender' +require 'test_receiver' +require 'test_session' +require 'test_connection' + diff --git a/qpid/cpp/bindings/swig_python_typemaps.i b/qpid/cpp/bindings/swig_python_typemaps.i index b69784a6de..18bfd48f72 100644 --- a/qpid/cpp/bindings/swig_python_typemaps.i +++ b/qpid/cpp/bindings/swig_python_typemaps.i @@ -17,6 +17,25 @@ * under the License. */ +/* For UUID objects, to convert them to Python uuid.UUID objects, + * we'll need a reference to the uuid module. + */ +%{ +static PyObject* pUuidModule; +%} + +%init %{ + pUuidModule = PyImport_ImportModule("uuid"); + + /* Although it is not required, we'll publish the uuid module in our + * module, as if this module was a python module and we called + * "import uuid" + */ + Py_INCREF(pUuidModule); + PyModule_AddObject(m, "uuid", pUuidModule); +%} + + %wrapper %{ #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) @@ -28,6 +47,7 @@ typedef int Py_ssize_t; PyObject* MapToPy(const qpid::types::Variant::Map*); PyObject* ListToPy(const qpid::types::Variant::List*); + PyObject* UuidToPy(const qpid::types::Uuid*); void PyToMap(PyObject*, qpid::types::Variant::Map*); void PyToList(PyObject*, qpid::types::Variant::List*); @@ -104,6 +124,9 @@ typedef int Py_ssize_t; break; } case qpid::types::VAR_UUID : { + qpid::types::Uuid uuid = v->asUuid(); + result = UuidToPy(&uuid); + break; } } } catch (qpid::types::Exception& ex) { @@ -143,6 +166,30 @@ typedef int Py_ssize_t; return result; } + PyObject* UuidToPy(const qpid::types::Uuid * uuid) { + PyObject* pUuidClass = PyObject_GetAttrString(pUuidModule, "UUID"); + if (!pUuidClass) { + // Failed to get UUID class + return 0; + } + + PyObject* pArgs = PyTuple_New(0); + PyObject* pKw = PyDict_New(); + PyObject* pData = PyString_FromStringAndSize( + (const char*)(uuid->data()), 16); + PyDict_SetItemString(pKw, "bytes", pData); + + PyObject* result = PyObject_Call(pUuidClass, pArgs, pKw); + + Py_DECREF(pData); + Py_DECREF(pKw); + Py_DECREF(pArgs); + Py_DECREF(pUuidClass); + + return result; + } + + void PyToMap(PyObject* obj, qpid::types::Variant::Map* map) { map->clear(); Py_ssize_t iter(0); @@ -304,6 +351,15 @@ typedef int Py_ssize_t; Py_INCREF($result); } +/* + * UUID type: C++ --> Python + */ +%typemap(out) qpid::types::UUID & { + $result = UuidToPy($1); + if ($result) + Py_INCREF($result); +} + /* * Variant types: Ruby --> C++ |