aws-sdk-perl icon indicating copy to clipboard operation
aws-sdk-perl copied to clipboard

SQS GetQueueAttributes doesn't work with elasticmq for some reason.

Open mschout opened this issue 5 years ago • 3 comments

Not sure whats going on here, but for some reason, we have been unable to get GetQueueAttributes working with Paws against elasticmq (latest version).

The following call is what we are trying to make:

aws --region='us-east-1' --profile=testing sqs get-queue-attributes \
  --queue-url=http://localhost:33369/queue/my-queue \
  --endpoint=http://localhost:33369 \
  --attribute-names All

We get results from the AWS cli:

{
    "Attributes": {
        "VisibilityTimeout": "30",
        "DelaySeconds": "0",
        "ReceiveMessageWaitTimeSeconds": "0",
        "ApproximateNumberOfMessages": "0",
        "ApproximateNumberOfMessagesNotVisible": "0",
        "ApproximateNumberOfMessagesDelayed": "0",
...
    }
}

But when we run the request under Paws (and I tried v0.34 through v0.41), we do not get any attributes returned. The exact same call works against Live AWS, so not sure if this is something elasticmq specific or Paws specific. We are able to get an attributes result using Amazon::SQS::Simple for example, so it seems like this should work with elasticmq.

Paws code:

#!/usr/bin/env perl

use Paws;
use Data::Dumper;

my $sqs = Paws->service('SQS',
  region   => 'us-east-1',
  endpoint => 'http://localhost:33369',
);

my $queue_url = 'http://localhost:33369/queue/my-queue';

my $res = $sqs->GetQueueAttributes(
  QueueUrl       => $queue_url,
  AttributeNames => ['All']
);

print Dumper($res);

I ran this through the debugger with a breakpoint at HTTP::Tiny::request() and the response payload from elasticmq is:

$VAR1 = {
          'success' => 1,
          'protocol' => 'HTTP/1.1',
          'headers' => {
                         'content-type' => 'text/plain; charset=UTF-8',
                         'server' => 'akka-http/10.1.3',
                         'content-length' => '350',
                         'date' => 'Sat, 31 Aug 2019 02:01:00 GMT'
                       },
          'content' => '<GetQueueAttributesResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
            <GetQueueAttributesResult>
              
            </GetQueueAttributesResult>
            <ResponseMetadata>
              <RequestId>00000000-0000-0000-0000-000000000000</RequestId>
            </ResponseMetadata>
          </GetQueueAttributesResponse>',
          'status' => '200',
          'reason' => 'OK',
          'url' => 'http://localhost:33369/'
        };

So it's able to communicate with elasticmq apparently, but we got an empty result back.

Like I said, not sure if the problem is on elasticmq or Paws side, but if I use the AWS cli for example, the attributes are included so seems that Paws is doing something different here.

mschout avatar Aug 31 '19 02:08 mschout

Issues is with Paws side. You can temporarily fix this by adding NameInRequest traits to AttributeNames.

simply replace the following line in SQS/GetQueueAttributes.pm

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

with

    has AttributeNames => (is => 'ro', isa => 'ArrayRef[Str|Undef]', traits => ['NameInRequest'], request_name => 'AttributeName');

Prajithp avatar Aug 31 '19 05:08 Prajithp

Thanks @Prajithp !

mschout avatar Aug 31 '19 23:08 mschout

@pplu Does this change affect any other services? All tests were executed, but still not sure.

diff --git a/templates/query/callargs_class.tt b/templates/query/callargs_class.tt
index ed7e1e3..f5c98bb 100644
--- a/templates/query/callargs_class.tt
+++ b/templates/query/callargs_class.tt
@@ -5,7 +5,9 @@ package [% c.api %]::[% operation.name %];
 [% FOREACH param_name IN shape.members.keys.sort -%]
   [%- member = c.shape(shape.members.$param_name.shape) -%]
   has [% param_name %] => (is => 'ro', isa => '[% member.perl_type %]'
-  [%- IF (shape.members.${param_name}.locationName) %], traits => ['NameInRequest'], request_name => '[% shape.members.${param_name}.locationName %]' [% END %]
+  [%- IF (shape.members.${param_name}.locationName) %], traits => ['NameInRequest'], request_name => '[% shape.members.${param_name}.locationName %]'
+    [%- ELSIF (member.type == 'list' and member.member.locationName.defined) %], traits => ['NameInRequest'], request_name => '[% member.member.locationName %]'
+  [%- END -%]
   [%- IF (shape.members.$param_name.streaming == 1) %], traits => ['ParamInBody'][% END %]
   [%- IF (c.required_in_shape(shape,param_name)) %], required => 1[% END %]);
 [% END %]

Prajithp avatar Oct 09 '19 12:10 Prajithp