diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 044759e4f..9c8858bc0 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -38,6 +38,8 @@ class Message(BaseModel): self.sent_timestamp = None self.approximate_first_receive_timestamp = None self.approximate_receive_count = 0 + self.deduplication_id = None + self.group_id = None self.visible_at = 0 self.delayed_until = 0 @@ -400,7 +402,7 @@ class SQSBackend(BaseBackend): queue._set_attributes(attributes) return queue - def send_message(self, queue_name, message_body, message_attributes=None, delay_seconds=None): + def send_message(self, queue_name, message_body, message_attributes=None, delay_seconds=None, deduplication_id=None, group_id=None): queue = self.get_queue(queue_name) @@ -412,6 +414,12 @@ class SQSBackend(BaseBackend): message_id = get_random_message_id() message = Message(message_id, message_body) + # Attributes, but not *message* attributes + if deduplication_id is not None: + message.deduplication_id = deduplication_id + if group_id is not None: + message.group_id = group_id + if message_attributes: message.message_attributes = message_attributes diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py index c475f0ce0..adf3e7a6e 100644 --- a/moto/sqs/responses.py +++ b/moto/sqs/responses.py @@ -198,6 +198,8 @@ class SQSResponse(BaseResponse): def send_message(self): message = self._get_param('MessageBody') delay_seconds = int(self._get_param('DelaySeconds', 0)) + message_group_id = self._get_param("MessageGroupId") + message_dedupe_id = self._get_param("MessageDeduplicationId") if len(message) > MAXIMUM_MESSAGE_LENGTH: return ERROR_TOO_LONG_RESPONSE, dict(status=400) @@ -213,7 +215,9 @@ class SQSResponse(BaseResponse): queue_name, message, message_attributes=message_attributes, - delay_seconds=delay_seconds + delay_seconds=delay_seconds, + deduplication_id=message_dedupe_id, + group_id=message_group_id ) template = self.response_template(SEND_MESSAGE_RESPONSE) return template.render(message=message, message_attributes=message_attributes) @@ -491,6 +495,18 @@ RECEIVE_MESSAGE_RESPONSE = """ ApproximateFirstReceiveTimestamp {{ message.approximate_first_receive_timestamp }} + {% if message.deduplication_id is not none %} + + MessageDeduplicationId + {{ message.deduplication_id }} + + {% endif %} + {% if message.group_id is not none %} + + MessageGroupId + {{ message.group_id }} + + {% endif %} {% if message.message_attributes.items()|count > 0 %} {{- message.attribute_md5 -}} {% endif %} diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py index 05936ab39..c5ad39eb0 100644 --- a/tests/test_sqs/test_sqs.py +++ b/tests/test_sqs/test_sqs.py @@ -170,6 +170,28 @@ def test_message_with_complex_attributes(): messages.should.have.length_of(1) +@mock_sqs +def test_send_message_with_message_group_id(): + sqs = boto3.resource('sqs', region_name='us-east-1') + queue = sqs.create_queue(QueueName="test-group-id.fifo", + Attributes={'FifoQueue': 'true'}) + + sent = queue.send_message( + MessageBody="mydata", + MessageDeduplicationId="dedupe_id_1", + MessageGroupId="group_id_1", + ) + + messages = queue.receive_messages() + messages.should.have.length_of(1) + + message_attributes = messages[0].attributes + message_attributes.should.contain('MessageGroupId') + message_attributes['MessageGroupId'].should.equal('group_id_1') + message_attributes.should.contain('MessageDeduplicationId') + message_attributes['MessageDeduplicationId'].should.equal('dedupe_id_1') + + @mock_sqs def test_send_message_with_unicode_characters(): body_one = 'Héllo!😀'