diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 4e9a3678f..2063a952a 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -265,7 +265,7 @@ class SQSBackend(BaseBackend): return message - def receive_messages(self, queue_name, count, wait_seconds_timeout): + def receive_messages(self, queue_name, count, wait_seconds_timeout, visibility_timeout): """ Attempt to retrieve visible messages from a queue. @@ -276,6 +276,7 @@ class SQSBackend(BaseBackend): :param string queue_name: The name of the queue to read from. :param int count: The maximum amount of messages to retrieve. + :param int visibility_timeout: The number of seconds the message should remain invisible to other queue readers. """ queue = self.get_queue(queue_name) result = [] @@ -288,7 +289,7 @@ class SQSBackend(BaseBackend): if not message.visible: continue message.mark_received( - visibility_timeout=queue.visibility_timeout + visibility_timeout=visibility_timeout ) result.append(message) if len(result) >= count: diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py index 7d37c44fb..ffe6c2b55 100644 --- a/moto/sqs/responses.py +++ b/moto/sqs/responses.py @@ -38,6 +38,18 @@ class SQSResponse(BaseResponse): queue_name = self.path.split("/")[-1] return queue_name + def _get_validated_visibility_timeout(self): + """ + :raises ValueError: If specified visibility timeout exceeds MAXIMUM_VISIBILTY_TIMEOUT + :raises TypeError: If visibility timeout was not specified + """ + visibility_timeout = int(self.querystring.get("VisibilityTimeout")[0]) + + if visibility_timeout > MAXIMUM_VISIBILTY_TIMEOUT: + raise ValueError + + return visibility_timeout + def create_queue(self): queue_name = self.querystring.get("QueueName")[0] queue = self.sqs_backend.create_queue(queue_name, visibility_timeout=self.attribute.get('VisibilityTimeout'), @@ -63,12 +75,11 @@ class SQSResponse(BaseResponse): def change_message_visibility(self): queue_name = self._get_queue_name() receipt_handle = self.querystring.get("ReceiptHandle")[0] - visibility_timeout = int(self.querystring.get("VisibilityTimeout")[0]) - if visibility_timeout > MAXIMUM_VISIBILTY_TIMEOUT: - return "Invalid request, maximum visibility timeout is {0}".format( - MAXIMUM_VISIBILTY_TIMEOUT - ), dict(status=400) + try: + visibility_timeout = self._get_validated_visibility_timeout() + except ValueError: + return ERROR_MAX_VISIBILITY_TIMEOUT_RESPONSE, dict(status=400) try: self.sqs_backend.change_message_visibility( @@ -233,7 +244,14 @@ class SQSResponse(BaseResponse): except TypeError: wait_time = queue.wait_time_seconds - messages = self.sqs_backend.receive_messages(queue_name, message_count, wait_time) + try: + visibility_timeout = self._get_validated_visibility_timeout() + except TypeError: + visibility_timeout = queue.visibility_timeout + except ValueError: + return ERROR_MAX_VISIBILITY_TIMEOUT_RESPONSE, dict(status=400) + + messages = self.sqs_backend.receive_messages(queue_name, message_count, wait_time, visibility_timeout) template = self.response_template(RECEIVE_MESSAGE_RESPONSE) output = template.render(messages=messages) return output @@ -436,3 +454,5 @@ ERROR_TOO_LONG_RESPONSE = """