File Coverage

blib/lib/Paws.pm
Criterion Covered Total %
statement 89 91 97.8
branch 20 26 76.9
condition 3 3 100.0
subroutine 20 20 100.0
pod 0 6 0.0
total 132 146 90.4


line stmt bran cond sub pod time code
1             package Paws::SDK::Config;
2              
3 22     22   2281037 use Moose;
  22         7262438  
  22         139  
4 22     22   162872 use Moose::Util::TypeConstraints;
  22         57  
  22         179  
5 22     22   54375 use Paws::Net::CallerRole;
  22         59  
  22         781  
6 22     22   9215 use Paws::Credential;
  22         57  
  22         5984  
7              
8             coerce 'Paws::Net::CallerRole',
9             from 'Str',
10             via {
11             my $class = $_;
12             Paws->load_class($class);
13             return $class->new()
14             };
15              
16             coerce 'Paws::Credential',
17             from 'Str',
18             via {
19             my $class = $_;
20             Paws->load_class($class);
21             return $class->new();
22             };
23              
24             has region => (
25             is => 'rw',
26             isa => 'Str|Undef',
27             default => sub { undef }
28             );
29              
30             has caller => (
31             is => 'rw',
32             does => 'Paws::Net::CallerRole',
33             lazy => 1,
34             default => sub {
35             Paws->load_class('Paws::Net::Caller');
36             Paws::Net::Caller->new
37             },
38             coerce => 1
39             );
40             has credentials => (
41             is => 'rw',
42             does => 'Paws::Credential',
43             lazy => 1,
44             default => sub {
45             Paws->load_class('Paws::Credential::ProviderChain');
46             Paws::Credential::ProviderChain->new
47             },
48             coerce => 1
49             );
50             has immutable => (
51             is => 'rw',
52             isa => 'Bool',
53             default => 0,
54             );
55             __PACKAGE__->meta->make_immutable;
56             1;
57              
58             package Paws;
59              
60             our $VERSION = '0.35';
61              
62 22     22   146 use Moose;
  22         39  
  22         103  
63 22     22   137871 use MooseX::ClassAttribute;
  22         1691258  
  22         91  
64 22     22   6090451 use Moose::Util qw//;
  22         53  
  22         439  
65 22     22   107 use Module::Runtime qw//;
  22         49  
  22         484  
66              
67 22     22   10185 use Paws::API::JSONAttribute;
  22         61  
  22         732  
68 22     22   6840 use Paws::API::Base64Attribute;
  22         63  
  22         682  
69              
70 22     22   6984 use Paws::API;
  22         66  
  22         927  
71 22     22   158 use Moose::Util::TypeConstraints;
  22         40  
  22         178  
