Repository: localstack/localstack

Issue:
bug: MessageAttributes inconsistency on SQS Receive message
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

using AWS SDK V3 for JS/TS

localstack

```js
  const { Messages } = await sqsClient.send(new ReceiveMessageCommand({
    QueueUrl,
    MessageAttributeNames: ['*'],
  }));

  console.log(Messages[0].MessageAttributes)
```

it will **not** retrieve the attributes, replacing the astrix with "All" will work
same code will work with real SQS in both cases


Same for aws cli

```shell
> aws --endpoint-url=http://localhost:4566 sqs receive-message --queue-url http://localhost:4566/000000000000/test-queue --max-number-of-messages 1 --message-attribute-names *

{
    "Messages": [
        {
            "MessageId": "99bad5bf-75f6-48b8-ab97-889e679c5a04",
            "ReceiptHandle": "ZTVlNGE2NjAtMDllZC00N2YxLWI4ODItYzUzMzkwZWUyYTA3IGFybjphd3M6c3FzOnVzLWVhc3QtMTowMDAwMDAwMDAwMDA6dGVzdC1xdWV1ZTEgOTliYWQ1YmYtNzVmNi00OGI4LWFiOTctODg5ZTY3OWM1YTA0IDE2ODc3MDM2NTkuOTgyNTA2",
            "MD5OfBody": "098f6bcd4621d373cade4e832627b4f6",
            "Body": "test"
        }
    ]
}

> aws --endpoint-url=http://localhost:4566 sqs receive-message --queue-url http://localhost:4566/000000000000/test-queue --max-number-of-messages 1 --message-attribute-names All

{
    "Messages": [
        {
            "MessageId": "73cbe585-70a3-4966-99c2-4d4cdf12f095",
            "ReceiptHandle": "Y2M0ZjAwNDAtYTY5MS00MjY5LTkwMmQtNDU4NzBmYzBiYzgxIGFybjphd3M6c3FzOnVzLWVhc3QtMTowMDAwMDAwMDAwMDA6dGVzdC1xdWV1ZTEgNzNjYmU1ODUtNzBhMy00OTY2LTk5YzItNGQ0Y2RmMTJmMDk1IDE2ODc3MDM2NjMuODcyNzg4",
            "MD5OfBody": "098f6bcd4621d373cade4e832627b4f6",
            "Body": "test",
            "MD5OfMessageAttributes": "f92843aa316e790fb678e5e4ed34d80f",
            "MessageAttributes": {
                "my-test": {
                    "StringValue": "test-value",
                    "DataType": "String"
                }
            }
        }
    ]
}
```

### Expected Behavior

Respect the astrix and behave as as "All"

### How are you starting LocalStack?

With a `docker run` command

### Steps To Reproduce

#### How are you starting localstack (e.g., `bin/localstack` command, arguments, or `docker-compose.yml`)

docker run -p 127.0.0.1:4566:4566/tcp --network=host localstack/localstack:2.1.0

#### Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

CLI

```
aws --endpoint-url=http://localhost:4566 sqs receive-message --queue-url http://localhost:4566/000000000000/test-queue --max-number-of-messages 1 --message-attribute-names *
```

SDK

```js
const { Messages } = await sqsClient.send(new ReceiveMessageCommand({
    QueueUrl,
    MessageAttributeNames: ['*'],
  }));
  ```

### Environment

```markdown
- LocalStack: 2.1.0
```


### Anything else?

_No response_


Discussion:
Thanks for reporting @artur-ma . Looks like we just need to add this condition here: https://github.com/localstack/localstack/blob/0caa19d5b34e61e1fbfc93c0ba46d7b40082fc11/localstack/services/sqs/provider.py#L1378-L1379

feel like adding a PR?

