aws / aws-sdk-net

The official AWS SDK for .NET. For more information on the AWS SDK for .NET, see our web site:

Home Page:http://aws.amazon.com/sdkfornet/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SQS 3.7.201.0+ GetQueueAttributesAsync with "All" does not work when trying to fetch queue attributes

ymekesser opened this issue · comments

Describe the bug

When trying to retrieve all queue attributes using an AmazonSQSClient, no attributes are returned:
await sqsClient.GetQueueAttributesAsync(queueUrl, new List<string> { "All" })

This should be the equivalent of the aws cli call: aws sqs get-queue-attributes --queue-url <queueUrl> --attribute-names All

If retrieving specific attributes, e.g.
await sqsClient.GetQueueAttributesAsync(queueUrl, new List<string> { "QueueArn" })
It does successfully return the requested attributes.

I can see this behaviour with the AWSSDK.SQS package starting from version 3.7.201.0. The previous version, 3.7.200.67, correctly returns all attributes.

Disclaimer: I did not test this with an actual SQS queue hosted on AWS. I am running a local docker image of elasticmq. Despite this, the above call should work the same as earlier versions and the CLI.

Expected Behavior

await sqsClient.GetQueueAttributesAsync(queueUrl, new List<string> { "All" })
Response contains all available queue attributes.

Current Behavior

await sqsClient.GetQueueAttributesAsync(queueUrl, new List<string> { "All" })
Response contains no attributes.

Reproduction Steps

I'm testing this with a local image of elasticmq. Excerpt from my docker-compose:

  sqs:
    image: softwaremill/elasticmq-native
    ports:
      - 9324:9324
      - 9325:9325
    volumes:
      - ./elasticmq.conf:/opt/elasticmq.conf

Minimal code to reproduce the issue:

using Amazon.Runtime;
using Amazon.SQS;
using Amazon.SQS.Model;

var sqsClient = new AmazonSQSClient(
    new AnonymousAWSCredentials(),
    new AmazonSQSConfig
    {
        ServiceURL = "http://localhost:9324",
        UseHttp = true,
    });

sqsClient.Config.Validate();

var queues = await sqsClient.ListQueuesAsync(new ListQueuesRequest());
Console.WriteLine($"Queues found: {string.Join(", ", queues.QueueUrls)}");
// Queues found: ...

var queueUrl = "http://sqs:9324/000000000000/inbound-message-queue";
var attributeSelectorAll = new List<string> { "All" };
var attributeSelectorArn = new List<string> { "QueueArn" };

var queueAttributesAll = await sqsClient.GetQueueAttributesAsync(queueUrl, attributeSelectorAll);
var queueAttributesArn = await sqsClient.GetQueueAttributesAsync(queueUrl, attributeSelectorArn);

Console.WriteLine($"No. of attributes found (All): {queueAttributesAll.Attributes.Count}");
// No. of attributes found (All): 0   <--- should be >0
Console.WriteLine($"No. of attributes found (Arn): {queueAttributesArn.Attributes.Count}");
// No. of attributes found (Arn): 1

Console.WriteLine($"ARN found (All): {queueAttributesAll.QueueARN}");
// ARN found (All):      <--- no response
Console.WriteLine($"ARN found (Arn): {queueAttributesArn.QueueARN}");
// ARN found (Arn): arn:aws:sqs:us-east-1:000000000000:inbound-message-queue

Console.WriteLine("Done");

Possible Solution

No response

Additional Information/Context

No response

AWS .NET SDK and/or Package version used

AWSSDK.SQS 3.7.201.0+

Targeted .NET Platform

.Net 8.0

Operating System and version

Windows 11

Version 3.7.201.0 of the SQS package added support for the AWS JSON wire protocol, so we switched the .NET SDK to always use it as it's more efficient than the protocol used before (which was based on XML).

I tried your example and it looks like elasticmq is returning an XML response for GetQueueAttributes:

PS> aws sqs get-queue-attributes --queue-url http://localhost:9324/000000000000/test-localhost-foo1 --attribute-names All --endpoint-url http://localhost:9324 --debug

DEBUG - Response body:
b'<GetQueueAttributesResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">...</GetQueueAttributesResponse>'

I'm not sure why (and I'm following up internally), but the CLI seems to be falling back to the previous protocol while each .NET package only supports one protocol (that's intentional and something we don't plan to change). So I recommend reaching out to elasticmq and asking them to update their operations to return JSON (which maps to the latest SQS model definition: https://github.com/aws/aws-sdk-net/blob/main/generator/ServiceModels/sqs/sqs-2012-11-05.api.json).


Edit: So I asked the CLI team and the latest version only uses the previous XML protocol (which is the one returned by elasticmq); they're planning to switch protocols in the future but I don't have an ECD to share.

In summary:

  • .NET expects the GetQueueAttributes response to be in JSON format
  • elasticmq returns XML instead
  • CLI works as it's expecting XML but this will change in the future

For the time being, you can keep using version 3.7.200.6 of the SQS package (I checked and there haven't been any new APIs since then), but as I mentioned be aware you may see differences when using AWS vs a third-party implementation.