72              
73             has _class_prefix => (isa => 'Str', is => 'ro', default => 'Paws::');
74              
75             coerce 'Paws::SDK::Config',
76             from 'HashRef',
77             via {
78             Paws::SDK::Config->new($_);
79             };
80             has config => (isa => 'Paws::SDK::Config', is => 'rw', coerce => 1, default => sub { Paws->default_config });
81              
82             # Holds a fully constructed Paws instance so continuous calls to get_self are all done over the
83             # same (implicit) object. This happens when the user calls Paws->service, as opposed to $instance->service
84             class_has _default_object => (is => 'rw', isa => 'Paws');
85              
86             class_has default_config => (is => 'rw', isa => 'Paws::SDK::Config', default => sub { Paws::SDK::Config->new });
87              
88             sub load_class {
89 14020     14020 0 126640 my (undef, @classes) = @_;
90 14020         31790 foreach my $class (@classes) {
91 14020         56087 Module::Runtime::require_module($class);
92             # immutability is a global setting that will affect all instances
93 14016 50       638851 $class->meta->make_immutable if (Paws->default_config->immutable);
94             }
95             }
96              
97             sub available_services {
98 1     1 0 1402 my ($self) = @_;
99 1         4 $self = $self->get_self;
100              
101 1         5 my $skip_list = {
102             API => 1, Credential => 1, Exception => 1, RegionInfo => 1,
103             };
104 1         258 require Module::Find;
105 1         1075 my $class_prefix = $self->_class_prefix;
106 1         7 return grep { not $skip_list->{ $_ } } map { $_ =~ s/^$class_prefix//; $_ } Module::Find::findsubmod Paws;
  109         172  
  109         48673  
  109         146  
107             }
108              
109             sub get_self {
110 1439     1439 0 2510 my $self = shift;
111 1439 100       3960 if (not ref($self)) {
112 114 100       3361 if (not defined Paws->_default_object) {
113 4         76 Paws->_default_object(Paws->new(config => Paws->default_config));
114             }
115 114         2290 return Paws->_default_object;
116             } else {
117 1325         2701 return $self;
118             }
119             }
120              
121             sub class_for_service {
122 772     772 0 2081 my ($self, $service_name) = @_;
123 772         1969 $self = $self->get_self;
124              
125 772         15242 my $class = $self->_class_prefix . $service_name;
126 772         3998 $self->load_class($class);
127 772         2257 return $class;
128             }
129              
130             sub service {
131 666     666 0 19003173 my ($self, $service_name, %constructor_params) = @_;
132 666         2444 $self = $self->get_self;
133              
134 666 100       3267 $constructor_params{ region } = $self->config->region if (not exists $constructor_params{ region });
135 666 100       10037 $constructor_params{ caller } = $self->config->caller if (not exists $constructor_params{ caller });
136 666 100       14703 $constructor_params{ credentials } = $self->config->credentials if (not exists $constructor_params{ credentials });
137              
138 666         2184 my $class = $self->class_for_service($service_name);
139 666         6136 my $instance = $class->new(
140             %constructor_params
141             );
142              
143 665         11027 return $instance;
144             }
145              
146             sub preload_service {
147 106     106 0 3938052 my (undef, $service, @operations) = @_;
148              
149             # load the service class
150 106         563 my $service_class = Paws->class_for_service($service);
151              
152 106 50       587 @operations = ('*') if (@operations == 0);
153              
154 106         327 my %calculated_operations = ();
155 106         324 foreach my $operation (@operations) {
156 106 50       442 if ($operation eq '*') {
    0          
157 106         596 $calculated_operations{ $_ } = 1 for ($service_class->operations);
158             } elsif ($operation =~ m/\*/) {
159 0         0 die "Wildcards not implemented yet";
160             } else {
161 0         0 $calculated_operations{ $operation } = 1;
162             }
163             }
164              
165 106         989 _preload_operations($service_class, keys %calculated_operations);
166             }
167              
168             sub _preload_operations {
169 106     106   853 my ($service_class, @operations) = @_;
170              
171 106         301 foreach my $operation (@operations) {
172             # Each operation has two classes associated:
173              
174             # 1st preload the classes that represent the arguments for a call
175 3360         25489 my $op_params_class = "${service_class}::${operation}";
176 3360         10121 _preload_scanclass($op_params_class);
177              
178             # 2nd preload the classes that represent responses from the call
179 3360 50       103771 _preload_scanclass($op_params_class->_returns) if ($op_params_class->_returns);
180             }
181             }
182              
183             sub _preload_scanclass {
184 12083     12083   122678 my ($class) = @_;
185              
186             # If the class is already loaded, we really don't want to be rescanning it
187             # this avoid infinite recursion on DynamoDB, for example
188 12083 100       34716 return if (Moose::Util::find_meta($class));
189              
190 8847         107015 Paws->load_class($class);
191              
192 8847         47896 foreach my $att ($class->meta->get_all_attributes){
193 30179         1350489 my $tconst = $att->type_constraint;
194              
195 30179 100 100     469957 if ($tconst->isa('Moose::Meta::TypeConstraint::Class')) {
    100          
196             # Any attribute that isa class will need to be inspected
197 3114         84550 _preload_scanclass($tconst->class);
198             } elsif ($tconst->isa('Moose::Meta::TypeConstraint::Parameterized') and
199             $tconst->type_parameter->isa('Moose::Meta::TypeConstraint::Class')) {
200             # those attributes can also be found in parametrized
201             # type constraints (ArrayRef[...], Hashref[...])
202 2249         85157 _preload_scanclass($tconst->type_parameter->class);
203             }
204             }
205             }
206              
207             1;
208             ### main pod documentation begin ###
209              
210             =encoding UTF-8
211              
212             =head1 NAME
213              
214             Paws - A Perl SDK for AWS (Amazon Web Services) APIs
215              
216             =head1 SYNOPSIS
217              
218             use Paws;
219             my $obj = Paws->service('...');
220             my $res = $obj->MethodCall(Arg1 => $val1, Arg2 => $val2);
221             print $res->AttributeFromResult;
222              
223             =head1 DESCRIPTION
224              
225             Paws is an attempt to develop an always up-to-date SDK that covers all possible AWS services.
226              
227             =head1 STATUS
228              
229             Please consider the SDK is beta quality. The intention of publishing to CPAN is having the community
230             find the SDK, try it, give feedback, etc. Some services are still not working, and some heavy
231             refactoring will still be done to the internals. The external interface to SDK users will try to be
232             kept stable, and changes to it should be notified via ChangeLog
233              
234             =head1 SUPPORTED SERVICES
235              
236              
237             L<Paws::ACM>
238              
239             L<Paws::ApiGateway>
240              
241             L<Paws::ApplicationAutoScaling>
242              
243             L<Paws::AppStream>
244              
245             L<Paws::Athena>
246              
247             L<Paws::AutoScaling>
248              
249             L<Paws::Batch>
250              
251             L<Paws::Budgets>
252              
253             L<Paws::CloudDirectory>
254              
255             L<Paws::CloudFormation>
256              
257             L<Paws::CloudFront>
258              
259             L<Paws::CloudHSM>
260              
261             L<Paws::CloudHSMv2>
262              
263             L<Paws::CloudSearch>
264              
265             L<Paws::CloudSearchDomain>
266              
267             L<Paws::CloudTrail>
268              
269             L<Paws::CloudWatch>
270              
271             L<Paws::CloudWatch>
272              
273             L<Paws::CloudWatchEvents>
274              
275             L<Paws::CloudWatchLogs>
276              
277             L<Paws::CodeBuild>
278              
279             L<Paws::CodeCommit>
280              
281             L<Paws::CodeDeploy>
282              
283             L<Paws::CodePipeline>
284              
285             L<Paws::CodeStar>
286              
287             L<Paws::CognitoIdentity>
288              
289             L<Paws::CognitoIdp>
290              
291             L<Paws::CognitoSync>
292              
293             L<Paws::Config>
294              
295             L<Paws::CUR>
296              
297             L<Paws::DataPipeline>
298              
299             L<Paws::DAX>
300              
301             L<Paws::DeviceFarm>
302              
303             L<Paws::DirectConnect>
304              
305             L<Paws::Discovery>
306              
307             L<Paws::DMS>
308              
309             L<Paws::DS>
310              
311             L<Paws::DynamoDB>
312              
313             L<Paws::DynamoDBStreams>
314              
315             L<Paws::EC2>
316              
317             L<Paws::ECR>
318              
319             L<Paws::ECS>
320              
321             L<Paws::EFS>
322              
323             L<Paws::ElastiCache>
324              
325             L<Paws::ElasticBeanstalk>
326              
327             L<Paws::ElasticTranscoder>
328              
329             L<Paws::ELB>
330              
331             L<Paws::ELB>
332              
333             L<Paws::ELBv2>
334              
335             L<Paws::EMR>
336              
337             L<Paws::EMR>
338              
339             L<Paws::ES>
340              
341             L<Paws::Firehose>
342              
343             L<Paws::GameLift>
344              
345             L<Paws::Glacier>
346              
347             L<Paws::Glue>
348              
349             L<Paws::Greengrass>
350              
351             L<Paws::Health>
352              
353             L<Paws::IAM>
354              
355             L<Paws::ImportExport>
356              
357             L<Paws::Inspector>
358              
359             L<Paws::IoT>
360              
361             L<Paws::IoTData>
362              
363             L<Paws::Kinesis>
364              
365             L<Paws::KinesisAnalytics>
366              
367             L<Paws::KMS>
368              
369             L<Paws::Lambda>
370              
371             L<Paws::LexModels>
372              
373             L<Paws::LexRuntime>
374              
375             L<Paws::Lightsail>
376              
377             L<Paws::MachineLearning>
378              
379             L<Paws::MarketplaceCommerceAnalytics>
380              
381             L<Paws::MarketplaceEntitlement>
382              
383             L<Paws::MarketplaceMetering>
384              
385             L<Paws::MigrationHub>
386              
387             L<Paws::MobileHub>
388              
389             L<Paws::MTurk>
390              
391             L<Paws::OpsWorks>
392              
393             L<Paws::OpsWorksCM>
394              
395             L<Paws::Organizations>
396              
397             L<Paws::Pinpoint>
398              
399             L<Paws::Polly>
400              
401             L<Paws::RDS>
402              
403             L<Paws::RedShift>
404              
405             L<Paws::Rekognition>
406              
407             L<Paws::ResourceTagging>
408              
409             L<Paws::Route53>
410              
411             L<Paws::Route53Domains>
412              
413             L<Paws::S3>
414              
415             L<Paws::SDB>
416              
417             L<Paws::ServiceCatalog>
418              
419             L<Paws::SES>
420              
421             L<Paws::SES>
422              
423             L<Paws::Shield>
424              
425             L<Paws::Signin>
426              
427             L<Paws::SimpleDB>
428              
429             L<Paws::SimpleWorkflow>
430              
431             L<Paws::SMS>
432              
433             L<Paws::Snowball>
434              
435             L<Paws::SNS>
436              
437             L<Paws::SQS>
438              
439             L<Paws::SSM>
440              
441             L<Paws::StepFunctions>
442              
443             L<Paws::StorageGateway>
444              
445             L<Paws::STS>
446              
447             L<Paws::Support>
448              
449             L<Paws::WAF>
450              
451             L<Paws::WAFRegional>
452              
453             L<Paws::WorkDocs>
454              
455             L<Paws::WorkSpaces>
456              
457             L<Paws::XRay>
458              
459              
460             =head1 SERVICES CLASSES
461              
462             Each service in AWS (EC2, CloudFormation, SQS, SNS, etc) has a service class. The service class represents the properties that a web service has (how to call it, what methods it has, how to authenticate, etc). When a service class is instantiated with the right properties (region, if needed, credentials, caller, etc), it will be able to make calls to the service.
463              
464             Service classes are obtained through
465              
466             my $service_class = Paws->class_for_service('Service');
467             my $service_object = $service_class->new(region => '...', caller => ...)
468              
469             Although they are seldom needed. 99% of the time you want service objects directly obtained with the ->service method (read next section) since you have to write less code.
470              
471             =head1 SERVICE OBJECTS
472              
473             Each Service Object represents the ability to call methods on a service endpoint. Those endpoints are
474             either global, or bound to a region depending on the service. Also, each object can be customized
475             with a credential provider, that tells the object where to obtain credentials for the call (you can
476             get them from the environment, from the filesystem, from the AWS Instance Profile, STS, etc.
477              
478             To obtain a service object, call the C<< ->service >> method
479              
480             use Paws;
481             my $service = Paws->service('Service');
482              
483             You can pass extra parameters if the service is bound to a region:
484              
485             my $service = Paws->service('Service', region => 'us-east-1');
486              
487             These parameters are basically passed to the service class constructor
488              
489             =head1 AUTHENTICATION
490              
491             Service classes by default try to authenticate with a chained authenticator. The chained authenticator tries to first find credentials in your environment variables B<AWS_ACCESS_KEY> and B<AWS_SECRET_KEY> (note that B<AWS_ACCESS_KEY_ID> and B<AWS_SECRET_ACCESS_KEY> are also scanned for compatibility with the official SDKs). Second, it will look for credentials in the B<default> profile of the B<~/.aws/credentials> or the file in B<AWS_CONFIG_FILE> env variable (an ini-formatted file). Last, if no environment variables are found, then a call to retrieve Role credentials is done. If your instance is running on an AWS instance, and has a Role assigned, the SDK will automatically retrieve credentials to call any services that the instances Role permits.
492              
493             Please never burn credentials into your code. That's why the methods for passing an explicit access key and secret key are not documented.
494              
495             So, instantiating a service with
496              
497             my $ec2 = Paws->service('EC2', region => 'eu-west-1');
498              
499             we get an service object that will try to authenticate with environment, credential file, or an instance role.
500              
501             When instantiating a service object, you can also pass a custom credential provider:
502              
503             use Paws::Credential::STS;
504              
505             my $cred_provider = Paws::Credential::STS->new(
506             Name => 'MyName',
507             DurationSeconds => 900,
508             Policy => '{"Version":"2012-10-17","Statement":[{"Effect": "Allow","Action":["ec2:DescribeInstances"],"Resource":"*"}]}'
509             );
510             my $ec2 = Paws->service('EC2', credentials => $cred_provider, region => 'eu-west-1');
511              
512             In this example we instance a service object that uses the STS service to create temporary credentials that only let the service object call DescribeInstances.
513              
514             Paws bundles some pre-baked credential providers:
515              
516             L<Paws::Credential::ProviderChain> - Gets credentials from a list of providers, returning the first provider to return credentials
517              
518             L<Paws::Credential::Environment> - Gets credentials from environment variables
519              
520             L<Paws::Credential::File> - Gets credentials from AWS SDK config files
521              
522             L<Paws::Credential::InstanceProfile> - Gets credentials from the InstanceProfile (Role) of the running instance
523              
524             L<Paws::Credential::STS> - Gets temporary credentials from the Secure Token Service
525              
526             L<Paws::Credential::AssumeRole> - Gets temporary credentials with AssumeRole
527              
528             L<Paws::Credential::AssumeRoleWithSAML> - Gets temporary credentials with AssumeRoleWithSAML
529              
530             L<Paws::Credential::Explicit> - Gets credentials specified in the code
531              
532             =head1 Using Service objects (Calling APIs)
533              
534             Each API call is represented as a method call with the same name as the API call. The arguments to the call are passed as lists (named parameters) to the call. So, to call DescribeInstances on the EC2 service:
535              
536             my $result = $ec2->DescribeInstances;
537              
538             The DescribeInstances call has no required parameters, but if needed, we can pass them in (you can look them up in L<Paws::EC2> and see detail in L<Paws::EC2::DescribeInstances>
539              
540             my $result = $ec2->DescribeInstances(MaxResults => 5);
541              
542             If the parameter is an Array:
543              
544             my $result = $ec2->DescribeInstances(InstanceIds => [ 'i-....' ]);
545              
546             If the parameter to be passed in is a complex value (an object)
547              
548             my $result = $ec2->DescribeInstances(Filters => [ { Name => '', Value => '' } ])
549              
550             =head1 RETURN VALUES
551              
552             The AWS APIs return nested datastructures in various formats. The SDK converts these datastructures into objects that can then be used as wanted.
553              
554             my $private_dns = $result->Reservations->[0]->Instances->[0]->PrivateDnsName;
555              
556             =head1 CONFIGURATION
557              
558             Paws instances have a configuration. The configuration is basically a specification of values that will be passed to the service method each time
559             it's called
560              
561             # the credentials and the caller keys accept an instance or the name of a class as a
562             # string (the class will be loaded and the constructor of that class will be automatically called
563             my $paws1 = Paws->new(config => { credentials => MyCredProvider->new, region => 'eu-west-1' });
564             my $paws2 = Paws->new(config => { caller => 'MyCustomCaller' });
565            
566             # EC2 service with MyCredProvider in eu-west-1
567             my $ec2 = $paws1->service('EC2');
568              
569             # DynamoDB service with MyCustomCaller in us-east-1. region is needed because it's not in the config
570             my $ddb = $paws2->service('DynamoDB', region => 'us-east-1');
571              
572             # DynamoDB in eu-west-1 with MyCredProvider
573             my $other_ddb = $paws1->service('DynamoDB');
574              
575             The attributes that can be configured are:
576              
577             =head3 credentials
578              
579             Accepts a string which value is the name of a class, or an already instantiated object. If a string is passed, the class will be loaded, and the
580             constructor called (without parameters). Also, the resulting instance or the already instantiated object has to have the L<Paws::Credential> role.
581              
582             =head3 caller
583              
584             Accepts a string which value is the name of a class, or an already instantiated object. If a string is passed, the class will be loaded, and the
585             constructor called (without parameters). Also, the resulting instance or the already instantiated object has to have the L<Paws::Net::CallerRole> role.
586              
587             =head3 region
588              
589             A string representing the region that service objects will be instantiated with. Most services need a region specified, meaning that you will have to specify the desired region every time you call the B<service> method.
590              
591             my $cfn = Paws->service('CloudFormation', region => 'eu-west-1');
592              
593             Some services (like IAM) are global, so they don't need their region specified:
594              
595             my $iam = Paws->service('IAM');
596              
597             A special service is STS, which by default has a global endpoint, but you can also specify regional endpoints
598              
599             my $global_sts = Paws->service('STS');
600             my $regional_sts = Paws->service('STS', region => 'eu-west-1');
601              
602             =head3 endpoint
603              
604             Paws needs to send HTTP requests to different URLS (endpoints) depending on the service and the region. URLs are normally automatically derived by specifying the region, but for special cases, like pointing to "fake-sqs" or "fake-s3" services, you can:
605              
606             Paws->service('SQS', endpoint => 'http://localhost:3000', region => 'eu-west-1');
607              
608             Some services, like the MachineLearning predictor API want you to specify a custom endpoint:
609              
610             my $model = $ml->GetMLModel(MLModelId => $model_id);
611             my $predictor = Paws->service('ML', endpoint => $model->EndpointInfo->EndpointUrl, region => 'eu-west-1');
612             $predictor->...
613              
614             =head1 Pluggability
615              
616             =head2 Credential Provider Pluggability
617              
618             Credential classes need to have the Role L<Paws::Credential> applied. This obliges them to implement access_key, secret_key and session_token methods.
619             The obtention of this data can be customized to be retrieved whereever the developer considers useful (files, environment, other services, etc). Take
620             a look at the Paws::Credential::XXXX namespace to find already implemented credential providers.
621              
622             The credential objects' access_key, secret_key and session_token methods will be called each time an API call has to be signed.
623              
624             =head2 Caller Pluggability
625              
626             Caller classes need to have the Role L<Paws::Net::CallerRole> applied. This obliges them to implement the do_call method. Tests use this interface to
627             mock calls and responses to the APIs (without using the network).
628              
629             The caller instance is responsable for doing the network Input/Output with some type of HTTP request library, and returning the Result from the API.
630              
631             These callers are included and supported in Paws:
632              
633             L<Paws::Net::Caller>: Uses HTTP::Tiny. It's the default caller for Paws
634              
635             L<Paws::Net::MojoAsyncCaller>: Experimental asyncronous IO caller. Paws method calls return futures instead of results
636              
637             L<Paws::Net::LWPCaller>: Uses LWP. LWP supports HTTPS proxies, so Paws can call AWS from behind an HTTPS proxy.
638              
639             L<Paws::Net::FurlCaller>: Uses Furl: a lightning fast HTTP client
640              
641             =head1 Optimization
642              
643             =head2 Preloading services and operations
644              
645             Paws->preload_service($service)
646             Paws->preload_service($service, @methods)
647              
648             Paws manages a lot of objects that are loaded dynamically as needed. This causes high memory consumption if you do operations with Paws in a forked
649             environment because each child loads a separate copy of all the classes it needs to do the calls. Paws provides the preload_service operation. Call
650             it with the name of the service before forking off so your server can benefit from copy on write memory sharing. The parent class will load all the
651             classes needed so that child processes don't need to load them.
652              
653             Some classes have lot's of calls, so preloading them can be quite expensive. If you call preload_service with a list of the methods you will call,
654             it will only load classes needed for those calls. This is specially useful for L<Paws::EC2>, for example.
655              
656             Preloading doesn't change the usage of Paws. That means that all services and methods still work without any change, just that if they're not preloaded
657             they'll be loaded at runtime.
658              
659             =head2 Immutabilizing classes
660              
661             Paws objects are programmed with L<Moose> (the Modern Perl Object Framework). Moose objects can be immutibilized so that method calls perform better,
662             at the cost of startup time. If you deem your usage of Paws to be long-lived, you can call
663              
664             Paws->default_config->immutable(1);
665              
666             as early as possible in the code. Very important that the immutable flag be activated before calling preload_service.
667              
668             =head1 AUTHOR
669              
670             Jose Luis Martinez
671             CPAN ID: JLMARTIN
672             CAPSiDE
673             jlmartinez@capside.com
674              
675             =head1 SEE ALSO
676              
677             L<http://aws.amazon.com/documentation/>
678              
679             L<https://github.com/pplu/aws-sdk-perl>
680              
681             =head1 BUGS and SOURCE
682              
683             The source code is located here: https://github.com/pplu/aws-sdk-perl
684              
685             Please report bugs to: https://github.com/pplu/aws-sdk-perl/issues
686              
687             =head1 COPYRIGHT and LICENSE
688              
689             Copyright (c) 2015 by Jose Luis Martinez Torres
690              
691             This code is distributed under the Apache 2 License. The full text of the license can be found in the LICENSE file included with this module.
692              
693             =head1 CONTRIBUITIONS
694              
695              
696             CAPSiDE (http://www.capside.com) for letting Paws be contributed in an open source model
697             and giving me time to build and maintain it regularly
698              
699             Luis Alberto Gimenez (@agimenez) for
700             - The git-fu cleaning up the "pull other sdks" code
701             - Credential Providers code
702             - Fixes for users that have no HOME env variable
703             - FileCaller to fully mock responses
704              
705             Srinvas (@kidambisrinivas) for testing, bug reporting and fixing
706              
707             juair10 for corrections and testing
708              
709             CHORNY for CPAN and cpanfile packaging corrections
710              
711             Iñigo Tejedor for service endpoint resolution based on rules
712              
713             codehead for helping fix SQS Queue Maps
714              
715             mbartold for helping fix SQS MessageBatch functionality
716              
717             coreymayer for reporting bug in RestXmlCaller
718              
719             arc (Aaron Crane) for documentation patches
720              
721             dtikhonov for LWP Caller and bug reporting/fixing
722              
723             vivus-ignis for DynamoDB bug reporting and test scripts for DynamoDB
724              
725             karenetheridge for bug reporting, pull requests and help
726              
727             ioanrogers for fixing unicode issues in tests
728              
729             ilmari for fixing issues with timestamps in Date and X-Amz-Date headers,
730             test fixes and 5.10 support fixes, documentation issue fixes for S3,
731             CloudFront and Route53, help with number stringification
732              
733             stevecaldwell77 for contributing support for temporary credentials in S3
734              
735             Ryan Olson (BeerBikesBBQ) for contributing documentation fixes
736              
737             Roger Pettett for testing and contributing fixes for tests on MacOSX
738              
739             Henri Yandell for help with licensing issues
740              
741             Oriol Soriano (@ureesoriano) for contribution to API builders
742              
743             H. Daniel Cesario (@maneta) for devel setup instructions on RH and MacOSX
744              
745             Glen van Ginkel for contributions to get S3 working
746              
747             Javier Arellano for discovering Tagging bug
748              
749             Ioan Rogers for contributing AssumeRoleWithSAML with ADFS auth example
750              
751             Miquel Soriano for reporting a bug with DescribeAutoScalingGroups
752              
753             Albert Bendicho (wiof) for contributing better retry logic
754              
755             Brian Hartsock for better handling of XMLResponse exceptions
756              
757             rpcme for reporting various bugs in the SDK
758              
759             glenveegee for lots of work sorting out the S3 implementation
760              
761             Grinzz for many bugs, suggestions and fixes
762              
763             Dakkar for solving issues with parameter passing
764              
765             Arthur Axel fREW Schmidt for speeding up credential refreshing
766              
767             PopeFelix for solving issues around S3 and MojoAsyncCaller
768              
769             meis for contributing Paws::Credential::Explicit
770              
771             sven-schubert for contributing fixes to RestXML services,
772             working on fixing S3 to work correctly.
773              
774             SeptamusNonovant for fixing paginators in non-callback mode
775              
776             gadgetjunkie for contributing the ECS credential provider
777              
778              
779             =cut