Paws the XV (Still Some Way to Go)
In my last post I got nicely snookered by the S3 call 'GetBucketLocation' which was one of the call that had a 'todo' test.
The XML coming back from ASW is correct
<?xml version="1.0" encoding="UTF-8"?> <LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-0301/"> EU </LocationConstraint> but no matter what I tried on 'XML::Simple' I could not get it to parse just the way I want though I did get very close with this
my $xml = XML::Simple->new(
ForceArray => qr/^(?:item|Errors)/i,
KeyAttr => '',
SuppressEmpty => undef,
++ KeepRoot => 1
);
return $xml->parse_string($data);
and I did get this in the end
bless( {
'LocationConstraint' => 'eu-west-2',
'_request_id' => 'ECDB8CF1EB9699A2'
}, 'Paws::S3::GetBucketLocationOutput' );
but I then get about 147 fails as that changes all the XML that is being parsed.
Failed 147/9641 subtests (5 TODO tests unexpectedly succeeded)
So I can't just arbitrarily change the parser settings but I might be able to change things is botocore to tell me to use that KeepRoot on the XML Parse but I that is a dead end as well as I am not sending any meta into the call that does the parseing
$self->unserialize_response( $content )
I was thinking I could fix the boto code up to add in an extra 'root' tag to the body of my 'XML' like this
"requestUri":"/{Bucket}?location"
},
"input":{"shape":"GetBucketLocationRequest"},
- "output":{"shape":"GetBucketLocationOutput"},
+ "output":{"shape":"GetBucketLocationResponse"},
"documentationUrl":"http://docs.amazonwebservices.com/AmazonS3/latest
...
+ "GetBucketLocationResponse":{
+ "type":"structure",
+ "members":{
+ "LocationConstraint":{
+ "shape":"GetBucketLocationOutput",
+ "location":"content",
+ "documentation":"<p/>"
+ }
+ }
+ },
"GetBucketLocationOutput":{
"type":"structure",
"members":{
"LocationConstraint":{
"shape":"BucketLocationConstraint",
+ "location":"content",
"documentation":"<p/>"
}
Not all that did was recreate the same problem but with just a minor change in the error output;
Attribute (LocationConstraint) does not pass the type constraint because: Validation failed for 'Paws::S3::GetBucketLocationOutput' with value eu-west-2 (not isa Paws::S3::GetBucketLocationOutput) at /wwwveh/lib/x86_64-linux-thread-multi/Moose/Object.pm line 24
and then I tried this
+ "LocationConstraint":{
+ "shape":"BucketLocationConstraint",
"location":"content",
but without the root in there I just get this again
can't use string ("eu-west-2") as a HASH ref while "strict refs" in use at /home/scolesj/aws-sdk-perl/lib/Paws/Net/RestXMLResponse.pm line 336.
The problem of course lies in the parser as it is cutting off the 'Root' node and no matter how much I am playing about with boto I am not going to solve the problem of the XML data coming back with only a 'Root' node.
Maybe a new trait in boto to tell me that the expected result for the 'attribure' in the response is the parsed content?
Maybe something like this in Boto;
"GetBucketLocationOutput":{
"type":"structure",
"members":{
"LocationConstraint":{
"location":"content",
"locationName":"LocationConstraint",
"shape":"BucketLocationConstraint",
"documentation":"<p/>"
}
}
},
"location":"content", will tell me to just look at the parsed content of the XML and I think I would have to add this new 'Trait' to 'API.pm'
package Paws::API::Attribute::Trait::ParamIsContent;
use Moose::Role;
use Moose::Util;
Moose::Util::meta_attribute_alias('ParamIsContent');
And like before a change to the template.
[%- ELSIF (shape.members.$param_name.location == 'uri') %], traits => ['ParamInURI'], uri_name => '[% shape.members.$param_name.locationName -%]'
[%- ELSIF (shape.members.$param_name.location == 'content') %], traits => ['ParamInContent']
[%- ELSE %], traits => ['NameInRequest'], request_name => '[% shape.members.$param_name.locationName %]'[%- END -%][%- END -%]
and give the build a run again;
carton exec builder-bin/gen_classes.pl --classes botocore/botocore/data/s3/2006-03-01/service-2.json Processing botocore/botocore/data/s3/2006-03-01/service-2.json Complex accessor NextMarker || Contents[-1].Key at builder-lib/Paws/API/Builder.pm line 1086. Complex accessor NextMarker || Contents[-1].Key at builder-lib/Paws/API/Builder.pm line 1086.
and a look in 'auto-lib/Paws/S3/GetBucketLocationOutput.pm'
package Paws::S3::GetBucketLocationOutput;
use Moose;
has LocationConstraint => (is => 'ro', isa => 'Str', traits => ['ParamIsContent']);
has _request_id => (is => 'ro', isa => 'Str');
1;
Which is nice but that gives me a 'trait' on a attribute which I unfortunately I cant really use as I have to work with this line of code;
if ($ret_class->can('_stream_param')) {
$unserialized_struct = {}
} else {
So I need to get my 'content' as part of the 'class' not an attribute of the 'class'.
So more to do for my next post. Darn.
Leave a comment