diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /cpp/bindings/qpid/perl | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-asyncstore.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/bindings/qpid/perl')
20 files changed, 3437 insertions, 5 deletions
diff --git a/cpp/bindings/qpid/perl/CMakeLists.txt b/cpp/bindings/qpid/perl/CMakeLists.txt index 0d66c144db..a1380fa4d0 100644 --- a/cpp/bindings/qpid/perl/CMakeLists.txt +++ b/cpp/bindings/qpid/perl/CMakeLists.txt @@ -21,18 +21,25 @@ ## Use Swig to generate a literal binding to the C++ API ##------------------------------------------------------ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i PROPERTIES CPLUSPLUS ON) -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include") +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i + PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/bindings") swig_add_module(cqpid_perl perl ${CMAKE_CURRENT_SOURCE_DIR}/perl.i) swig_link_libraries(cqpid_perl qpidmessaging qpidtypes qmf2 ${PERL_LIBRARY}) -set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing -I${PERL_INCLUDE_PATH} -I${qpid-cpp_SOURCE_DIR}/include") +set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing") +include_directories(${PERL_INCLUDE_PATH} + ${qpid-cpp_SOURCE_DIR}/include + ${qpid-cpp_SOURCE_DIR}/bindings) ##---------------------------------- ## Install the complete Perl binding ##---------------------------------- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcqpid_perl.so ${CMAKE_CURRENT_BINARY_DIR}/cqpid_perl.pm - DESTINATION ${PERL_ARCHLIB} + ${CMAKE_CURRENT_SOURCE_DIR}/qpid.pm + ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE + ${CMAKE_CURRENT_SOURCE_DIR}/Makefile.PL + DESTINATION ${PERL_PFX_ARCHLIB} COMPONENT ${QPID_COMPONENT_CLIENT} ) diff --git a/cpp/bindings/qpid/perl/ChangeLog b/cpp/bindings/qpid/perl/ChangeLog new file mode 100644 index 0000000000..72685443b1 --- /dev/null +++ b/cpp/bindings/qpid/perl/ChangeLog @@ -0,0 +1,6 @@ +Version 0.22 (TBA): + * QPID-4466: qpid::messaging::Duration now supports multiplication + * QPID-4416: Messages with embedded nulls won't break on getContentPtr + * QPID-4505: Provides unit tests for Address, Duration and Message + * QPID-4504: Broke up the Per classes into separate source modules + * QPID-4580: Added perldoc markup to each source module diff --git a/cpp/bindings/qpid/perl/LICENSE b/cpp/bindings/qpid/perl/LICENSE new file mode 100644 index 0000000000..bc46b77047 --- /dev/null +++ b/cpp/bindings/qpid/perl/LICENSE @@ -0,0 +1,206 @@ +========================================================================= +== Apache License == +========================================================================= + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + diff --git a/cpp/bindings/qpid/perl/Makefile.PL b/cpp/bindings/qpid/perl/Makefile.PL new file mode 100644 index 0000000000..7a4d7f03dc --- /dev/null +++ b/cpp/bindings/qpid/perl/Makefile.PL @@ -0,0 +1,13 @@ +#!/usr/bin/perl -w + +use strict; + +use ExtUtils::MakeMaker; +use Config; + +WriteMakefile( + NAME => 'cqpid_perl', + PREREQ_PM => {}, + LIBS => ["-lqpidmessaging -lqpidtypes"], + C => ['cqpid_perl.cpp'], +); diff --git a/cpp/bindings/qpid/perl/README b/cpp/bindings/qpid/perl/README new file mode 100644 index 0000000000..ca5a96e539 --- /dev/null +++ b/cpp/bindings/qpid/perl/README @@ -0,0 +1,15 @@ +Qpid Perl Language Bindings +=========================== + +How to get help +=============== + +You can use the perldoc command to display API help for working with Qpid. + + perldoc qpid_messaging.pm + +will show a simple example application written in Perl that uses the APIs. +From there you can display the individual module documentation by typing: + + perldoc [module] + diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Address.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Address.pm new file mode 100644 index 0000000000..d417770b1c --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Address.pm @@ -0,0 +1,338 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Address + +=head1 DESCRIPTION + +An B<Address> represents an address to which messages can be sent or +from which they can be received. + +=head2 THE ADDRESS STRING + +An address can be described suing the following pattern: + +E<lt>addressE<gt> [ / E<lt>subjectE<gt> ]= ; [ { E<lt>keyE<gt> : E<lt>valueE<gt> , ... } ] + +where B<address> is a simple name and B<subject> is a subject or subject +pattern. + +=head3 ADDRESS OPTIONS + +The options, encluded 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: + +=over + +=item B<create> + +Indicates if the address should be created; values are B<always>, B<never>, +B<sender> or B<receiver> + +=item B<assert> + +Indicates whether or not to assert any specified node properties; values are +B<always>, B<never>, B<sender> or B<receiver> + +=item B<delete> + +Indicates whether or not to delete the addressed node when a sender or receiver +is cancelled; values are B<always>, B<never>, B<sender> or B<receiver> + +=item B<node> + +A nested map describing properties for the addressed node. Properties are +B<type> (B<topic> or B<queue>), B<durable> (a boolean), B<x-declare> (a nested +map of AMQP 0.10-specific options) and B<x-bindings> (a nested list which +specifies a queue, exchange or a binding key and arguments). + +=item B<link> + +=item B<mode> + +=back + +=cut + +package qpid::messaging::Address; + +use overload ( + 'bool' => \& boolify, + '""' => \& stringify, + ); + +sub boolify { + my ($self) = @_; + my $impl = $self->{_impl}; + + return length($impl->getName()); +} + +sub stringify { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $self->str(); +} + +sub str { + my ($self) = @_; + + return $self->get_implementation()->str(); +} + +=pod + +=head1 CONSTRUCTOR + +Creates an B<Address> + +=over + +=item $address = new qpid::messaging::Address( addr ) + +=back + +=head3 ARGUMENTS + +=over + +=item * addr + +The address string. + +=back + +=cut +sub new { + my ($class) = @_; + my ($self) = {}; + + # 2 args: either a string address or a cqpid_perl::Address + # 3+ args: name + subject + options + type + if (@_ eq 2) { + my $address = $_[1]; + + if (ref($address) eq 'cqpid_perl::Address') { + $self->{_impl} = $address; + } else { + $self->{_impl} = new cqpid_perl::Address($_[1]); + } + } elsif (@_ >= 4) { + my $impl = new cqpid_perl::Address($_[1], $_[2], $_[3]); + + $impl->setType($_[4]) if @_ >= 5; + + $self->{_impl} = $impl; + } else { + die "You must specify an address." + } + + bless $self, $class; + return $self; +} + +sub get_implementation { + my ($self) = @_; + return $self->{_impl}; +} + +=pod + +=head1 ATTRIBUTES + +=cut + +=pod + +=head2 NAME + +The name portion of the address. + +=over + +=item $address->set_name( name ) + +=item $name = $address->get_name + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +See the address string explanation. + +=back + +=cut +sub set_name { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setName($_[1]); +} + +sub get_name { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getName(); +} + +=pod + +=head2 SUBJECT + +The subject portion of the address. + +=over + +=item $address->set_subject( subject ) + +=item $subject = $address->get_subject + +=back + +=head3 ARGUMENTS + +=over + +=item * subject + +See the address string explanation. + +=back + +=cut +sub set_subject { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setSubject($_[1]); +} + +sub get_subject { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getSubject; +} + +=pod + +=head2 OPTIONS + +The address options. + +=over + +=item $address->set_options( options ) + +=item @opts = $address->get_options + +=back + +=head3 ARGUMENTS + +=over + +=item * options + +The set of name:value pairs for the address. See the address string explanation. + +=back + +=cut +sub set_options { + my ($self) = @_; + my $impl = $self->{_impl}; + my $options = $_[1]; + + die "Options cannot be null" if !defined($options); + + $impl->setOptions($_[1]); +} + +sub get_options { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getOptions; +} + +=pod + +=head2 TYPE + +The type of the address determines how B<Sender> and B<Receiver> objects are +constructed for it. It also affects how a b<reply-to> address is encoded. + +If no type is specified then it willb e determined by querying the broker. +Explicitly setting the type prevents this. + +=over + +=item $address->set_type( type ) + +=item $type = $address->get_type + +=back + +=head3 ARGUMENTS + +=over + +=item * type + +Values can be either B<queue> or B<type>. + +=back + +=cut +sub set_type { + my ($self) = @_; + my $impl = $self->{_impl}; + my $type = $_[1]; + + die "Type must be defined" if !defined($type); + + $impl->setType($type); +} + +sub get_type { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getType; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Connection.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Connection.pm new file mode 100644 index 0000000000..6d478cdf0c --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Connection.pm @@ -0,0 +1,291 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Connection + +=head1 DESCRIPTION + +A B<qpid::messaging::Connection> represents a network connection to a remote +endpoint. + +=cut + +package qpid::messaging::Connection; + +=pod + +=head1 CONSTRUCTOR + +=over + +=item $conn = new qpid::messaging::Connection + +=item $conn = new qpid::messaging::Connection( url ) + +=item $conn = new qpid::messaging::Connection( url, options ) + +Creates a connection object. Raises a C<MessagingError> if an invalid +connection option is used. + +=back + +=head3 ARGUMENTS + +=over + +=item * url + +The URL for the broker. See B<qpid::messaging::Address> for more on + address strings + +=item * options + +The connection options. + +=back + +=cut + +sub new { + my ($class) = @_; + my $self = { + _url => $_[1] || "localhost:5672", + _options => $_[2] || {}, + _impl => $_[3], + }; + + bless $self, $class; + return $self; +} + +=pod + +=head1 ACTIONS + +=cut + + +=pod + +=head2 OPENING AND CLOSING CONNECTIONS + +=cut + + +=pod + +=over + +=item $conn->open + +Establishes the connection to the broker. + +=back + +=cut +sub open { + my ($self) = @_; + my $impl = $self->{_impl}; + + # if we have an implementation instance then use it, otherwise + # create a new implementation instance + unless (defined($impl)) { + my $url = $self->{_url}; + my ($options) = $self->{_options}; + + $impl = new cqpid_perl::Connection($url, $options); + $self->{_impl} = $impl + } + + $impl->open() unless $impl->isOpen() +} + +=pod + +=over + +=item $conn->is_open + +Reports whether the connection is open. + +=back + +=cut +sub is_open { + my ($self) = @_; + my $impl = $self->{_impl}; + + if (defined($impl) && $impl->isOpen()) { + 1; + } else { + 0; + } +} + +=pod + +=over + +=item $conn->close + +Closes the connection. + +=back + +=cut +sub close { + my ($self) = @_; + + if ($self->is_open) { + my $impl = $self->{_impl}; + + $impl->close; + $self->{_impl} = undef; + } +} + +=pod + +=head2 SESSIONS + +=cut + + +=pod + +=over + +=item $session = $conn->create_session + +=item $conn->create_session( name ) + +Creates a new session. + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +Specifies a name for the session. + +=back + +=cut +sub create_session { + my ($self) = @_; + + die "No connection available." unless ($self->open); + + my $impl = $self->{_impl}; + my $name = $_[1] || ""; + my $session = $impl->createSession($name); + + return new qpid::messaging::Session($session, $self); +} + +=pod + +=over + +=item $session = $conn->create_transactional_session + +=item $session = $conn->create_transaction_session( name ) + +Creates a transactional session. + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +Specifies a name for the session. + +=back + +=cut +sub create_transactional_session { + my ($self) = @_; + + die "No connection available." unless ($self->open); + + my $impl = $self->{_impl}; + my $name = $_[1] || ""; + my $session = $impl->createTransactionalSession($name); + + return new qpid::messaging::Session($session, $self); +} + +=pod + +=over + +=item $session = $conn->get_session( name ) + +Returns the session with the specified name. + +=over + +=item $name + +The name given to the session when it was created. + +=back + +=back + +=cut +sub get_session { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getSession($_[1]); +} + +=pod + +=over + +=item $uname = $conn->get_authenticated_username + +Returns the username user to authenticate with the broker. + +If the conneciton did not use authentication credentials, then the +username returned is "anonymous". + +=back + +=cut +sub get_authenticated_username { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getAuthenticatedUsername; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Duration.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Duration.pm new file mode 100644 index 0000000000..7d05daeeab --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Duration.pm @@ -0,0 +1,204 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Duration + +=head1 DESCRIPTION + +A B<qpid::messaging::Duration> represents a period of time in milliseconds. + +=head1 NAMED DURATIONS + +The following named durations are available as constants + +=over + +=item B<FOREVER> + +The maximum wait time, equal to the maximum integer value for the platform. +Effective this will wait forever. + +=item B<IMMEDIATE> + +An alias for 0 milliseconds. + +=item B<SECOND> + +An alias for 1,000 milliseconds. + +=item B<MINUTE> + +An alias for 60,000 milliseconds. + +=back + +=cut + +package qpid::messaging::Duration; + +=pod + +=head1 OPERATORS + +=cut + +use overload ( + "*" => \&multiply, + "==" => \&equalify, + "!=" => \&unequalify, + ); + +=pod + +=over + +=item $doubled = $duration * $factor + +=item $doubled = $duration * 2 + +Multiplies the duration and returns a new instance. + +=over + +=item $factor + +A factor for multiplying the duration. + +=back + +=back + +=cut +sub multiply { + my ($self) = @_; + my $factor = $_[1]; + + die "Factor must be non-negative values" if !defined($factor) || ($factor < 0); + + my $duration = $self->{_impl} * $factor; + + return new qpid::messaging::Duration($duration); +} + +sub equalify { + my ($self) = @_; + my $that = $_[1]; + + return 0 if !defined($that) || !UNIVERSAL::isa($that, 'qpid::messaging::Duration');; + + return ($self->get_milliseconds() == $that->get_milliseconds()) ? 1 : 0; +} + +sub unequalify { + my ($self) = @_; + my $that = $_[1]; + + return 1 if !defined($that) || !UNIVERSAL::isa($that, 'qpid::messaging::Duration');; + + return ($self->get_milliseconds() != $that->get_milliseconds()) ? 1 : 0; +} + +=pod + +=head1 CONSTRUCTOR + +Creates a new instance. + +=over + +=item duration = new qpid::messaging::Duration( time ) + +=back + +=head3 ARGUMENTS + +=over + +=item * time + +The duration in B<milliseconds>. + +=back + +=cut +sub new { + my ($class) = @_; + my $duration = $_[1]; + + die "Duration time period must be defined" if !defined($duration); + + if (!UNIVERSAL::isa($duration, 'cqpid_perl::Duration')) { + die "Duration must be non-negative" if $duration < 0; + $duration = new cqpid_perl::Duration($duration); + } + + my ($self) = { + _impl => $duration, + }; + + bless $self, $class; + return $self; +} + +=pod + +=head1 ATTRIBUTES + +=cut + + +=pod + +=head2 MILLISECONDS + +The length of time is measured in milliseconds. + +=over + +=item time = $duration->get_milliseconds + +=back + +=cut +sub get_milliseconds { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getMilliseconds(); +} + +sub get_implementation { + my ($self) = @_; + + return $self->{_impl}; +} + +# TODO: Need a better way to define FOREVER +use constant { + FOREVER => new qpid::messaging::Duration(1000000), + IMMEDIATE => new qpid::messaging::Duration(0), + SECOND => new qpid::messaging::Duration(1000), + MINUTE => new qpid::messaging::Duration(60000), +}; + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Message.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Message.pm new file mode 100644 index 0000000000..6437290244 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Message.pm @@ -0,0 +1,584 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Message + +=head1 DESCRIPTION + +A B<qpid::messaging::Message> a routable piece of information. + +=cut + +package qpid::messaging::Message; + + +=pod + +=head1 CONSTRUCTOR + +Creates a B<Message>. + +=over + +=item $msg = new qpid::messaging::Message + +=item $msg = new qpid::messaging::Message( $content ) + +=back + +=head3 ARGUMENTS + +=over + +=item * $content + +The message's content. + +=back + +=cut +sub new { + my ($class) = @_; + my $content = $_[1] if (@_ > 1); + my $impl = $_[2] if (@_ > 2); + my ($self) = { + _content => $content || "", + _impl => $impl || undef, + }; + + unless (defined($self->{_impl})) { + my $impl = new cqpid_perl::Message($self->{_content}); + + $self->{_impl} = $impl; + } + + bless $self, $class; + return $self; +} + +sub get_implementation { + my ($self) = @_; + + return $self->{_impl}; +} + + +=pod + +=head1 ATTRIBUTES + +=cut + +=pod + +=head2 REPLY TO ADDRESS + +The reply-to address tells a receiver where to send any responses. + +=over + +=item $msg->set_reply_to( "#reqly-queue;{create:always}" ) + +=item $msg->set_reply_to( address ) + +=item $address = $msg->get_reply_to + +=back + +=head3 ARGUMENTS + +=over + +=item * address + +The address. Can be either an instance of B<qpid::messaging::Address> or else an +address string. + +=back + +=cut +sub set_reply_to { + my ($self) = @_; + my $impl = $self->{_impl}; + my $address = $_[1]; + + # if the address was a string, then wrap it + # in a qpid::messaging::Address instance + if (!UNIVERSAL::isa($address, 'qpid::messaging::Address')) { + $address = new qpid::messaging::Address($_[1]); + } + + $impl->setReplyTo($address->get_implementation()); +} + +sub get_reply_to { + my ($self) = @_; + my $impl = $self->{_impl}; + + return new qpid::messaging::Address($impl->getReplyTo()); +} + +=pod + +=head2 SUBJECT + +=over + +=item $msg->set_subject( "responses" ) + +=item $msg->set_subject( subject ) + +=item $subject = $msg->get_subject + +=back + +=cut +sub set_subject { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setSubject($_[1]); +} + +sub get_subject { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getSubject; +} + +=pod + +=head2 CONTENT TYPE + +This should be set by the sending application and indicates to the +recipients of the message how to interpret or decide the content. + +By default, only dictionaries and maps are automatically given a content +type. If this content type is replaced then retrieving the content will +not behave correctly. + +=over + +=item $msg->set_content_type( content_type ) + +=back + +=head3 ARGUMENTS + +=over + +=item * content_type + +The content type. For a list this would be C<amqp/list> and for a hash it is +C<amqp/map>. + +=back + +=cut +sub set_content_type { + my ($self) = @_; + my $type = $_[1]; + + my $impl = $self->{_impl}; + $impl->setContentType($type); +} + +sub get_content_type { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getContentType; +} + +=pod + +=head2 MESSAGE ID + +A message id must be a UUID type. A non-UUID value will be converted +to a zero UUID, thouygh a blank ID will be left untouched. + +=over + +=item $msg->set_message_id( id ) + +=item $id = $msg->get_message_id + +=back + +=cut +sub set_message_id { + my ($self) = @_; + my $impl = $self->{_impl}; + my $id = $_[1]; + + die "message id must be defined" if !defined($id); + + $impl->setMessageId($id); +} + +sub get_message_id { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getMessageId; +} + +=pod + +=head2 USER ID + +The user id should, in general, be the user-id which was used when +authenticating the connection itself, as the messaging infrastructure +will verify this. + +See B<qpid::messaging::Address#authenticated_username>. + +=over + +=item $msg->set_user_id( id ) + +=item $id = $msg->get_user_id + +=back + +=cut +sub set_user_id { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setUserId($_[1]); +} + +sub get_user_id { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getUserId; +} + +=pod + +=head2 CORRELATION ID + +The correlation id can be used as part of a protocol for message exchange +patterns; e.g., a request-response pattern might require the correlation id +of the request and hte response to match, or it might use the message id of +the request as the correlation id on the response. + +B<NOTE:> If the id is not a string then the id is setup using the object's +string representation. + +=over + +=item $msg->set_correlation_id( id ) + +=item $id = $msg->get_correlation_id + +=back + +=cut +sub set_correlation_id { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setCorrelationId($_[1]); +} + +sub get_correlation_id { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getCorrelationId; +} + +=pod + +=head2 PRIORITY + +The priority may be used by the messaging infrastructure to prioritize +delivery of messages with higher priority. + +B<NOTE:> If the priority is not an integer type then it is set using the +object's integer represtation. If the integer value is greater than an +8-bit value then only 8-bits are used. + +=over + +=item $msg->set_priority( priority ) + +=item $priority = $msg->get_priority + +=back + +=cut +sub set_priority { + my ($self) = @_; + my $impl = $self->{_impl}; + my $priority = $_[1]; + + die "Priority must be provided" if !defined($priority); + + $priority = int($priority); + die "Priority must be non-negative" if $priority < 0; + + $impl->setPriority($priority); +} + +sub get_priority { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getPriority; +} + +=pod + +=head2 TIME TO LIVE + +This can be used by the messaging infrastructure to discard messages +that are no longer of relevance. + +=over + +=item $msg->set_ttl( ttl ) + +=item $ttl = $msg->get_ttl + +=back + +=head3 ARGUMENTS + +=over + +=item * ttl + +A B<qpid::messaging::Duration> instance. If it is not, then a new instance +is created using the integer value for the argument. + +A B<negative> value is treated as the equipment of +B<qpid::messaging::Duration::FOREVER>. + +=back + +=cut +sub set_ttl { + my ($self) = @_; + my $impl = $self->{_impl}; + my $duration = $_[1]; + + die "Duration must be provided" if !defined($duration); + if (!UNIVERSAL::isa($duration, 'qpid::messaging::Duration')) { + $duration = int($duration); + + if ($duration < 0) { + $duration = qpid::messaging::Duration::FOREVER; + } elsif ($duration == 0) { + $duration = qpid::messaging::Duration::IMMEDIATE; + } else { + $duration = new qpid::messaging::Duration(int($duration)); + } + } + + $impl->setTtl($duration->get_implementation()); +} + +sub get_ttl { + my ($self) = @_; + my $impl = $self->{_impl}; + + return new qpid::messaging::Duration($impl->getTtl); +} + +=pod + +=head2 DURABILITY + +The durability of a B<Message> is a hint to the messaging infrastructure that +the message should be persisted or otherwise stored. This helps to ensure that +the message is not lost due to failures or a shutdown. + +=over + +=item $msg->set_durable( 1 ) + +=item $durable = $msg->get_durable + +=back + +=cut +sub set_durable { + my ($self) = @_; + my $impl = $self->{_impl}; + my $durable = $_[1]; + + die "Durable must be specified" if !defined($durable); + + $impl->setDurable($durable); +} + +sub get_durable { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getDurable; +} + +=pod + +=head2 REDELIVERED + +This is a hint to the messaging infrastructure that if de-duplication is +required, that this message should be examined to determine if it is a +duplicate. + +=over + +=item $msg->set_redelivered( 1 ) + +=item $redelivered = $msg->get_redelivered + +=back + +=cut +sub set_redelivered { + my ($self) = @_; + my $impl = $self->{_impl}; + my $redelivered = $_[1]; + + die "Redelivered must be specified" if !defined($redelivered); + + $impl->setRedelivered($redelivered); +} + +sub get_redelivered { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getRedelivered; +} + +=pod + +=head2 PROPERTIES + +Named properties for the message are name/value pairs. + +=over + +=item $msg->set_property( name, value ) + +=item $value = $msg->get_property( name ) + +=item @props = $msg->get_properties + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +The property name. + +=item * value + +The property value. + +=back + +=cut +sub set_property { + my ($self) = @_; + my $impl = $self->{_impl}; + my $key = $_[1]; + my $value = $_[2]; + + $impl->setProperty($key, $value); +} + +sub get_properties { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getProperties; +} + +=pod + +=head2 CONTENT + +The message content. + +=begin _private + +TODO: Need to make the content automatically encode and decode for +hashes and lists. + +=end _private + +=over + +=item $msg->set_content( content ) + +=item $content = $msg->get_content + +=item $length = $msg->get_content_size + +=back + +=cut +sub set_content { + my ($self) = @_; + my $content = $_[1]; + my $impl = $self->{_impl}; + + die "Content must be provided" if !defined($content); + + $self->{_content} = $content; + + qpid::messaging::encode($content, $self); +} + +sub get_content { + my ($self) = @_; + my $impl = $self->{_impl}; + $content = $self->{_content} || undef; + + if(!defined($content)) { + $content = qpid::messaging::decode($self); + $self->{_content} = $content; + } + + return $content; +} + +sub get_content_size { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getContentSize; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Receiver.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Receiver.pm new file mode 100644 index 0000000000..c3bc4bb8a8 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Receiver.pm @@ -0,0 +1,317 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Receiver + +=head1 DESCRIPTION + +A B<qpid::messaging::Receiver> is the entity though which messages are received. + +An instance can only be created using an active (i.e., not previously closed) +B<qpid::messaging::Session>. + +=head1 EXAMPLE + + # create a connection and a session + my $conn = new qpid::messaging::Connection("mybroker:5672"); + conn->open; + my $session = $conn->create_session; + + # create a receiver that listens on the "updates" topic of "alerts" + my $recv = $session->create_receiver("alerts/updates"); + + # set the local queue size to hold a maximum of 100 messages + $recv->set_capacity(100); + + # wait for an incoming message and process it + my $incoming = $recv->get; + process($incoming) + +=cut + +package qpid::messaging::Receiver; + +sub new { + my ($class) = @_; + my ($self) = { + _impl => $_[1], + _session => $_[2], + }; + + die "Must provide an implementation." unless defined($self->{_impl}); + die "Must provide a Session." unless defined($self->{_session}); + + bless $self, $class; + return $self; +} + +=pod + +=head1 ACTIONS + +=cut + + +=pod + +There are two ways to retrieve messages: from the local queue or from the +remote queue. + +=head2 GETTING FROM THE LOCAL QUEUE + +Messages can be held locally in message queues. + +=over + +=item $incoming = $receiver->get + +=item $incoming = $receiver->get( timeout) + +=back + +=head3 ARGUMENTS + +=over + +=item * timeout + +The period of time to wait for a message before raising an exception. If no +period of time is specified then the default is to wait B<forever>. + +=back + +=cut +sub get { + my ($self) = @_; + my $duration = $_[1]; + my $impl = $self->{_impl}; + + $duration = $duration->get_implementation() if defined($duration); + + my $message = undef; + + if (defined($duration)) { + $message = $impl->get($duration); + } else { + $message = $impl->get; + } +} + +=pod + +=head2 FETCHING FROM THE REMOTE QUEUE + +Messages held in the remote queue must be fetched from the broker in order +to be processed. + +=over + +=item $incoming = $receiver->fetch + +=item $incoming = $receiver->fetch( time ) + +=back + +=head3 ARGUMENTS + +=over + +=item * timeout + +The period of time to wait for a message before raising an exception. If no +period of time is specified then the default is to wait B<forever>. + +=back + +=cut +sub fetch { + my ($self) = @_; + my $duration = $_[1]; + my $impl = $self->{_impl}; + my $message = undef; + + if (defined($duration)) { + $message = $impl->fetch($duration->get_implementation()); + } else { + $message = $impl->fetch; + } + + return new qpid::messaging::Message("", $message); +} + +=pod + +=head2 CLOSING THE RECEIVER + +=over + +=item receiver->close + +Closes the receiver. + +=back + +=cut +sub close { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->close; +} + +=pod + +=head1 ATTRIBUTES + +=cut + + +=pod + +=head2 CAPACITY + +The maximum number of messages that are prefected and held locally is +determined by the capacity of the receiver. + +=over + +=item $receiver->set_capacity( size ) + +=item $size = $receiver->get_capacity + +=back + +=cut +sub set_capacity { + my ($self) = @_; + my $capacity = $_[1]; + my $impl = $self->{_impl}; + + $impl->setCapacity($capacity); +} + +sub get_capacity { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getCapacity; +} + +=pod + +=head2 AVAILABLE + +The number of messages waiting in the local queue. + +The value is always in the range 0 <= B<available> <= B<capacity>. + +=over + +=item $count = $receiver->get_available + +=back + +=cut + +sub get_available { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getAvailable; +} + +=pod + +=over + +=item $count = $receiver->get_unsettled + +Returns the number of messages that have been received and acknowledged but +whose acknowledgements have not been confirmed by the sender. + +=back + +=cut +sub get_unsettled { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getUnsettled; +} + +=pod + +=over + +=item $name = $receiver->get_name + +Returns the name of the receiver. + +=back + +=cut +sub get_name { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getName; +} + +=pod + +=over + +=item $session = $receiver->get_session + +Returns the B<qpid::messaging::Session> instance from which this +receiver was created. + +=back + +=cut +sub get_session { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->{_session}; +} + +=pod + +=over + +=item $receiver->is_closed + +Returns whether the receiver is closed. + +=back + +=cut +sub is_closed { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->isClosed; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Sender.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Sender.pm new file mode 100644 index 0000000000..5d0896ff79 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Sender.pm @@ -0,0 +1,258 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Sender + +=head1 DESCRIPTION + +A B<qpid::messaging::Sender> is the entity through which messages are sent. + +An instance can only be created using an active (i.e., not previously closed) +B<qpid::messaging::Session>. + +=head1 EXAMPLE + + # create a connection and a session + my $conn = new qpid::messaging::Connection("mybroker:5672"); + conn->open; + my $session = $conn->create_session; + + # create a sender that posts messages to the "updates" queue + my $sender = $session->create_sender "updates;{create:always}" + + # begin sending updates + while( 1 ) { + my $content = wait_for_event; + $sender->send(new qpid::messaging::Message($content)); + } + +=cut + +package qpid::messaging::Sender; + +sub new { + my ($class) = @_; + my ($self) = { + _impl => $_[1], + _session => $_[2], + }; + + die "Must provide an implementation." unless defined($self->{_impl}); + die "Must provide a Session." unless defined($self->{_session}); + + bless $self, $class; + return $self; +} + +=pod + +=head1 ACTIONS + +=cut + + +=pod + +=head2 SENDING MESSAGES + +=over + +=item $sender->send( message ) + +=item $sender->send( message, block) + +Sends a message, optionally blocking until the message is received by +the broker. + +=back + +=head3 ARGUMENTS + +=over + +=item * message + +The message to be sent. + +=item * block + +If true then blocks until the message is received. + +=back + +=cut +sub send { + my ($self) = @_; + my $message = $_[1]; + my $sync = $_[2] || 0; + + die "No message to send." unless defined($message); + + my $impl = $self->{_impl}; + + $impl->send($message->get_implementation, $sync); +} + +=pod + +=head2 CLOSING THE SENDER + +=item sender->close + +Closes the sender. + +This does not affect the ownering B<Session> or B<Connection> + +=back + +=cut +sub close { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->close; +} + +=pod + +=head1 ATTRIBUTES + +=cut + +=pod + +=head2 CAPACITY + +The capacity is the number of outoing messages that can be held pending +confirmation of receipt by the broker. + +=over + +=item sender->set_capacity( size ) + +=item $size = sender->get_capacity + +=back + +=back + +=cut +sub set_capacity { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->setCapacity($_[1]); +} + +sub get_capacity { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getCapacity; +} + +=pod + +=head2 UNSETTLED + +The number of messages sent that are pending receipt confirmation by the broker. + +=over + +=item $count = sender->get_unsettled + +=back + +=cut +sub get_unsettled { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getUnsettled; +} + +=pod + +=head2 AVAILABLE + +The available slots for sending messages. + +This differences form B<capacity> in that it is the available slots in the +senders capacity for holding outgoing messages. The difference between +capacity and available is the number of messages that have no been delivered +yet. + +=over + +=item $slots = sender->get_available + +=back + +=cut +sub get_available { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getAvailable(); +} + +=pod + +=head2 NAME + +The human-readable name for this sender. + +=over + +=item $name = sender-get_name + +=back + +=cut +sub get_name { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getName; +} + +=pod + +=head2 SESSION + +The owning session from which the sender was created. + +=over + +=item $session = $sender->get_session + +=back + +=cut +sub get_session { + my ($self) = @_; + + return $self->{_session}; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/Session.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/Session.pm new file mode 100644 index 0000000000..af85731685 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/Session.pm @@ -0,0 +1,473 @@ +# +# 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. +# + +=pod + +=head1 NAME + +qpid::messaging::Session + +=head1 DESCRIPTION + +A B<qpid::messaging::Session> represents a distinct conversation between end +points. They are created from an active (i.e, not closed) B<Connection>. + +A session is used to acknowledge individual or all messages that have +passed through it, as well as for creating senders and receivers for conversing. +=cut +package qpid::messaging::Session; + +sub new { + my ($class) = @_; + my ($self) = { + _impl => $_[1], + _conn => $_[2], + }; + + die "Must provide an implementation." unless defined($self->{_impl}); + die "Must provide a Connection." unless defined($self->{_conn}); + + bless $self, $class; + return $self; +} + +=pod + +=head1 ACTIONS + +=cut + + +=pod + +=head2 CLOSING THE SESSION + +=over + +=item $session->close + +=back + +=cut +sub close { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->close; +} + +=pod + +=head2 TRANSACTIONS + +Transactions can be rolled back or committed. + +=over + +=item $session->commit + +=item $session->rollback + +=back + +=cut +sub commit { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->commit; +} + +sub rollback { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->rollback; +} + +=pod + +=head2 MESSAGE DISPOSITIONS + +=cut + + +=pod + +=over + +=item $session->acknowledge( msg ) + +Acknowledges that a specific message that has been received. + +=back + +=begin _private + +TODO: How to handle acknowledging a specific message? + +=end _private + +=cut +sub acknowledge { + my ($self) = @_; + my $sync = $_[1] || 0; + + my $impl = $self->{_impl}; + + $impl->acknowledge($sync); +} + +=pod + +=over + +=item $session->reject( msg ) + +Rejects the specified message. A reject message will not be redelivered. + +=back + +=cut +sub reject { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->reject($_[1]); +} + +=pod + +=over + +=item $session->release( msg ) + +Releases the specified message, which allows the broker to attempt to +redeliver it. + +=back + +=cut +sub release { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->release($_[1]); +} + +=pod + +=over + +=item $session->sync + +=item $session->sync( block ) + +Requests synchronization with the broker. + +=back + +=head3 ARGUMENTS + +=over + +=item * block + +If true, then the call blocks until the process completes. + +=back + +=cut +sub sync { + my ($self) = @_; + my $impl = $self->{_impl}; + + if(defined($_[1])) { + $impl->sync($_[1]); + } else { + $impl->sync; + } +} + +=pod + +=head2 SENDERS AND RECEIVERS + +=cut + + +=pod + +=over + +=item $sender = $session->create_sender( address ) + +Creates a new sender. + +=back + +=head3 ARGUMENTS + +=over + +=item * address + +The sender address. See B<qpid::messaging::Address> for more details + +=back + +=cut +sub create_sender { + my ($self) = @_; + my $impl = $self->{_impl}; + + my $address = $_[1]; + + if (ref($address) eq "qpid::messaging::Address") { + my $temp = $address->get_implementation(); + $address = $temp; + } + my $send_impl = $impl->createSender($address); + + return new qpid::messaging::Sender($send_impl, $self); +} + +=pod + +=over + +=item $sender = $session->get_session( name ) + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +The name of the sender. + +Raises an exception when no sender with that name exists. + +=back + +=cut +sub get_sender { + my ($self) = @_; + my $impl = $self->{_impl}; + + my $send_impl = $impl->getSender($_[1]); + my $sender = undef; + + if (defined($send_impl)) { + $sender = new qpid::messaging::Sender($send_impl, $self); + } + + return $sender; +} + +=pod + +=over + +=item $receiver = $session->create_receiver( address ) + +=back + +=head3 ARGUMENTS + +=over + +=item * address + +The receiver address. see B<qpid::messaging::Address> for more details. + +=back + +=cut +sub create_receiver { + my ($self) = @_; + my $impl = $self->{_impl}; + + my $address = $_[1]; + + if (ref($address) eq "qpid::messaging::Address") { + $address = $address->get_implementation(); + } + my $recv_impl = $impl->createReceiver($address); + + return new qpid::messaging::Receiver($recv_impl, $self); +} + +=pod + +=over + +=item $receiver = $session->get_receiver( name ) + +=back + +=head3 ARGUMENTS + +=over + +=item * name + +The name of the receiver. + +=back + +=cut +sub get_receiver { + my ($self) = @_; + my $impl = $self->{_impl}; + + my $recv_impl = $impl->getReceiver($_[1]); + my $receiver = undef; + + if (defined($recv_impl)) { + $receiver = new qpid::messaging::Receiver($recv_impl, $self); + } + + return $receiver; +} + +=pod + +=head1 ATTRIBUTES + +=cut + + +=pod + +=head2 RECEIVABLE + +The total number of receivable messages, and messages already received, +by receivers associated with this session. + +=over + +=item $session->get_receivable + +=back + +=cut +sub get_receivable { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getReceivable; +} + +=pod + +=head2 UNSETTLED ACKNOWLEDGEMENTS + +The number of messages that have been acknowledged by this session whose +acknowledgements have not been confirmed as processed by the broker. + +=over + +=item $session->get_unsettled_acks + +=back + +=cut +sub get_unsettled_acks { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->getUnsettledAcks; +} + +=pod + +=head2 NEXT RECEIVER + +The next receiver is the one, created by this session, that has any pending +local messages. + +If no receivers are found within the timeout then a B<MessagingException> is +raised. + +=over + +=item $session->get_next_receiver + +=item $session->get_next_receiver( timeout ) + +=back + +=head3 ARGUMENTS + +=over + +=item * timeout + +The period of time to wait for a receiver to be found. If no period of time is +specified then the default is to wait B<forever>. + +=back + +=cut +sub get_next_receiver { + my ($self) = @_; + my $impl = $self->{_impl}; + + my $timeout = $_[1] || qpid::messaging::Duration::FOREVER; + + return $impl->getNextReceiver($timeout); +} + +=pod + +=head2 CONNECTION + +=over + +=item $conn = $session->get_connection + +Returns the owning connection for the session. + +=back + +=cut +sub get_connection { + my ($self) = @_; + + return $self->{_conn}; +} + +sub has_error { + my ($self) = @_; + my $impl = $self->{_impl}; + + return $impl->hasError; +} + +sub check_for_error { + my ($self) = @_; + my $impl = $self->{_impl}; + + $impl->checkForError; +} + +1; diff --git a/cpp/bindings/qpid/perl/lib/qpid/messaging/codec.pm b/cpp/bindings/qpid/perl/lib/qpid/messaging/codec.pm new file mode 100644 index 0000000000..c9d6845eb9 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid/messaging/codec.pm @@ -0,0 +1,53 @@ +# +# 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. +# + +package qpid::messaging; + +sub encode { + my $content = $_[0]; + my $message = $_[1]; + my $impl = $message->get_implementation(); + + if(UNIVERSAL::isa($content, "HASH")) { + cqpid_perl::encode($content, $impl, "amqp/map"); + } elsif(UNIVERSAL::isa($content, "ARRAY")) { + cqpid_perl::encode($content, $impl, "amqp/list"); + } else { + $message->get_implementation()->setContent($content); + } +} + +sub decode { + my $message = $_[0]; + my $impl = $message->get_implementation(); + my $content_type = $impl->getContentType(); + + if($content_type eq "amqp/map") { + $result = cqpid_perl::decodeMap($impl); + } elsif($content_type eq "amqp/list") { + $result = cqpid_perl::decodeList($impl); + } else { + $result = $impl->getContent(); + } + + return $result; +} + +1; + diff --git a/cpp/bindings/qpid/perl/lib/qpid_messaging.pm b/cpp/bindings/qpid/perl/lib/qpid_messaging.pm new file mode 100644 index 0000000000..e6a2681c15 --- /dev/null +++ b/cpp/bindings/qpid/perl/lib/qpid_messaging.pm @@ -0,0 +1,95 @@ +# +# 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. +# + +use strict; +use warnings; +use cqpid_perl; + +package qpid::messaging; + +use qpid::messaging::codec; +use qpid::messaging::Address; +use qpid::messaging::Duration; +use qpid::messaging::Message; +use qpid::messaging::Receiver; +use qpid::messaging::Sender; +use qpid::messaging::Session; +use qpid::messaging::Connection; + +1; + +__END__ + +=pod + +=head1 NAME + +qpid::messaging + +=head1 DESCRIPTION + +The Qpid Messaging framework is an enterprise messaging framework +based on the open-source AMQP protocol. + +=head1 EXAMPLE + +Here is a simple example application. It creates a link to a broker located +on a system named C<broker.myqpiddomain.com>. It then creates a new messaging +queue named C<qpid-examples> and publishes a message to it. It then consumes +that same message and closes the connection. + + use strict; + use warnings; + + use qpid; + + # create a connection, open it and then create a session named "session1" + my $conn = new qpid::messaging::Connection("broker.myqpiddomain.com"); + $conn->open(); + my $session = $conn->create_session("session1"); + + # create a sender and a receiver + # the sender marks the queue as one that is deleted when the sender disconnects + my $send = $session->create_sender("qpid-examples;{create:always}"); + my $recv = $session->create_receiver("qpid-examples"); + + # create an outgoing message and send it + my $outgoing = new qpid::messaging::Message(); + $outgoing->set_content("The time is " . localtime(time)"); + $send->send($outgoing); + + # set the receiver's capacity to 10 and then check out many messages are pending + $recv->set_capacity(10); + print "There are " . $recv->get_available . " messages waiting.\n"; + + # get the nextwaitingmessage, which should be in the local queue now, + # and output the contents + my $incoming = $recv->fetch(); + print "Received the following message: " . $incoming->get_content() . "\n"; + # the output should be the text that was sent earlier + + # acknowledge the message, letting the sender know the message was received + printf "The sender currently has " . $send->get_unsettled . " message(s) pending.\n"; + # should report 1 unsettled message + $session->acknowledge(); # acknowledges all pending messages + print "Now sender currently has " . $send->get_unsettled . " message(s) pending.\n"; + # should report 0 unsettled messages + + # close the connection + $conn->close diff --git a/cpp/bindings/qpid/perl/perl.i b/cpp/bindings/qpid/perl/perl.i index 38ac91761f..0d118ae0fb 100644 --- a/cpp/bindings/qpid/perl/perl.i +++ b/cpp/bindings/qpid/perl/perl.i @@ -19,7 +19,7 @@ %module cqpid_perl %include "std_string.i" -%include "../../swig_perl_typemaps.i" +%include "qpid/swig_perl_typemaps.i" /* Define the general-purpose exception handling */ %exception { @@ -31,5 +31,5 @@ } } -%include "../qpid.i" +%include "qpid/qpid.i" diff --git a/cpp/bindings/qpid/perl/qpid.pm b/cpp/bindings/qpid/perl/qpid.pm new file mode 100644 index 0000000000..88b98353a8 --- /dev/null +++ b/cpp/bindings/qpid/perl/qpid.pm @@ -0,0 +1,22 @@ +# +# 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. +# + +use qpid_messaging; + +1; diff --git a/cpp/bindings/qpid/perl/t/Address.t b/cpp/bindings/qpid/perl/t/Address.t new file mode 100644 index 0000000000..4e74f8cad2 --- /dev/null +++ b/cpp/bindings/qpid/perl/t/Address.t @@ -0,0 +1,102 @@ +#!/usr/bin/env perl -w +# +# 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. +# + +use Test::More qw(no_plan); +use Test::Exception; + +require 'utils.pm'; + +# verify that qpid is available +BEGIN { use_ok( 'qpid' ); } +require_ok ('qpid' ); + +# construction +# address cannot be null +dies_ok (sub {new qpid::messaging::Address(undef);}, + "Address cannot be null"); + +# can use an address +my $address = new qpid::messaging::Address("0.0.0.0"); +ok ($address, "Can be created with an arbitrary address"); + +# name +# name cannot be null +dies_ok (sub {$address->set_name(undef);}, + "Name cannot be null"); + +# name can be an empty string +$address->set_name(""); +ok ($address->get_name() eq "", + "Name can be empty"); + +# name can be an arbitrary string +my $name = random_string(25); +$address->set_name($name); +ok ($address->get_name() eq $name, + "Name can be an arbitrary string"); + +# subject +# cannot be null +dies_ok (sub {$address->set_subject(undef);}, + "Subject cannot be null"); + +# can be an empty string +$address->set_subject(""); +ok ($address->get_subject() eq "", + "Subject can be empty"); + +# can be an arbitrary string +my $subject = random_string(64); +$address->set_subject($subject); +ok ($address->get_subject() eq $subject, + "Subject can be an arbitrary string"); + +# options +# options cannot be null +dies_ok (sub {$address->set_options(undef);}, + "Options cannot be null"); + +# options can be an empty hash +$address->set_options({}); +ok (eq_hash($address->get_options(), {}), + "Options can be an empty hash"); + +# options cannot be arbitrary values +my %options = ("create", "always", "delete", "always"); +$address->set_options(\%options); +ok (eq_hash($address->get_options(), \%options), + "Options can be arbitrary keys"); + +# type +# cannot be null +dies_ok (sub {$address->set_type(undef);}, + "Type cannot be null"); + +# can be an empty string +$address->set_type(""); +ok ($address->get_type() eq "", + "Type can be an empty string"); + +# can be an arbitrary string +my $type = random_string(16); +$address->set_type($type); +ok ($address->get_type() eq $type, + "Type can be an arbitrary type"); + diff --git a/cpp/bindings/qpid/perl/t/Duration.t b/cpp/bindings/qpid/perl/t/Duration.t new file mode 100644 index 0000000000..6975e8006f --- /dev/null +++ b/cpp/bindings/qpid/perl/t/Duration.t @@ -0,0 +1,124 @@ +#!/usr/bin/env perl -w +# +# 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. +# + +use Test::More qw(no_plan); +use Test::Exception; + +require 'utils.pm'; + +# verify that qpid is available +BEGIN { use_ok( 'qpid' ); } +require_ok ('qpid' ); + +# milliseconds +# duration cannot be null +{ + dies_ok (sub {new qpid::messaging::Duration(undef);}, + "Durations cannot have null time periods"); +} + +# duration cannot be negative +{ + my $period = 0 - (int(rand(65535)) + 1); + dies_ok(sub {new qpid::messaging::Duration($period);}, + "Duration times cannot be negative"); +} + +# duration can be an arbitrary value +{ + my $period = int(rand(65535)); + my $duration = new qpid::messaging::Duration($period); + ok ($duration->get_milliseconds() == $period, + "Milliseconds are properly stored and fetched"); +} + +# multiplier +# cannot multiply by null +dies_ok(sub {qpid::messaging::Duration::FOREVER * undef;}, + "Cannot multiply a duration times a null"); + +# cannot multiply by a negative +dies_ok (sub {qpid::messaging::Duration::MINUTE * -2;}, + "Duration cannot be multiplied by a negative"); + +# multiply by zero returns a zero time period +{ + my $result = qpid::messaging::Duration::MINUTE * 0; + + ok ($result->get_milliseconds() == 0, + "Multiplying duration by 0 returns a 0 duration"); +} + +# multiply by arbitrary values works +{ + my $factor = int(1 + rand(100)); + my $result = qpid::messaging::Duration::MINUTE * $factor; + ok ($result->get_milliseconds() == 60000 * $factor, + "Multiplying by a factor returns a new Duration with that period"); +} + +# equality +# always fails with null +ok (!(qpid::messaging::Duration::MINUTE == undef), + "Duration is never equal to null"); + +# never equal to a non-duration class +ok (!(qpid::messaging::Duration::MINUTE == random_string(12)), + "Duration is never equal to a non-Duration"); + +# works with self +ok (qpid::messaging::Duration::MINUTE == qpid::messaging::Duration::MINUTE, + "Duration is always equal to itself"); + +# fails with non-equal instance +ok (!(qpid::messaging::Duration::MINUTE == qpid::messaging::Duration::SECOND), + "Duration non-equality works"); + +# works with equal instance +{ + my $result = qpid::messaging::Duration::MINUTE * 0; + ok ($result == qpid::messaging::Duration::IMMEDIATE, + "Equality comparison works correctly"); +} + +# non-equality +# always not equal to null +ok (qpid::messaging::Duration::MINUTE != undef, + "Always unequal to null"); + +# always not equal to a non-duration class +ok (qpid::messaging::Duration::MINUTE != random_string(64), + "Always unequal to a non-duration class"); + +# not unequal to itself +ok (!(qpid::messaging::Duration::MINUTE != qpid::messaging::Duration::MINUTE), + "Never unequal to itself"); + +# not unequal to an equal instance +{ + my $duration = qpid::messaging::Duration::MINUTE * 1; + ok (!(qpid::messaging::Duration::MINUTE != $duration), + "Never unequal to an equal instance"); +} + +# works with unequal instances +ok (qpid::messaging::Duration::MINUTE != qpid::messaging::Duration::FOREVER, + "Always unequal to a non-equal instance"); + diff --git a/cpp/bindings/qpid/perl/t/Message.t b/cpp/bindings/qpid/perl/t/Message.t new file mode 100644 index 0000000000..15baafb446 --- /dev/null +++ b/cpp/bindings/qpid/perl/t/Message.t @@ -0,0 +1,286 @@ +#!/usr/bin/env perl -w +# +# 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. +# + +use Test::More qw(no_plan); +use Test::Exception; + +require 'utils.pm'; + +# verify that qpid is available +BEGIN { use_ok( 'qpid' ); } +require_ok ('qpid' ); + +# Create a new message +my $message = new qpid::messaging::Message(); +isa_ok($message, 'qpid::messaging::Message'); + +# reply to +# rejects an null address +dies_ok (sub {$message->set_reply_to(undef);}, + "Reply to cannot be null."); + +# can handle a string address +$message->set_reply_to("test"); +ok ($message->get_reply_to()->str() eq "test", + "Reply to can be set"); + +# subject +# cannot have an null subject +dies_ok (sub {$message->set_subject(undef);}, + "Subject cannot be null"); + +# can have an empty subject +$message->set_subject(""); +ok ($message->get_subject() eq "", + "Subject can be empty"); + +# can have a subject +my $subject = random_string(16); +$message->set_subject($subject); +ok ($message->get_subject() eq $subject, + "Subject can be set."); + +# content type +# cannot have an null content type +dies_ok (sub {$message->set_content_type(undef);}, + "Content type must be defined."); + +# can an empty content type +$message->set_content_type(""); +ok ($message->get_content_type() eq "", + "Content type can be empty"); + +# can have an arbitrary content type +my $content_type = random_string(10); +$message->set_content_type($content_type); +ok ($message->get_content_type() eq $content_type, + "Content type can be arbitrary"); + +# can be for a map +$content_type = "amqp/map"; +$message->set_content_type($content_type); +ok ($message->get_content_type() eq $content_type, + "Content type can be for a map"); + +# message id +# cannot be null +dies_ok (sub {$message->set_message_id(undef);}, + "Message id cannot be null"); + +# can be an empty string +$message->set_message_id(""); +ok ($message->get_message_id() eq "", + "Message id can be empty"); + +# can be an arbitrary string +my $id = random_string(32); +$message->set_message_id($id); +ok ($message->get_message_id() eq $id, + "Message id can be an arbitrary string"); + +# can be a UUID +$id = generate_uuid(); +$message->set_message_id($id); +ok ($message->get_message_id() eq $id, + "Message id can be a valid UUID"); + +# user id +# cannot be null +dies_ok (sub {$message->set_user_id(undef);}, + "User id cannot be null"); + +# can be an empty string +my $user_id = ""; +$message->set_user_id($user_id); +ok ($message->get_user_id() eq $user_id, + "User id can be empty"); + +# can be an arbitrary string +$id = random_string(65); +$message->set_user_id($user_id); +ok ($message->get_user_id() eq $user_id, + "User id can be an arbitrary string"); + +# correlation id +# cannot be null +dies_ok (sub {$message->set_correlation_id(undef);}, + "Correlation id cannot be null"); + +# can be empty +my $correlation_id = ""; +$message->set_correlation_id($correlation_id); +ok ($message->get_correlation_id() eq $correlation_id, + "Correlation id can be an empty string"); + +# can be an arbitrary string +$correlation_id = random_string(32); +$message->set_correlation_id($correlation_id); +ok ($message->get_correlation_id() eq $correlation_id, + "Correlation id can be an arbitrary string"); + +# priority +# cannot be nul +dies_ok (sub {$message->set_priority(undef);}, + "Priority cannot be null"); + +# cannot be negative +my $priority = 0 - (rand(2**8) + 1); +dies_ok (sub {$message->set_priority($priority);}, + "Priority cannot be negative"); + +# can be 0 +$message->set_priority(0); +ok ($message->get_priority() == 0, + "Priority can be zero"); + +# can be an arbitrary value +$priority = int(rand(2**8) + 1); +$message->set_priority($priority); +ok ($message->get_priority() == $priority, + "Priority can be any positive value"); + +# ttl +# cannot be null +dies_ok (sub {$message->set_ttl(undef);}, + "TTL cannot be null"); + +# can be a duration +$message->set_ttl(qpid::messaging::Duration::FOREVER); +ok ($message->get_ttl()->get_milliseconds() == qpid::messaging::Duration::FOREVER->get_milliseconds(), + "TTL can be a Duration"); + +# if numeric, is converted to a duration +my $duration = rand(65535); +$message->set_ttl($duration); +ok ($message->get_ttl()->get_milliseconds() == int($duration), + "TTL can be any arbitrary duration"); + +# if 0 it's converted to IMMEDIATE +$message->set_ttl(0); +ok ($message->get_ttl()->get_milliseconds() == qpid::messaging::Duration::IMMEDIATE->get_milliseconds(), + "TTL of 0 is converted to IMMEDIATE"); + +# if negative it's converted to FOREVER +$message->set_ttl(0 - (rand(65535) + 1)); +ok ($message->get_ttl()->get_milliseconds() == qpid::messaging::Duration::FOREVER->get_milliseconds(), + "TTL of <0 is converted to FOREVER"); + +# durable +# cannot be null +dies_ok (sub {$message->set_durable(undef);}, + "Durable cannot be null"); + +# can be set to true +$message->set_durable(1); +ok ($message->get_durable(), + "Durable can be true"); + +# can be set to false +$message->set_durable(0); +ok (!$message->get_durable(), + "Durable can be false"); + +# redelivered +# redelivered cannot be null +dies_ok (sub {$message->set_redelivered(undef);}, + "Redelivered cannot be null"); + +# can be set to true +$message->set_redelivered(1); +ok ($message->get_redelivered(), + "Redelivered can be true"); + +# can be set to false +$message->set_redelivered(0); +ok (!$message->get_redelivered(), + "Redelivered can be false"); + +# properties +# can retrieve all properties +my $properties = $message->get_properties(); +ok (UNIVERSAL::isa($properties, 'HASH'), + "Returns the properties as a hash map"); + +# property +# setting a property using a null key fails +dies_ok (sub {$message->set_property(undef, "bar");}, + "Property cannot have a null key"); + +# setting a property with a null value succeeds +my $key = random_string(16); +$message->set_property($key, undef); +ok (!$message->get_properties()->{$key}, + "Properties can have null values"); + +# setting a property succeeds +my $value = random_string(255); +$message->set_property($key, $value); +ok ($message->get_properties()->{$key} eq $value, + "Messages can have arbitrary property values"); + +# content +# cannot be null +dies_ok (sub {$message->set_content(undef);}, + "Content cannot be null"); + +# can be an empty string +$message->set_content(""); +ok ($message->get_content() eq "", + "Content can be an empty string"); + +# can be an arbitrary string +my $content = random_string(255); +$message->set_content($content); +ok ($message->get_content() eq $content, + "Content can be an arbitrary string"); + +# Embedded nulls should be handled properly +$content = { id => 1234, name => "With\x00null" }; +qpid::messaging::encode($content, $message); +my $map = qpid::messaging::decode_map($message); +ok ($map->{name} eq "With\x00null", + "Nulls embedded in map values work."); + +# Unicode strings shouldn't be broken +$content = { id => 1234, name => "Euro=\x{20AC}" }; +qpid::messaging::encode($content, $message); +$map = qpid::messaging::decode_map($message); +ok ($map->{name} eq "Euro=\x{20AC}", + "Unicode strings encoded correctly."); + +# Setting the content as a hash automatically encodes it +($content) = {"id" => "1234", "name" => "qpid"}; +$message->set_content($content); +ok ($message->get_content_type() eq "amqp/map", + "Hashes are automatically encoded correctly"); + +# Setting the content as a list automatically encodes it +my @acontent = (1, 2, 3, 4); +$message->set_content(\@acontent); +ok ($message->get_content_type() eq "amqp/list", + "Lists are automatically encoded correctly"); + +# content size +# content size is correct +my $content_size = int(rand(256)); +$content = random_string($content_size); +$message->set_content($content); +ok ($message->get_content_size() == $content_size, + "Content size is correct"); diff --git a/cpp/bindings/qpid/perl/t/utils.pm b/cpp/bindings/qpid/perl/t/utils.pm new file mode 100644 index 0000000000..db8093d324 --- /dev/null +++ b/cpp/bindings/qpid/perl/t/utils.pm @@ -0,0 +1,38 @@ +# 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. +# + +use Digest::MD5; + +sub random_string +{ + my $len=$_[0]; + my @chars=('a'..'z','A'..'Z','0'..'9','_'); + my $result; + + foreach (1..$len) { + $result .= $chars[rand @chars]; + } + return $result; +} + +sub generate_uuid +{ + return Digest::MD5::md5_base64( rand ); +} + +1; |