aws-0.15: Aws/Sqs/Commands/Message.hs
module Aws.Sqs.Commands.Message
(
-- * User Message Attributes
UserMessageAttributeCustomType
, UserMessageAttributeValue(..)
, UserMessageAttributeName
, UserMessageAttribute
-- * Send Message
, SendMessage(..)
, SendMessageResponse(..)
-- * Delete Message
, DeleteMessage(..)
, DeleteMessageResponse(..)
-- * Receive Message
, Message(..)
, ReceiveMessage(..)
, ReceiveMessageResponse(..)
-- * Change Message Visiblity
, ChangeMessageVisibility(..)
, ChangeMessageVisibilityResponse(..)
) where
import Aws.Core
import Aws.Sqs.Core
import Control.Applicative
import Control.Monad.Trans.Resource (throwM)
import Data.Maybe
import Data.Monoid
import Text.XML.Cursor (($/), ($//), (&/), (&|))
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Char8 as B
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Data.Scientific
import qualified Network.HTTP.Types as HTTP
import Text.Read (readEither)
import qualified Text.XML.Cursor as Cu
import Prelude
-- -------------------------------------------------------------------------- --
-- User Message Attributes
-- | You can append a custom type label to the supported data types (String,
-- Number, and Binary) to create custom data types. This capability is similar
-- to type traits in programming languages. For example, if you have an
-- application that needs to know which type of number is being sent in the
-- message, then you could create custom types similar to the following:
-- Number.byte, Number.short, Number.int, and Number.float. Another example
-- using the binary data type is to use Binary.gif and Binary.png to
-- distinguish among different image file types in a message or batch of
-- messages. The appended data is optional and opaque to Amazon SQS, which
-- means that the appended data is not interpreted, validated, or used by
-- Amazon SQS. The Custom Type extension has the same restrictions on allowed
-- characters as the message body.
--
type UserMessageAttributeCustomType = T.Text
-- | Message Attribute Value
--
-- The user-specified message attribute value. For string data types, the value
-- attribute has the same restrictions on the content as the message body. For
-- more information, see SendMessage.
--
-- Name, type, and value must not be empty or null. In addition, the message
-- body should not be empty or null. All parts of the message attribute,
-- including name, type, and value, are included in the message size
-- restriction, which is currently 256 KB (262,144 bytes).
--
-- The supported message attribute data types are String, Number, and Binary.
-- You can also provide custom information on the type. The data type has the
-- same restrictions on the content as the message body. The data type is case
-- sensitive, and it can be up to 256 bytes long.
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_MessageAttributeValue.html>
--
data UserMessageAttributeValue
= UserMessageAttributeString (Maybe UserMessageAttributeCustomType) T.Text
-- ^ Strings are Unicode with UTF-8 binary encoding.
| UserMessageAttributeNumber (Maybe UserMessageAttributeCustomType) Scientific
-- ^ Numbers are positive or negative integers or floating point numbers.
-- Numbers have sufficient range and precision to encompass most of the
-- possible values that integers, floats, and doubles typically support. A
-- number can have up to 38 digits of precision, and it can be between
-- 10^-128 to 10^+126. Leading and trailing zeroes are trimmed.
| UserMessageAttributeBinary (Maybe UserMessageAttributeCustomType) B.ByteString
-- ^ Binary type attributes can store any binary data, for example,
-- compressed data, encrypted data, or images.
-- UserMessageAttributesStringList (Maybe UserMessageAttributeCustomType) [T.Text]
-- -- ^ Not implemented. Reserved for future use.
-- UserMessageAttributeBinaryList (Maybe UserMessageAttributeCustomType) [B.ByteString]
-- -- ^ Not implemented. Reserved for future use.
deriving (Show, Read, Eq, Ord)
-- | The message attribute name can contain the following characters: A-Z, a-z,
-- 0-9, underscore(_), hyphen(-), and period (.). The name must not start or
-- end with a period, and it should not have successive periods. The name is
-- case sensitive and must be unique among all attribute names for the message.
-- The name can be up to 256 characters long. The name cannot start with "AWS."
-- or "Amazon." (or any variations in casing) because these prefixes are
-- reserved for use by Amazon Web Services.
--
type UserMessageAttributeName = T.Text
-- | Message Attribute
--
-- Name, type, and value must not be empty or null. In addition, the message
-- body should not be empty or null. All parts of the message attribute,
-- including name, type, and value, are included in the message size
-- restriction, which is currently 256 KB (262,144 bytes).
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSMessageAttributes.html#SQSMessageAttributes.DataTypes>
--
-- /NOTE/
--
-- The Amazon SQS API reference calls this /MessageAttribute/. The Haskell
-- bindings use this term for what the Amazon documentation calls just
-- /Attributes/. In order to limit backward compatibility issues we keep the
-- terminology of the Haskell bindings and call this type
-- /UserMessageAttributes/.
--
type UserMessageAttribute = (UserMessageAttributeName, UserMessageAttributeValue)
userMessageAttributesQuery :: [UserMessageAttribute] -> HTTP.Query
userMessageAttributesQuery = concat . zipWith msgAttrQuery [1 :: Int ..]
where
msgAttrQuery i (name, value) =
[ ( pre <> ".Name", Just $ TE.encodeUtf8 name )
, ( pre <> ".Value.DataType", Just typ )
, ( pre <> ".Value." <> valueKey, Just encodedValue )
]
where
pre = "MessageAttribute." <> B.pack (show i) <> "."
customType Nothing t = TE.encodeUtf8 t
customType (Just c) t = TE.encodeUtf8 $ t <> "." <> c
(typ, valueKey, encodedValue) = case value of
UserMessageAttributeString c t ->
(customType c "String", "StringValue", TE.encodeUtf8 t)
UserMessageAttributeNumber c n ->
(customType c "Number", "StringValue", B.pack $ show n)
UserMessageAttributeBinary c b ->
(customType c "Binary", "BinaryValue", b)
-- -------------------------------------------------------------------------- --
-- Send Message
-- | Delivers a message to the specified queue. With Amazon SQS, you now have
-- the ability to send large payload messages that are up to 256KB (262,144
-- bytes) in size. To send large payloads, you must use an AWS SDK that
-- supports SigV4 signing. To verify whether SigV4 is supported for an AWS SDK,
-- check the SDK release notes.
--
-- /IMPORTANT/
--
-- The following list shows the characters (in Unicode) allowed in your
-- message, according to the W3C XML specification. For more information, go to
-- <http://www.w3.org/TR/REC-xml/#charsets> If you send any characters not
-- included in the list, your request will be rejected.
--
-- > #x9 | #xA | #xD | [#x20 to #xD7FF] | [#xE000 to #xFFFD] | [#x10000 to #x10FFFF]
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_SendMessage.html>
--
data SendMessage = SendMessage
{ smMessage :: !T.Text
-- ^ The message to send. String maximum 256 KB in size.
, smQueueName :: !QueueName
-- ^ The URL of the Amazon SQS queue to take action on.
, smAttributes :: ![UserMessageAttribute]
-- ^ Each message attribute consists of a Name, Type, and Value.
, smDelaySeconds :: !(Maybe Int)
-- ^ The number of seconds (0 to 900 - 15 minutes) to delay a specific
-- message. Messages with a positive DelaySeconds value become available for
-- processing after the delay time is finished. If you don't specify a value,
-- the default value for the queue applies.
}
deriving (Show, Read, Eq, Ord)
-- | At
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_SendMessageResult.html>
-- all fields of @SendMessageResult@ are denoted as optional.
-- At
-- <http://queue.amazonaws.com/doc/2012-11-05/QueueService.wsdl>
-- all fields are specified as required.
--
-- The actual service seems to treat at least 'smrMD5OfMessageAttributes'
-- as optional.
--
data SendMessageResponse = SendMessageResponse
{ smrMD5OfMessageBody :: !T.Text
-- ^ An MD5 digest of the non-URL-encoded message body string. This can be
-- used to verify that Amazon SQS received the message correctly. Amazon SQS
-- first URL decodes the message before creating the MD5 digest. For
-- information about MD5, go to <http://www.faqs.org/rfcs/rfc1321.html>.
, smrMessageId :: !MessageId
-- ^ An element containing the message ID of the message sent to the queue.
, smrMD5OfMessageAttributes :: !(Maybe T.Text)
-- ^ An MD5 digest of the non-URL-encoded message attribute string. This can
-- be used to verify that Amazon SQS received the message correctly. Amazon
-- SQS first URL decodes the message before creating the MD5 digest. For
-- information about MD5, go to <http://www.faqs.org/rfcs/rfc1321.html>.
}
deriving (Show, Read, Eq, Ord)
instance ResponseConsumer r SendMessageResponse where
type ResponseMetadata SendMessageResponse = SqsMetadata
responseConsumer _ _ = sqsXmlResponseConsumer parse
where
parse el = SendMessageResponse
<$> force "Missing MD5 Signature"
(el $// Cu.laxElement "MD5OfMessageBody" &/ Cu.content)
<*> (fmap MessageId . force "Missing Message Id")
(el $// Cu.laxElement "MessageId" &/ Cu.content)
<*> (pure . listToMaybe)
(el $// Cu.laxElement "MD5OfMessageAttributes" &/ Cu.content)
instance SignQuery SendMessage where
type ServiceConfiguration SendMessage = SqsConfiguration
signQuery SendMessage{..} = sqsSignQuery SqsQuery
{ sqsQueueName = Just smQueueName
, sqsQuery =
[ ("Action", Just "SendMessage")
, ("MessageBody", Just $ TE.encodeUtf8 smMessage)
]
<> userMessageAttributesQuery smAttributes
<> maybeToList (("DelaySeconds",) . Just . B.pack . show <$> smDelaySeconds)
}
instance Transaction SendMessage SendMessageResponse
instance AsMemoryResponse SendMessageResponse where
type MemoryResponse SendMessageResponse = SendMessageResponse
loadToMemory = return
-- -------------------------------------------------------------------------- --
-- Delete Message
-- | Deletes the specified message from the specified queue. You specify the
-- message by using the message's receipt handle and not the message ID you
-- received when you sent the message. Even if the message is locked by another
-- reader due to the visibility timeout setting, it is still deleted from the
-- queue. If you leave a message in the queue for longer than the queue's
-- configured retention period, Amazon SQS automatically deletes it.
--
-- /NOTE/
--
-- The receipt handle is associated with a specific instance of receiving the
-- message. If you receive a message more than once, the receipt handle you get
-- each time you receive the message is different. When you request
-- DeleteMessage, if you don't provide the most recently received receipt
-- handle for the message, the request will still succeed, but the message
-- might not be deleted.
--
-- /IMPORTANT/
--
-- It is possible you will receive a message even after you have deleted it.
-- This might happen on rare occasions if one of the servers storing a copy of
-- the message is unavailable when you request to delete the message. The copy
-- remains on the server and might be returned to you again on a subsequent
-- receive request. You should create your system to be idempotent so that
-- receiving a particular message more than once is not a problem.
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_DeleteMessage.html>
--
data DeleteMessage = DeleteMessage
{ dmReceiptHandle :: !ReceiptHandle
-- ^ The receipt handle associated with the message to delete.
, dmQueueName :: !QueueName
-- ^ The URL of the Amazon SQS queue to take action on.
}
deriving (Show, Read, Eq, Ord)
data DeleteMessageResponse = DeleteMessageResponse {}
deriving (Show, Read, Eq, Ord)
instance ResponseConsumer r DeleteMessageResponse where
type ResponseMetadata DeleteMessageResponse = SqsMetadata
responseConsumer _ _ = sqsXmlResponseConsumer parse
where
parse _ = return DeleteMessageResponse {}
instance SignQuery DeleteMessage where
type ServiceConfiguration DeleteMessage = SqsConfiguration
signQuery DeleteMessage{..} = sqsSignQuery SqsQuery
{ sqsQueueName = Just dmQueueName
, sqsQuery =
[ ("Action", Just "DeleteMessage")
, ("ReceiptHandle", Just $ TE.encodeUtf8 $ printReceiptHandle dmReceiptHandle)
]
}
instance Transaction DeleteMessage DeleteMessageResponse
instance AsMemoryResponse DeleteMessageResponse where
type MemoryResponse DeleteMessageResponse = DeleteMessageResponse
loadToMemory = return
-- -------------------------------------------------------------------------- --
-- Receive Message
-- | Retrieves one or more messages, with a maximum limit of 10 messages, from
-- the specified queue. Long poll support is enabled by using the
-- WaitTimeSeconds parameter. For more information, see
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html Amazon SQS Long Poll>
-- in the Amazon SQS Developer Guide.
--
-- Short poll is the default behavior where a weighted random set of machines
-- is sampled on a ReceiveMessage call. This means only the messages on the
-- sampled machines are returned. If the number of messages in the queue is
-- small (less than 1000), it is likely you will get fewer messages than you
-- requested per ReceiveMessage call. If the number of messages in the queue is
-- extremely small, you might not receive any messages in a particular
-- ReceiveMessage response; in which case you should repeat the request.
--
-- For each message returned, the response includes the following:
--
-- Message body
--
-- * MD5 digest of the message body. For information about MD5, go to
-- <http://www.faqs.org/rfcs/rfc1321.html>.
--
-- * Message ID you received when you sent the message to the queue.
--
-- * Receipt handle.
--
-- * Message attributes.
--
-- * MD5 digest of the message attributes.
--
-- The receipt handle is the identifier you must provide when deleting the
-- message. For more information, see Queue and Message Identifiers in the
-- Amazon SQS Developer Guide.
--
-- You can provide the VisibilityTimeout parameter in your request, which will
-- be applied to the messages that Amazon SQS returns in the response. If you
-- do not include the parameter, the overall visibility timeout for the queue
-- is used for the returned messages. For more information, see Visibility
-- Timeout in the Amazon SQS Developer Guide.
--
-- /NOTE/
--
-- Going forward, new attributes might be added. If you are writing code that
-- calls this action, we recommend that you structure your code so that it can
-- handle new attributes gracefully.
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_ReceiveMessage.html>
--
data ReceiveMessage = ReceiveMessage
{ rmVisibilityTimeout :: !(Maybe Int)
-- ^ The duration (in seconds) that the received messages are hidden from
-- subsequent retrieve requests after being retrieved by a ReceiveMessage
-- request.
, rmAttributes :: ![MessageAttribute]
-- ^ A list of attributes that need to be returned along with each message.
--
-- The following lists the names and descriptions of the attributes that can
-- be returned:
--
-- * All - returns all values.
--
-- * ApproximateFirstReceiveTimestamp - returns the time when the message was
-- first received (epoch time in milliseconds).
--
-- * ApproximateReceiveCount - returns the number of times a message has been
-- received but not deleted.
--
-- * SenderId - returns the AWS account number (or the IP address, if
-- anonymous access is allowed) of the sender.
--
-- * SentTimestamp - returns the time when the message was sent (epoch time
-- in milliseconds).
, rmMaxNumberOfMessages :: !(Maybe Int)
-- ^ The maximum number of messages to return. Amazon SQS never returns more
-- messages than this value but may return fewer. Values can be from 1 to 10.
-- Default is 1.
--
-- All of the messages are not necessarily returned.
, rmUserMessageAttributes :: ![UserMessageAttributeName]
-- ^ The name of the message attribute, where N is the index. The message
-- attribute name can contain the following characters: A-Z, a-z, 0-9,
-- underscore (_), hyphen (-), and period (.). The name must not start or end
-- with a period, and it should not have successive periods. The name is case
-- sensitive and must be unique among all attribute names for the message.
-- The name can be up to 256 characters long. The name cannot start with
-- "AWS." or "Amazon." (or any variations in casing), because these prefixes
-- are reserved for use by Amazon Web Services.
--
-- When using ReceiveMessage, you can send a list of attribute names to
-- receive, or you can return all of the attributes by specifying "All" or
-- ".*" in your request. You can also use "foo.*" to return all message
-- attributes starting with the "foo" prefix.
, rmQueueName :: !QueueName
-- ^The URL of the Amazon SQS queue to take action on.
, rmWaitTimeSeconds :: !(Maybe Int)
-- ^ The duration (in seconds) for which the call will wait for a message to
-- arrive in the queue before returning. If a message is available, the call
-- will return sooner than WaitTimeSeconds.
}
deriving (Show, Read, Eq, Ord)
-- | An Amazon SQS message.
--
-- In
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_Message.html>
-- all elements are denoted as optional.
-- In
-- <http://queue.amazonaws.com/doc/2012-11-05/QueueService.wsdl>
-- all elements except for the attributes are specified as required.
-- At least for the field 'mMD5OfMessageAttributes' the the service
-- is not always returning a value and therefor we make this field optional.
--
data Message = Message
{ mMessageId :: !T.Text
-- ^ A unique identifier for the message. Message IDs are considered unique
-- across all AWS accounts for an extended period of time.
, mReceiptHandle :: !ReceiptHandle
-- ^ An identifier associated with the act of receiving the message. A new
-- receipt handle is returned every time you receive a message. When deleting
-- a message, you provide the last received receipt handle to delete the
-- message.
, mMD5OfBody :: !T.Text
-- ^ An MD5 digest of the non-URL-encoded message body string.
, mBody :: T.Text
-- ^ The message's contents (not URL-encoded).
, mAttributes :: ![(MessageAttribute,T.Text)]
-- ^ SenderId, SentTimestamp, ApproximateReceiveCount, and/or
-- ApproximateFirstReceiveTimestamp. SentTimestamp and
-- ApproximateFirstReceiveTimestamp are each returned as an integer
-- representing the epoch time in milliseconds.
, mMD5OfMessageAttributes :: !(Maybe T.Text)
-- ^ An MD5 digest of the non-URL-encoded message attribute string. This can
-- be used to verify that Amazon SQS received the message correctly. Amazon
-- SQS first URL decodes the message before creating the MD5 digest. For
-- information about MD5, go to <http://www.faqs.org/rfcs/rfc1321.html>.
, mUserMessageAttributes :: ![UserMessageAttribute]
-- ^ Each message attribute consists of a Name, Type, and Value.
}
deriving(Show, Read, Eq, Ord)
data ReceiveMessageResponse = ReceiveMessageResponse
{ rmrMessages :: ![Message]
}
deriving (Show, Read, Eq, Ord)
readMessageAttribute
:: Cu.Cursor
-> Response SqsMetadata (MessageAttribute,T.Text)
readMessageAttribute cursor = do
name <- force "Missing Name" $ cursor $/ Cu.laxElement "Name" &/ Cu.content
value <- force "Missing Value" $ cursor $/ Cu.laxElement "Value" &/ Cu.content
parsedName <- parseMessageAttribute name
return (parsedName, value)
readUserMessageAttribute
:: Cu.Cursor
-> Response SqsMetadata UserMessageAttribute
readUserMessageAttribute cursor = (,)
<$> force "Missing Name" (cursor $/ Cu.laxElement "Name" &/ Cu.content)
<*> readUserMessageAttributeValue cursor
readUserMessageAttributeValue
:: Cu.Cursor
-> Response SqsMetadata UserMessageAttributeValue
readUserMessageAttributeValue cursor = do
typStr <- force "Missing DataType"
$ cursor $/ Cu.laxElement "DataType" &/ Cu.content
case parseType typStr of
("String", c) -> do
val <- force "Missing StringValue"
$ cursor $/ Cu.laxElement "StringValue" &/ Cu.content
return $ UserMessageAttributeString c val
("Number", c) -> do
valStr <- force "Missing StringValue"
$ cursor $/ Cu.laxElement "StringValue" &/ Cu.content
val <- tryXml . readEither $ T.unpack valStr
return $ UserMessageAttributeNumber c val
("Binary", c) -> do
val64 <- force "Missing StringValue"
$ cursor $/ Cu.laxElement "StringValue" &/ Cu.content
val <- tryXml . B64.decode $ TE.encodeUtf8 val64
return $ UserMessageAttributeBinary c val
(x, _) -> throwM . XmlException
$ "unkown data type for MessageAttributeValue: " <> T.unpack x
where
parseType s = case T.break (== '.') s of
(a, "") -> (a, Nothing)
(a, x) -> (a, Just (T.tail x))
tryXml = either (throwM . XmlException) return
readMessage :: Cu.Cursor -> Response SqsMetadata Message
readMessage cursor = do
mid <- force "Missing Message Id"
$ cursor $// Cu.laxElement "MessageId" &/ Cu.content
rh <- force "Missing Reciept Handle"
$ cursor $// Cu.laxElement "ReceiptHandle" &/ Cu.content
md5 <- force "Missing MD5 Signature"
$ cursor $// Cu.laxElement "MD5OfBody" &/ Cu.content
body <- force "Missing Body"
$ cursor $// Cu.laxElement "Body" &/ Cu.content
attributes <- sequence
$ cursor $// Cu.laxElement "Attribute" &| readMessageAttribute
userAttributes <- sequence
$ cursor $// Cu.laxElement "MessageAttribute" &| readUserMessageAttribute
let md5OfMessageAttributes = listToMaybe
$ cursor $// Cu.laxElement "MD5OfMessageAttributes" &/ Cu.content
return Message
{ mMessageId = mid
, mReceiptHandle = ReceiptHandle rh
, mMD5OfBody = md5
, mBody = body
, mAttributes = attributes
, mMD5OfMessageAttributes = md5OfMessageAttributes
, mUserMessageAttributes = userAttributes
}
formatMAttributes :: [MessageAttribute] -> HTTP.Query
formatMAttributes attrs = case attrs of
[attr] -> [("AttributeName", encodeAttr attr)]
_ -> zipWith f [1 :: Int ..] attrs
where
f x y = ("AttributeName." <> B.pack (show x), encodeAttr y)
encodeAttr = Just . TE.encodeUtf8 . printMessageAttribute
formatUserMessageAttributes :: [UserMessageAttributeName] -> HTTP.Query
formatUserMessageAttributes attrs = case attrs of
[attr] -> [("MessageAttributeName", encodeAttr attr)]
_ -> zipWith f [1 :: Int ..] attrs
where
f x y = ("MessageAttributeName." <> B.pack (show x), encodeAttr y)
encodeAttr = Just . TE.encodeUtf8
instance ResponseConsumer r ReceiveMessageResponse where
type ResponseMetadata ReceiveMessageResponse = SqsMetadata
responseConsumer _ _ = sqsXmlResponseConsumer parse
where
parse el = do
result <- force "Missing ReceiveMessageResult"
$ el $// Cu.laxElement "ReceiveMessageResult"
messages <- sequence
$ result $// Cu.laxElement "Message" &| readMessage
return ReceiveMessageResponse{ rmrMessages = messages }
instance SignQuery ReceiveMessage where
type ServiceConfiguration ReceiveMessage = SqsConfiguration
signQuery ReceiveMessage{..} = sqsSignQuery SqsQuery
{ sqsQueueName = Just rmQueueName
, sqsQuery = [ ("Action", Just "ReceiveMessage") ]
<> catMaybes
[ ("VisibilityTimeout",) <$> case rmVisibilityTimeout of
Just x -> Just $ Just $ B.pack $ show x
Nothing -> Nothing
, ("MaxNumberOfMessages",) <$> case rmMaxNumberOfMessages of
Just x -> Just $ Just $ B.pack $ show x
Nothing -> Nothing
, ("WaitTimeSeconds",) <$> case rmWaitTimeSeconds of
Just x -> Just $ Just $ B.pack $ show x
Nothing -> Nothing
]
<> formatMAttributes rmAttributes
<> formatUserMessageAttributes rmUserMessageAttributes
}
instance Transaction ReceiveMessage ReceiveMessageResponse
instance AsMemoryResponse ReceiveMessageResponse where
type MemoryResponse ReceiveMessageResponse = ReceiveMessageResponse
loadToMemory = return
-- -------------------------------------------------------------------------- --
-- Change Message Visibility
-- | Changes the visibility timeout of a specified message in a queue to a new
-- value. The maximum allowed timeout value you can set the value to is 12
-- hours. This means you can't extend the timeout of a message in an existing
-- queue to more than a total visibility timeout of 12 hours. (For more
-- information visibility timeout, see Visibility Timeout in the Amazon SQS
-- Developer Guide.)
--
-- For example, let's say you have a message and its default message visibility
-- timeout is 30 minutes. You could call ChangeMessageVisiblity with a value of
-- two hours and the effective timeout would be two hours and 30 minutes. When
-- that time comes near you could again extend the time out by calling
-- ChangeMessageVisiblity, but this time the maximum allowed timeout would be 9
-- hours and 30 minutes.
--
-- /NOTE/
--
-- There is a 120,000 limit for the number of inflight messages per queue.
-- Messages are inflight after they have been received from the queue by a
-- consuming component, but have not yet been deleted from the queue. If you
-- reach the 120,000 limit, you will receive an OverLimit error message from
-- Amazon SQS. To help avoid reaching the limit, you should delete the messages
-- from the queue after they have been processed. You can also increase the
-- number of queues you use to process the messages.
--
-- /IMPORTANT/
--
-- If you attempt to set the VisibilityTimeout to an amount more than the
-- maximum time left, Amazon SQS returns an error. It will not automatically
-- recalculate and increase the timeout to the maximum time remaining.
--
-- /IMPORTANT/
--
-- Unlike with a queue, when you change the visibility timeout for a specific
-- message, that timeout value is applied immediately but is not saved in
-- memory for that message. If you don't delete a message after it is received,
-- the visibility timeout for the message the next time it is received reverts
-- to the original timeout value, not the value you set with the
-- ChangeMessageVisibility action.
--
-- <http://docs.aws.amazon.com/AWSSimpleQueueService/2012-11-05/APIReference/API_ChangeMessageVisibility.html>
--
data ChangeMessageVisibility = ChangeMessageVisibility
{ cmvReceiptHandle :: !ReceiptHandle
-- ^ The receipt handle associated with the message whose visibility timeout
-- should be changed. This parameter is returned by the ReceiveMessage
-- action.
, cmvVisibilityTimeout :: !Int
-- ^ The new value (in seconds - from 0 to 43200 - maximum 12 hours) for the
-- message's visibility timeout.
, cmvQueueName :: !QueueName
-- ^ The URL of the Amazon SQS queue to take action on.
}
deriving (Show, Read, Eq, Ord)
data ChangeMessageVisibilityResponse = ChangeMessageVisibilityResponse {}
deriving (Show, Read, Eq, Ord)
instance ResponseConsumer r ChangeMessageVisibilityResponse where
type ResponseMetadata ChangeMessageVisibilityResponse = SqsMetadata
responseConsumer _ _ = sqsXmlResponseConsumer parse
where
parse _ = return ChangeMessageVisibilityResponse {}
-- | ServiceConfiguration: 'SqsConfiguration'
instance SignQuery ChangeMessageVisibility where
type ServiceConfiguration ChangeMessageVisibility = SqsConfiguration
signQuery ChangeMessageVisibility {..} = sqsSignQuery SqsQuery
{ sqsQueueName = Just cmvQueueName
, sqsQuery =
[ ("Action", Just "ChangeMessageVisibility")
, ("ReceiptHandle", Just . TE.encodeUtf8 $ printReceiptHandle cmvReceiptHandle)
, ("VisibilityTimeout", Just . B.pack $ show cmvVisibilityTimeout)
]
}
instance Transaction ChangeMessageVisibility ChangeMessageVisibilityResponse
instance AsMemoryResponse ChangeMessageVisibilityResponse where
type MemoryResponse ChangeMessageVisibilityResponse = ChangeMessageVisibilityResponse
loadToMemory = return