Amazon-SQS-Client
view release on metacpan or search on metacpan
lib/Amazon/SQS/Client.pm view on Meta::CPAN
$client_options->{SecurityToken} = $args[2];
}
}
return $class->SUPER::new(
{ aws_access_key_id => $args[0],
aws_secret_access_key => $args[1],
$client_options->{SecurityToken} ? ( token => $client_options->{SecurityToken} ) : (),
$client_options->{loglevel} ? ( loglevel => $client_options->{loglevel} ) : (),
}
);
}
################################################################################
# Copyright 2008 Amazon Technologies, Inc.
# 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://aws.amazon.com/apache2.0
# This file 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.
#
# Copyright 2024 Robert C. Lauer
#
# Note: The software contained in this distribution has been modified from the
# original. You may freely use and distribute this software under the
# terms of the original license.
package Amazon::SQS::Client;
use strict;
use warnings;
use Amazon::Credentials;
use Amazon::SQS::Constants qw(:all);
use Amazon::SQS::Exception;
use Carp qw(croak);
use Data::Dumper;
use Digest::SHA qw (hmac_sha1_base64 hmac_sha256_base64);
use English qw(-no_match_vars);
use LWP::UserAgent;
use Scalar::Util qw(reftype);
use Time::HiRes qw(usleep);
use URI::Escape;
use URI;
use XML::Simple;
__PACKAGE__->follow_best_practice();
__PACKAGE__->mk_accessors(
qw(
ServiceURL
UserAgent
SignatureVersion
SignatureMethod
MaxErrorRetry
ServiceVersion
SecurityToken
Region
v4_signer
credentials
last_request
last_response
)
);
use parent qw(Class::Accessor::Fast);
our $VERSION = '@PACKAGE_VERSION';
########################################################################
sub new {
########################################################################
my ( $class, @args ) = @_;
my $options;
if ( ref $args[0] ) {
$options = $args[0];
}
elsif ( $args[0] && $args[1] ) {
my $credentials = Amazon::SQS::Credentials->new(@args);
$options = { credentials => $credentials };
if ( ref $args[2] ) {
$options = { %{$options}, %{ $args[2] } };
}
}
else {
$options = ref $args[2] ? $args[2] : {};
$options->{credentials} //= Amazon::Credentials->new();
}
set_defaults($options);
my $self = $class->SUPER::new($options);
$self->init_v4_signer;
return $self;
}
########################################################################
sub set_defaults {
########################################################################
my ($options) = @_;
$options->{SignatureVersion} //= 2;
$options->{SignatureMethod} //= 'HmacSHA256';
$options->{MaxErrorRetry} //= 3;
$options->{ServiceVersion} //= '2012-11-05';
if ( $options->{Region} && !$options->{ServiceURL} ) {
$options->{ServiceURL} = sprintf 'https://sqs.%s.amazonaws.com', $options->{Region};
}
elsif ( !$options->{ServiceURL} ) {
$options->{ServiceURL} = 'https://queue.amazonaws.com';
}
if ( !$options->{UserAgent} ) {
require LWP::UserAgent;
$options->{UserAgent} = LWP::UserAgent->new;
}
return $options;
}
########################################################################
sub init_v4_signer {
########################################################################
my ($self) = @_;
return
if $self->get_SignatureVersion ne '4';
my $credentials = $self->get_credentials;
my $aws_access_key_id = $credentials->get_aws_access_key_id;
my $aws_secret_access_key = $credentials->get_aws_secret_access_key;
my $token = $credentials->get_token;
require AWS::Signature4;
$self->set_v4_signer(
AWS::Signature4->new(
'-access_key' => $aws_access_key_id,
'-secret_key' => $aws_secret_access_key,
$token
? ( '-security_token' => $token )
: ()
)
);
return;
}
# setter/getters for resetting credentials
########################################################################
sub aws_access_key_id {
########################################################################
my ( $self, @args ) = @_;
if (@args) {
$self->get_credentials->set_aws_access_key_id( $args[0] );
}
return $self->get_credentials->get_aws_access_key_id();
}
########################################################################
sub aws_secret_access_key {
########################################################################
my ( $self, @args ) = @_;
if (@args) {
$self->get_credentials->set_aws_secret_access_key( $args[0] );
}
return $self->get_credentials->get_aws_secret_access_key();
}
########################################################################
sub token {
########################################################################
my ( $self, @args ) = @_;
if (@args) {
$self->get_credentials->set_token( $args[0] );
}
return $self->get_credentials->get_token();
}
########################################################################
sub createQueue {
########################################################################
my ( $self, $request ) = @_;
if ( ref $request ne 'Amazon::SQS::Model::CreateQueueRequest' ) {
require Amazon::SQS::Model::CreateQueueRequest;
$request = Amazon::SQS::Model::CreateQueueRequest->new($request);
}
require Amazon::SQS::Model::CreateQueueResponse;
return Amazon::SQS::Model::CreateQueueResponse->fromXML(
$self->_invoke( $self->_convertCreateQueue($request) ) );
}
########################################################################
sub listQueues {
########################################################################
my ( $self, $request ) = @_;
if ( not ref $request eq 'Amazon::SQS::Model::ListQueuesRequest' ) {
require Amazon::SQS::Model::ListQueuesRequest;
$request = Amazon::SQS::Model::ListQueuesRequest->new($request);
}
require Amazon::SQS::Model::ListQueuesResponse;
return Amazon::SQS::Model::ListQueuesResponse->fromXML(
$self->_invoke( $self->_convertListQueues($request) ) );
}
########################################################################
sub listDeadLetterSourceQueues {
########################################################################
my ( $self, $request ) = @_;
if ( not ref $request eq 'Amazon::SQS::Model::ListDeadLetterSourceQueuesRequest' ) {
require Amazon::SQS::Model::ListDeadLetterSourceQueuesRequest;
$request = Amazon::SQS::Model::ListDeadLetterSourceQueuesRequest->new($request);
}
require Amazon::SQS::Model::ListDeadLetterSourceQueuesResponse;
return Amazon::SQS::Model::ListDeadLetterSourceQueuesResponse->fromXML(
$self->_invoke( $self->_convertListDeadLetterSourceQueues($request) ) );
}
########################################################################
sub addPermission {
########################################################################
my ( $self, $request ) = @_;
if ( not ref $request eq 'Amazon::SQS::Model::AddPermissionRequest' ) {
require Amazon::SQS::Model::AddPermissionRequest;
$request = Amazon::SQS::Model::AddPermissionRequest->new($request);
}
require Amazon::SQS::Model::AddPermissionResponse;
lib/Amazon/SQS/Client.pm view on Meta::CPAN
return $ex
if ref $ex;
return Amazon::SQS::Exception->new(
{ Message => 'Internal Error',
StatusCode => $status,
ResponseBody => $responseBody,
}
);
}
#
# perform http post
#
########################################################################
sub _httpPost {
########################################################################
my ( $self, $queueUrl, $parameters ) = @_;
my $url = $queueUrl;
my $ua = $self->get_UserAgent;
my $request = HTTP::Request->new( POST => $url );
$request->content_type('application/x-www-form-urlencoded; charset=utf-8');
my $data = $EMPTY;
foreach my $parameterName ( keys %{$parameters} ) {
no warnings 'uninitialized'; ## no critic
$data .= $parameterName . $EQUALS . $self->_urlencode( $parameters->{$parameterName}, 0 );
$data .= $AMPERSAND;
}
chop $data;
$request->content($data);
# sign request here if v4 else, it is done in _addRequiredParameters()
if ( defined $self->get_v4_signer ) {
$self->get_v4_signer->sign($request);
}
$self->set_last_request($request);
my $response = $ua->request($request);
$self->set_last_response($response);
return $response;
}
#
# Add authentication related and version parameters
#
sub _addRequiredParameters {
my ( $self, $parameters, $queueUrl ) = @_;
my $credentials = $self->get_credentials;
my $token = $credentials->get_token;
my $aws_access_key_id = $credentials->get_aws_access_key_id;
my $aws_secret_access_key = $credentials->get_aws_secret_access_key;
$parameters->{AWSAccessKeyId} = $aws_access_key_id;
$parameters->{Timestamp} = $self->_getFormattedTimestamp();
$parameters->{Version} = $self->get_ServiceVersion;
# v2 signing
if ( !defined $self->{_v4_signer} ) {
if ($token) {
$parameters->{SecurityToken} = $token;
}
$parameters->{SignatureVersion} = $self->get_SignatureVersion || '1';
$parameters->{Signature} = $self->_signParameters( $parameters, $queueUrl, $aws_secret_access_key );
}
return $parameters;
}
#
# Computes RFC 2104-compliant HMAC signature for request parameters
# Implements AWS Signature, as per following spec:
#
# If Signature Version is 0, it signs concatenated Action and Timestamp
#
# If Signature Version is 1, it performs the following:
#
# Sorts all parameters (including SignatureVersion and excluding Signature,
# the value of which is being created), ignoring case.
#
# Iterate over the sorted list and append the parameter name (in original case)
# and then its value. It will not URL-encode the parameter values before
# constructing this string. There are no separators.
#
sub _signParameters {
my ( $self, $parameters, $queueUrl, $key ) = @_;
my $algorithm = 'HmacSHA1';
my $data = $EMPTY;
my $signatureVersion = $parameters->{SignatureVersion};
if ( '0' eq $signatureVersion ) {
$data = $self->_calculateStringToSignV0($parameters);
}
elsif ( '1' eq $signatureVersion ) {
$data = $self->_calculateStringToSignV1($parameters);
}
elsif ( '2' eq $signatureVersion ) {
$algorithm = $self->get_SignatureMethod;
$parameters->{SignatureMethod} = $algorithm;
$data = $self->_calculateStringToSignV2( $parameters, $queueUrl );
}
else {
Carp::croak('Invalid Signature Version specified');
}
return $self->_sign( $data, $key, $algorithm );
}
sub _calculateStringToSignV0 {
lib/Amazon/SQS/Client.pm view on Meta::CPAN
losing messages or requiring each component to be always available.
Amazon SQS works by exposing Amazon's web-scale messaging
infrastructure as a web service. Any computer on the Internet can add
or read messages without any installed software or special firewall
configurations. Components of applications using Amazon SQS can run
independently, and do not need to be on the same network, developed
with the same technologies, or running at the same time.
=head1 METHODS AND SUBROUTINES
=head2 new
new( aws-access-key-id, aws-secret-access-key, [token], [options] )
=over 5
=item aws-access-key-id
The AWS I<access key> your were given when you signed up for AWS services.
You can create a new account by visiting L</http://aws.amazon.com/>.
=item aws-secret-access-key
The AWS I<secret access key> you were given when you signed up for AWS services.
=item token
Pass the session token as the third argument on as SecurityToken in
the options hash described below.
=item options
C<options> is an optional hash reference containing the options listed
below.
=over 5
=item * ServiceURL
default: C<https://queue.amazonaws.com>
Set the ServiceUrl when you want to use a mocking service like
L<LocalStack|https://www.localstack.cloud>.
=item * UserAgent
default: LWP::UserAgent
=item * SignatureVersion
default: 2
I<Note: Signature Version 4 is supported by AWS::Signature4. If you
use the Signature 4 signing facility, make sure your ServiceURL
includes the region endpoint. Ex:
https://sqs.us-east-1.amazonaws.com.>
=item * SecurityToken
For temporary credentials, add the security token returned from the
AWS Security Token Service.
=item * ServiceVersion
default: 2012-11-05
=item * MaxErrorRetry
default: 3
=item * credentials
An instance of a class (e.g. Amazon::Credentials) which supports the getters:
get_aws_access_key_id
get_aws_secret_access_key
get_token
You are encouraged to use this option rather than sending the
credentials in the constructor.
=back
=back
=head2 createQueue
createQueue( request )
The C<CreateQueue> action creates a new queue, or returns the URL of an
existing one. When you request C<CreateQueue>, you provide a name for
the queue. To successfully create a new queue, you must provide a name
that is unique within the scope of your own queues. If you provide the
name of an existing queue, a new queue isnE<039>t created and an error
isnE<039>t returned. Instead, the request succeeds and the queue URL for
the existing queue is returned.
I<Exception: if you provide a value for C<DefaultVisibilityTimeout> that is
different from the value for the existing queue, you receive an error.>
See
L</http://docs.amazonwebservices.com/AWSSimpleQueueService/2009-02-01/SQSDeveloperGuide/Query_QueryCreateQueue.html>.
Returns an C<Amazon::SQS::Model::CreateQueueResponse> object.
Throws an C<Amazon::SQS::Exception>. Use eval to catch it.
=over 5
=item request
C<request> is either a hash reference of parameters for
a C<Amazon::SQS::Model::CreateQueueRequest> object or
a C<Amazon::SQS::Model::CreateQueueRequest> object itself.
See C<Amazon::SQS::Model::CreateQueueRequest> for valid arguments.
=back
=head2 listQueues
listQueues( request )
The ListQueues action returns a list of your queues.
Returns an C<Amazon::SQS::Model::ListQueuesResponse> object.
Throws an C<Amazon::SQS::Exception>. Use eval to catch it
See L</http://docs.amazonwebservices.com/AWSSimpleQueueService/2009-02-01/SQSDeveloperGuide/Query_QueryListQueues.html>
=over 5
=item request
Argument either hash reference of parameters for
C<Amazon::SQS::Model::ListQueuesRequest> request or
C<Amazon::SQS::Model::ListQueuesRequest> object itself.
See C<Amazon::SQS::Model::ListQueuesRequest> for valid arguments.
( run in 0.767 second using v1.01-cache-2.11-cpan-39bf76dae61 )