Paws XXXXIX (Very Close)

Finally things were looking my way. I plowed thought the remaining CloudFront actions and got them all to work without any more changes to Paws.

In the end I checked in 30+ new tests cases and over 2k of tests the other day. So I can safely say that 'CloudFront' is fully operational.

That leaves only 'Route53' to look and for me this is somewhat problematic. The Route53 api deals with 'Domains', 'Checks', 'Hosts', 'Traffic' and such. To test 90% of the actions in this API you will need

  1. Have at least one registered DNS domains to start
  2. Know how to create a Hosts for a Domain
  3. Know how to config a Host for a Domain and most importantly
  4. Have some spare cash to pay for all the actions you are mucking with

As I fail on all 4 of the above I am not comfortable with creating working scrips for this API.

I am still going to forge ahead with dummy/invalid data though the actions will most likely fail I can still get the XML correct which is half the battle.

Starting out I quickly ran into a bug with 'ChangeTagsForResource'.


$ListObjectsV2Output = $s3->ChangeTagsForResource(
 ResourceId   => 'MyTagResourceId',
  ResourceType => 'healthcheck',
  AddTags      => [
    {
      Key   => 'MyTagKey',      
      Value => 'MyTagValue',  
    },
    {
      Key   => 'MyTagKey',     
      Value => 'MyTagValue', 
    },
  ],                          
  RemoveTagKeys => [
    'MyTagKey', 'Key2'            
  ],                          
);

The 'RemoveTagKeys' was failing and my '_to_xml' sub in 'RestXMLCaller.pm' dose not handle an array directly. Funny we have yet to run into this so far along with some 300 actions all working.

To first this I had to extend the code to capture just a simple an 'ARRAY' but even with that I needed to traslated that into some sort of XML and on the API doc what I am looking for is;


 <RemoveTagKeys>
      <Key>string</Key>
   </RemoveTagKeys>

so I checked the attribute in the generated class;


      has RemoveTagKeys => (is => 'ro', isa => 'ArrayRef[Str|Undef]' );
 

and unfortunerly there is nothing I can use there to get that 'Key' for my tag. To be 100% sure I checked Boto which led me here


 "RemoveTagKeys":{
          "shape":"TagKeyList",

and then here


 "TagKeyList":{
      "type":"list",
      "member":{
        "shape":"TagKey",
        "locationName":"Key"
      },
      "max":10,
      "min":1
    },

ah there is something I can play with there but is is rather buried but I at least have that 'locationName'. Another dive into the templates.

So I played in there a bit found this hash was being returned;


{
          'min' => 1,
          'example_code' => '    [
      \'MyTagKey\', ...    # max: 128
    ]',
          'max' => 10,
          'member' => {
                        'locationName' => 'Key',
                        'shape' => 'TagKey'
                      },
          'perl_type' => 'ArrayRef[Str|Undef]',
          'type' => 'list'
        };

and with this patch to the template


  [% IF (shape.members.$param_name.locationName != '' ||  member.member.locationName != param_name) %]
  [%- IF (shape.members.$param_name.locationName == 'x-amz-meta-') %]
+  [%- ELSIF (shape.members.$param_name.locationName and shape.members.$param_name.locationName != param_name); traits.push('NameInRequest'); %], request_name => '[% shape.members.$param_name.locationName %]'
+  [%- ELSIF (member.member.locationName != param_name);            traits.push('NameInRequest'); %], request_name => '[% member.member.locationName %]'
  [%- END %]
  [%- END %]

It kinda worked with this result;


   use Moose;
      has AddTags => (is => 'ro', isa => 'ArrayRef[Paws::Route53::Tag]', request_name => 'Tag', traits => ['NameInRequest'] );
      has RemoveTagKeys => (is => 'ro', isa => 'ArrayRef[Str|Undef]'  , request_name => 'Key', traits => ['NameInRequest'] );

Which I think I can work with;

I eventullay got it to work with this patch


 if ( ref $attribute_value ) {
                my $location =
                    $attribute->does('NameInRequest')
                  ? $attribute->request_name
                  : $attribute->name;
                if ( $attribute->does('Flatten') ) {
                    $xml .= $self->_to_xml($attribute_value);
                }
                elsif ( $call->can('_namspace_uri') ) {
                    $xml .= sprintf '<%s xmlns="%s">%s</%s>', $location,
                      $call->_namspace_uri(), $self->_to_xml($attribute_value),
                      $location;
                }
+                elsif (ref($attribute_value) eq 'ARRAY'){
+                    my $location = $attribute->name;
+                   my $list_name = $attribute->name;
+
+                    $location =  $attribute->request_name
+                     if ( $attribute->can('request_name'));
+                    my $temp_xml  = (
+                  join '',
+                map {
+                 sprintf '<%s>%s</%s>', $location,
+                   , ref($_) ? $self->_to_xml($_) : $_,
+               $location
+         } @{ $attribute_value }
+       );
+     $temp_xml = "<$list_name>$temp_xml</$list_name>"
+      if ( $location ne $list_name );
+ $xml .= $temp_xml;
                }
                else {

Lets see If I killed anything else as I did change one of the templates. So a regenration and retests I got



Failed 104/1792 subtests

on the 09_requests.t test case; Ouch!

Most seem to be like this

not ok 1717 - Got content eq from request
#   Failed test 'Got content eq from request'
#   at t/09_requests.t line 123.
#          got: '< xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><TagSet>
#     expected: '<Tagging xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><TagSet>

Going back a bit I had a look in generated class ' PutPublicAccessBlock' and found that the 'request_name' was empty;


          has PublicAccessBlockConfiguration => (is => 'ro', isa => 'Paws::S3::PublicAccessBlockConfiguration'
   , request_name => '', traits => ['NameInRequest']  , required => 1);

So something in the template again; That request_name has to be filled in or the trait not applied;

I did a quick change to the template


 [%- ELSIF (member.member.locationName != param_name);            traits.push('NameInRequest'); %], request_name => '[% member.member.locationName %]'
  [%- ELSIF ( member.member.locationName != '' and member.member.locationName != param_name);            traits.push('NameInRequest'); %], request_name => '[% ember.member.locationName %]'

to account for that and now I am only getting about 20 errors when I run both 09 and 10 tests suites.

I am not going to worry much about those as at first glance they mostly look like problems with the tests and not the actual code I generated.

I manged to plow though most of the Route53 commands and the all now pass valid XML tests so I think my Paws RestXML API journey is coming to an end.


yhboo4.jpg

2 Comments

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations