File Coverage

lib/Amazon/S3/BucketV2.pm
Criterion Covered Total %
statement 51 91 56.0
branch 2 22 9.0
condition 2 24 8.3
subroutine 13 16 81.2
pod 1 4 25.0
total 69 157 43.9


line stmt bran cond sub pod time code
1             package Amazon::S3::BucketV2;
2              
3 2     2   10 use strict;
  2         4  
  2         113  
4 2     2   56 use warnings;
  2         5  
  2         159  
5              
6 2     2   13 use Amazon::S3::Constants qw(:all);
  2         4  
  2         751  
7 2     2   12 use Amazon::S3::Util qw(:all);
  2         2  
  2         207  
8              
9 2     2   13 use Carp;
  2         2  
  2         127  
10 2     2   9 use Data::Dumper;
  2         2  
  2         135  
11 2     2   10 use English qw(-no_match_vars);
  2         3  
  2         18  
12 2     2   678 use List::Util qw(pairs);
  2         4  
  2         115  
13 2     2   8 use Scalar::Util qw(reftype);
  2         2  
  2         93  
14              
15 2     2   7 use parent qw(Amazon::S3::Bucket);
  2         3  
  2         12  
16              
17             our $VERSION = '2.0.2'; ## no critic (RequireInterpolation)
18              
19             ######################################################################
20             our @GET_OBJECT_METHODS = (
21             ######################################################################
22             get_object_acl => 'acl',
23             get_object_attributes => 'attributes',
24             get_object_legal_hold => 'legal-hold',
25             get_object_lock_configuration => 'object-lock',
26             get_object_retention => 'retention',
27             get_object_tagging => 'tagging',
28             get_object_torrent => 'torrent',
29             get_public_access_block => 'publicAccessBlock',
30             );
31              
32             create_methods(
33             type => 'object',
34             method => 'GET',
35             method_def => \@GET_OBJECT_METHODS
36             );
37              
38             ######################################################################
39             our @HEAD_OBJECT_METHODS = ( get_object_head => 'head', );
40             ######################################################################
41              
42             create_methods(
43             type => 'object',
44             method => 'HEAD',
45             method_def => [ head_object => $EMPTY ]
46             );
47              
48             create_methods(
49             type => 'bucket',
50             method => 'HEAD',
51             method_def => [ head_bucket => $EMPTY ]
52             );
53              
54             ######################################################################
55             our @GET_BUCKET_METHODS = (
56             ######################################################################
57             get_bucket_accelerate_configuration => 'accelerate',
58             get_bucket_acl => 'acl',
59             get_bucket_analytics => 'analytics',
60             get_bucket_cors => 'cors',
61             get_bucket_encryption => 'encryption',
62             get_bucket_intelligent_tiering_configuration => 'intelligent_tiering',
63             get_bucket_inventory_configuration => 'inventory',
64             get_bucket_lifecycle_configuration => 'lifecycle',
65             get_bucket_location => 'location',
66             get_bucket_logging => 'logging',
67             get_bucket_metrics_configuration => 'metrics',
68             get_bucket_notification_configuration => 'notification',
69             get_bucket_ownership_controls => 'ownershipControls',
70             get_bucket_policy => 'policy',
71             get_bucket_policy_status => 'policyStatus',
72             get_bucket_replication => 'replication',
73             get_bucket_request_payment => 'requestPayment',
74             get_bucket_tagging => 'tagging',
75             get_bucket_versioning => 'versioning',
76             get_bucket_website => 'website',
77             );
78              
79             create_methods(
80             type => 'bucket',
81             method => 'GET',
82             method_def => \@GET_BUCKET_METHODS,
83             );
84              
85             #######################################################################
86             our @PUT_BUCKET_METHODS = (
87             #######################################################################
88             put_bucket_intelligent_tiering_configuration => 'intelligent-tiering',
89             put_bucket_cors => 'cors',
90             put_bucket_replication_configuration => 'replication',
91             put_bucket_versioning => 'versioning',
92             put_bucket_encryption => 'encryption',
93             put_bucket_lifecycle_configuration => 'lifecycle',
94             put_bucket_lifecycle => 'lifecycle',
95             put_bucket_tagging => 'tagging',
96             );
97              
98             create_methods(
99             type => 'bucket',
100             method => 'PUT',
101             method_def => \@PUT_BUCKET_METHODS
102             );
103              
104             ######################################################################
105             our @PUT_OBJECT_METHODS = (
106             #######################################################################
107             put_object => $EMPTY,
108             put_object_acl => 'acl',
109             put_object_tagging => 'tagging',
110             put_object_retention => 'retention',
111             put_object_legal_hold => 'legal-hold',
112             put_object_lock_configuraiton => 'lock-object',
113             put_public_access_block => 'publicAccessBlock',
114             restore_object => sub {
115             return { method => 'POST', api => 'restore' };
116             },
117             upload_part => $EMPTY,
118             upload_part_copy => $EMPTY,
119             );
120              
121             create_methods(
122             type => 'object',
123             method => 'PUT',
124             method_def => \@PUT_OBJECT_METHODS,
125             );
126              
127             ######################################################################
128             our @DELETE_OBJECT_METHODS = (
129             ######################################################################
130             delete_object => $EMPTY,
131             delete_objects => sub {
132             return { method => 'POST', api => 'delete' };
133             },
134             delete_object_tagging => 'tagging',
135             );
136              
137             create_methods(
138             type => 'object',
139             method => 'DELETE',
140             method_def => \@DELETE_OBJECT_METHODS,
141             );
142              
143             ######################################################################
144             our @DELETE_BUCKET_METHODS = (
145             ######################################################################
146             delete_bucket => $EMPTY,
147             delete_bucket_analytics_configuration => 'analytics',
148             delete_bucket_cors => 'cors',
149             delete_bucket_encryption => 'encryption',
150             delete_bucket_intelligent_tiering => 'intelligent-tiering',
151             delete_bucket_inventory_configuration => 'inventory',
152             delete_bucket_lifecycle => 'lifecycle',
153             delete_bucket_metrics_configuration => 'metrics',
154             delete_bucket_ownership_controls => 'ownershipControls',
155             delete_bucket_policy => 'policy',
156             delete_bucket_replication => 'replication',
157             delete_bucket_tagging => 'tagging',
158             delete_bucket_website => 'website',
159             delete_public_access_block => 'publicAccessBlock',
160             );
161              
162             create_methods(
163             type => 'bucket',
164             method => 'DELETE',
165             method_def => \@DELETE_BUCKET_METHODS
166             );
167              
168             ########################################################################
169             sub new {
170             ########################################################################
171 0     0 1 0 my ( $class, @args ) = @_;
172              
173 0         0 return $class->SUPER::new(@args);
174             }
175              
176             ########################################################################
177             sub to_camel_case {
178             ########################################################################
179 130     130 0 136 my ($method) = @_;
180              
181 130         213 return join $EMPTY, map { ucfirst $_ } split /_/xsm, $method;
  426         643  
182             }
183              
184             ########################################################################
185             # send_request()
186             ########################################################################
187             # This is a general purpose method to send requests that may include an
188             # XML payload. These requests may also accept headers or query string
189             # parameters.
190             #
191             # args is a hash ref or list of key/value pairs
192             # api => name of the API to invoke (example: 'versioning')
193             # content_key => optional root element for XML serialzation
194             # headers => optional headers - create a Content-MD5 key in the headers
195             # object if you want to add the MD5 value
196             # bucket => optional bucket name
197             # key => optional key value for APIs that accept a key
198             # data => optional object that will be converted to an XML payload
199             # method => HTTP method
200             #
201             # NOTES:
202             # 1. If the 'data' object is included, the default method is 'PUT'
203             # 2. If no 'data' object is included, the default method is 'GET'
204             # 3. If 'content_key' is not provided when including a 'data' object
205             # the method will attempt to guess the root element (content_key)
206             # when serializing the data object to XML. If you include
207             # additional elements to be used as query string parameters,
208             # you should specify 'content_key'..
209             ########################################################################
210             sub send_request {
211             ########################################################################
212 0     0 0 0 my ( $self, @args ) = @_;
213              
214 0         0 my $parameters = get_parameters(@args);
215              
216 0         0 my $account = $self->account;
217              
218 0         0 my $headers = delete $parameters->{headers};
219 0   0     0 $headers //= {};
220              
221 0         0 my $bucket = delete $parameters->{bucket};
222              
223 0   0     0 $bucket //= $self->bucket;
224              
225 0 0       0 croak 'no bucket'
226             if !$bucket;
227              
228 0   0     0 my $key = delete $parameters->{key} // $EMPTY;
229              
230 0         0 my $api = delete $parameters->{api};
231              
232 0 0       0 croak 'no api'
233             if !defined $api;
234              
235 0         0 my $path = delete $parameters->{path};
236              
237 0         0 my $method = delete $parameters->{method};
238              
239             # see if we need to send an XML payload
240 0         0 my $data = delete $parameters->{data};
241              
242 0 0       0 if ($data) {
243 0         0 my $content_key = delete $parameters->{content_key};
244              
245             # if we are sending data, include MD5 by default
246 0         0 my $md5 = delete $parameters->{md5};
247 0   0     0 $md5 //= $TRUE;
248              
249 0 0       0 if ( !$content_key ) {
250 0         0 ($content_key) = keys %{$parameters};
  0         0  
251             }
252              
253 0         0 $data = create_xml_request($data);
254              
255 0 0 0     0 if ( $md5 || exists $headers->{'Content-MD5'} ) {
256 0         0 set_md5_header( data => $data, headers => $headers );
257             }
258             }
259              
260             # create the URI from bucket, key, api and possibly additional parameters
261 0   0     0 $path //= sprintf '%s/%s?%s', $bucket, $key, $api;
262              
263 0 0       0 if ( keys %{$parameters} ) {
  0         0  
264 0         0 my $query_string = create_query_string( %{$parameters} );
  0         0  
265              
266 0 0       0 if ( $path !~ /[?]$/xsm ) {
267 0         0 $query_string = "&$query_string";
268             }
269              
270 0         0 $path .= $query_string;
271             }
272              
273 0 0 0     0 return $account->_send_request(
274             { region => $self->region,
275             method => $method // 'GET',
276             path => $path,
277             headers => $headers,
278             $data ? ( data => $data ) : (),
279             }
280             );
281             }
282              
283             ########################################################################
284             sub create_methods {
285             ########################################################################
286 16     16 0 46 my (%args) = @_;
287              
288 16         26 my ( $type, $method, $method_def ) = @args{qw( type method method_def)};
289              
290 2     2   2132 no strict 'refs'; ## no critic
  2         5  
  2         672  
291              
292 16         14 foreach my $p ( pairs @{$method_def} ) {
  16         158  
293 130         172 my ( $sub_name, $api ) = @{$p};
  130         214  
294              
295 130 100 66     187 if ( ref($api) && reftype($api) eq 'CODE' ) {
296 4         8 my $api_params = $api->();
297 4         8 ( $method, $api ) = @{$api_params}{qw(method api)};
  4         8  
298             }
299              
300             my $anon = sub {
301 0     0   0 my ( $self, %args ) = @_;
302              
303 0         0 my ( $key, $body, $uri_params, $headers ) = @args{qw(key body uri_param headers)};
304 0   0     0 $uri_params //= {};
305              
306             return $self->send_request(
307             method => $method,
308             api => $api,
309             headers => $headers,
310             $key ? ( key => $key ) : (),
311             $body ? ( data => $body ) : (),
312 0 0       0 %{$uri_params},
  0 0       0  
313             );
314 130         561 };
315              
316 130         149 $sub_name = sprintf 'Amazon::S3::Bucket::%s', to_camel_case($sub_name);
317 130         672 *{$sub_name} = $anon;
  130         544  
318             }
319              
320 16         77 return;
321             }
322              
323             1;
324              
325             __END__