Resolving patch:
diff --git a/localstack/services/sqs/provider.py b/localstack/services/sqs/provider.py
--- a/localstack/services/sqs/provider.py
+++ b/localstack/services/sqs/provider.py
@@ -1365,7 +1365,7 @@ def message_filter_message_attributes(message: Message, names: Optional[MessageA
     https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.receive_message.
 
     :param message: The message to filter (it will be modified)
-    :param names: the attributes names/filters (can be 'All', '.*', or prefix filters like 'Foo.*')
+    :param names: the attributes names/filters (can be 'All', '.*', '*' or prefix filters like 'Foo.*')
     """
     if not message.get("MessageAttributes"):
         return
@@ -1374,7 +1374,7 @@ def message_filter_message_attributes(message: Message, names: Optional[MessageA
         del message["MessageAttributes"]
         return
 
-    if "All" in names or ".*" in names:
+    if "All" in names or ".*" in names or "*" in names:
         return
 
     attributes = message["MessageAttributes"]


Test patch:
diff --git a/tests/integration/test_sqs.py b/tests/integration/test_sqs.py
--- a/tests/integration/test_sqs.py
+++ b/tests/integration/test_sqs.py
@@ -3350,6 +3350,10 @@ def receive_message(message_attribute_names):
         response = receive_message(["All"])
         assert snapshot.match("all_name", response)
 
+        # test "*"
+        response = receive_message(["*"])
+        assert snapshot.match("all_wildcard_asterisk", response["Messages"][0])
+
         # test ".*"
         response = receive_message([".*"])
         assert snapshot.match("all_wildcard", response["Messages"][0])
diff --git a/tests/integration/test_sqs.snapshot.json b/tests/integration/test_sqs.snapshot.json
--- a/tests/integration/test_sqs.snapshot.json
+++ b/tests/integration/test_sqs.snapshot.json
@@ -1,159 +1,180 @@
 {
   "tests/integration/test_sqs.py::TestSqsProvider::test_receive_message_message_attribute_names_filters": {
-    "recorded-date": "31-05-2022, 11:41:35",
+    "recorded-date": "06-07-2023, 11:20:02",
     "recorded-content": {
       "send_message_response": {
-        "MD5OfMessageBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MD5OfMessageAttributes": "4c360f3fdafd970e05fae2f149d997f5",
+        "MD5OfMessageBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MessageId": "<uuid:1>",
         "ResponseMetadata": {
-          "HTTPStatusCode": 200,
-          "HTTPHeaders": {}
+          "HTTPHeaders": {},
+          "HTTPStatusCode": 200
         }
       },
       "empty_filter": {
         "Messages": [
           {
-            "MessageId": "<uuid:1>",
-            "ReceiptHandle": "<receipt-handle:1>",
+            "Body": "msg",
             "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
-            "Body": "msg"
+            "MessageId": "<uuid:1>",
+            "ReceiptHandle": "<receipt-handle:1>"
           }
         ],
         "ResponseMetadata": {
-          "HTTPStatusCode": 200,
-          "HTTPHeaders": {}
+          "HTTPHeaders": {},
+          "HTTPStatusCode": 200
         }
       },
       "all_name": {
         "Messages": [
           {
-            "MessageId": "<uuid:1>",
-            "ReceiptHandle": "<receipt-handle:2>",
-            "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
             "Body": "msg",
+            "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
             "MD5OfMessageAttributes": "4c360f3fdafd970e05fae2f149d997f5",
             "MessageAttributes": {
               "General": {
-                "StringValue": "Kenobi",
-                "DataType": "String"
+                "DataType": "String",
+                "StringValue": "Kenobi"
               },
               "Hello": {
-                "StringValue": "There",
-                "DataType": "String"
+                "DataType": "String",
+                "StringValue": "There"
               },
               "Help.Me": {
-                "StringValue": "Me",
-                "DataType": "String"
+                "DataType": "String",
+                "StringValue": "Me"
               }
-            }
+            },
+            "MessageId": "<uuid:1>",
+            "ReceiptHandle": "<receipt-handle:2>"
           }
         ],
         "ResponseMetadata": {
-          "HTTPStatusCode": 200,
-          "HTTPHeaders": {}
+          "HTTPHeaders": {},
+          "HTTPStatusCode": 200
         }
       },
-      "all_wildcard": {
-        "MessageId": "<uuid:1>",
-        "ReceiptHandle": "<receipt-handle:3>",
+      "all_wildcard_asterisk": {
+        "Body": "msg",
         "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
+        "MD5OfMessageAttributes": "4c360f3fdafd970e05fae2f149d997f5",
+        "MessageAttributes": {
+          "General": {
+            "DataType": "String",
+            "StringValue": "Kenobi"
+          },
+          "Hello": {
+            "DataType": "String",
+            "StringValue": "There"
+          },
+          "Help.Me": {
+            "DataType": "String",
+            "StringValue": "Me"
+          }
+        },
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:3>"
+      },
+      "all_wildcard": {
         "Body": "msg",
+        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MD5OfMessageAttributes": "4c360f3fdafd970e05fae2f149d997f5",
         "MessageAttributes": {
           "General": {
-            "StringValue": "Kenobi",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "Kenobi"
           },
           "Hello": {
-            "StringValue": "There",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "There"
           },
           "Help.Me": {
-            "StringValue": "Me",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "Me"
           }
-        }
+        },
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:4>"
       },
       "only_non_existing_names": {
-        "MessageId": "<uuid:1>",
-        "ReceiptHandle": "<receipt-handle:4>",
+        "Body": "msg",
         "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
-        "Body": "msg"
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:5>"
       },
       "only_existing": {
-        "MessageId": "<uuid:1>",
-        "ReceiptHandle": "<receipt-handle:5>",
-        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "Body": "msg",
+        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MD5OfMessageAttributes": "fca026605781cb4126a1e9044df24232",
         "MessageAttributes": {
           "General": {
-            "StringValue": "Kenobi",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "Kenobi"
           },
           "Hello": {
-            "StringValue": "There",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "There"
           }
-        }
+        },
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:6>"
       },
       "existing_and_non_existing": {
-        "MessageId": "<uuid:1>",
-        "ReceiptHandle": "<receipt-handle:6>",
-        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "Body": "msg",
+        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MD5OfMessageAttributes": "a311262e065454b75da111d535b8dacd",
         "MessageAttributes": {
           "Hello": {
-            "StringValue": "There",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "There"
           }
-        }
+        },
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:7>"
       },
       "prefix_filter": {
-        "MessageId": "<uuid:1>",
-        "ReceiptHandle": "<receipt-handle:7>",
-        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "Body": "msg",
+        "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
         "MD5OfMessageAttributes": "83fee93c1bcd8b9a5a923ffacdc636c7",
         "MessageAttributes": {
           "Hello": {
-            "StringValue": "There",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "There"
           },
           "Help.Me": {
-            "StringValue": "Me",
-            "DataType": "String"
+            "DataType": "String",
+            "StringValue": "Me"
           }
-        }
+        },
+        "MessageId": "<uuid:1>",
+        "ReceiptHandle": "<receipt-handle:8>"
       },
       "illegal_name_1": {
         "Messages": [
           {
-            "MessageId": "<uuid:1>",
-            "ReceiptHandle": "<receipt-handle:8>",
+            "Body": "msg",
             "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
-            "Body": "msg"
+            "MessageId": "<uuid:1>",
+            "ReceiptHandle": "<receipt-handle:9>"
           }
         ],
         "ResponseMetadata": {
-          "HTTPStatusCode": 200,
-          "HTTPHeaders": {}
+          "HTTPHeaders": {},
+          "HTTPStatusCode": 200
         }
       },
       "illegal_name_2": {
         "Messages": [
           {
-            "MessageId": "<uuid:1>",
-            "ReceiptHandle": "<receipt-handle:9>",
+            "Body": "msg",
             "MD5OfBody": "6e2baaf3b97dbeef01c0043275f9a0e7",
-            "Body": "msg"
+            "MessageId": "<uuid:1>",
+            "ReceiptHandle": "<receipt-handle:10>"
           }
         ],
         "ResponseMetadata": {
-          "HTTPStatusCode": 200,
-          "HTTPHeaders": {}
+          "HTTPHeaders": {},
+          "HTTPStatusCode": 200
         }
       }
     }