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.