Пример #1
0
        public void Init()
        {
            var accountId = Environment.GetEnvironmentVariable("SQS_ACCOUNT_ID");
            if(string.IsNullOrEmpty(accountId)) {
                accountId = "accountid";
            }
            var publicKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
            if(string.IsNullOrEmpty(publicKey)) {
                publicKey = "publickey";
            }
            var privateKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY");
            if(string.IsNullOrEmpty("privatekey")) {
                privateKey = "privatekey";
            }
            _client = new SqsClient(SqsClientConfig.From(new XDoc("sqs-config")
                .Elem("endpoint", "default")
                .Elem("accountid", accountId)
                .Elem("publickey", publicKey)
                .Elem("privatekey", privateKey)));
            TEST_QUEUE = new SqsQueueName("steveb-events");

            // purge the queue
            while(true) {
                var messages = _client.ReceiveMessages(TEST_QUEUE, 1.Seconds(), SqsUtils.MAX_NUMBER_OF_MESSAGES_TO_FETCH);
                if(messages.None()) {
                    break;
                }
                _client.DeleteMessages(TEST_QUEUE, messages);
            }
        }
Пример #2
0
 public IEnumerable<SqsMessageId> DeleteMessages(SqsQueueName queueName, IEnumerable<SqsMessage> messages)
 {
     foreach(var message in messages) {
         DeleteMessage(queueName, message.MessageReceipt);
     }
     return new SqsMessageId[0];
 }
Пример #3
0
 private void AssertQueueIsNotNull(SqsQueueName queueName, List <QueueEntry> queue)
 {
     if (queue == null)
     {
         throw new InMemorySqsNullQueueException(string.Format("Queue '{0}' is null", queueName));
     }
 }
Пример #4
0
        /// <summary>
        /// Send one or more message to a named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messageBodies">Enumeration of message bodies.</param>
        /// <returns>Enumeration of message bodies that failed to send.</returns>
        public IEnumerable <string> SendMessages(SqsQueueName queueName, IEnumerable <string> messageBodies)
        {
            if (messageBodies.Count() > SqsUtils.MAX_NUMBER_OF_BATCH_SEND_MESSAGES)
            {
                throw new ArgumentException(string.Format("messageBodies is larger than {0}, which is the maximum", SqsUtils.MAX_NUMBER_OF_BATCH_SEND_MESSAGES));
            }
            var msgId       = 1;
            var attributes  = GetQueueNameAttribute(queueName.Value);
            var sendEntries = (from messageBody in messageBodies select new SendMessageBatchRequestEntry {
                MessageBody = messageBody, Id = string.Format("msg-{0}", msgId++), MessageAttributes = attributes
            }).ToList();
            var response    = Invoke(() =>
                                     _client.SendMessageBatch(new SendMessageBatchRequest {
                QueueUrl = GetQueueUrl(queueName.Value),
                Entries  = sendEntries
            }),
                                     queueName,
                                     SENDING_BATCH_MESSAGES);

            AssertSuccessfulStatusCode(response.HttpStatusCode, queueName, SENDING_BATCH_MESSAGES);
            if (response.Failed.None())
            {
                return(Enumerable.Empty <string>());
            }
            var messagesById = sendEntries.ToDictionary(entry => entry.Id, entry => entry.MessageBody);

            return(response.Failed.Select(failed => messagesById.TryGetValue(failed.Id, null)).Where(messageBody => messageBody != null).ToArray());
        }
Пример #5
0
 //--- Class Methods ---
 private static void AssertSuccessfulStatusCode(HttpStatusCode statusCode, SqsQueueName queueName, string sqsOperation)
 {
     if (statusCode != HttpStatusCode.OK)
     {
         throw new SqsException(string.Format("Got a '{0}' response while '{1}' from SQS queue '{2}'", statusCode, sqsOperation, queueName.Value), null);
     }
 }
Пример #6
0
        //--- Methods ---

        /// <summary>
        /// Receive zero or more messages from name queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="waitTimeSeconds">Max amount of time to wait until this method returns.</param>
        /// <param name="maxNumberOfMessages">Max number of messages to request.</param>
        /// <returns>Enumeration of received messages.</returns>
        public IEnumerable <SqsMessage> ReceiveMessages(SqsQueueName queueName, TimeSpan waitTimeSeconds, uint maxNumberOfMessages)
        {
            // Check preconditions
            if (waitTimeSeconds.TotalSeconds > SqsUtils.MAX_LONG_POLL_WAIT_TIME.TotalSeconds)
            {
                throw new ArgumentException(string.Format("The argument waitTimeSeconds is larger than '{0}', which is the maximum value allowed", SqsUtils.MAX_LONG_POLL_WAIT_TIME.TotalSeconds));
            }
            if (maxNumberOfMessages > SqsUtils.MAX_NUMBER_OF_MESSAGES_TO_FETCH)
            {
                throw new ArgumentException(string.Format("The argument maxNumberOfMessages is larger than '{0}', which is the maximum value allowed", SqsUtils.MAX_NUMBER_OF_MESSAGES_TO_FETCH));
            }

            // Perform request
            var response = Invoke(() =>
                                  _client.ReceiveMessage(new ReceiveMessageRequest {
                QueueUrl            = GetQueueUrl(queueName.Value),
                WaitTimeSeconds     = (int)waitTimeSeconds.TotalSeconds,
                MaxNumberOfMessages = (int)maxNumberOfMessages
            }),
                                  queueName,
                                  RECEIVING_MESSAGE
                                  );

            AssertSuccessfulStatusCode(response.HttpStatusCode, queueName, RECEIVING_MESSAGE);
            return(response.Messages.Select(msg => new SqsMessage(new SqsMessageId(msg.MessageId), new SqsMessageReceipt(msg.ReceiptHandle), msg.Body)).ToArray());
        }
Пример #7
0
        //--- Constructors ---

        /// <summary>
        /// Constructor for creating an instance.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="callback">Callback for received SQS messages.</param>
        /// <param name="longPollInterval">Max amount of time to wait for SQS message to arrive.</param>
        /// <param name="maxNumberOfMessages">Max number of SQS messages to request.</param>
        /// <param name="waitTimeOnError">Amount of time to wait until trying again to listen after an error occurred.</param>
        public SqsPollingClientSettings(SqsQueueName queueName, Action <IEnumerable <SqsMessage> > callback, TimeSpan longPollInterval, uint maxNumberOfMessages, TimeSpan waitTimeOnError)
        {
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }
            if (longPollInterval == null)
            {
                throw new ArgumentNullException("longPollInterval");
            }
            if (longPollInterval > 20.Seconds())
            {
                throw new ArgumentException("longPollInterval exceeds the limit allowed");
            }
            if (waitTimeOnError == null)
            {
                throw new ArgumentNullException("waitTimeOnError");
            }
            if (waitTimeOnError < 0.Seconds() || waitTimeOnError > 5.Minutes())
            {
                throw new ArgumentException("waitTimeOnError must be greater than 0 up to 5 minutes");
            }
            this.QueueName           = queueName;
            this.Callback            = callback;
            this.LongPollInterval    = longPollInterval;
            this.MaxNumberOfMessages = maxNumberOfMessages;
            this.WaitTimeOnError     = waitTimeOnError;
        }
Пример #8
0
 private List <QueueEntry> GetQueue(SqsQueueName queueName)
 {
     lock (_queues) {
         List <QueueEntry> msgQueue;
         _queues.TryGetValue(queueName, out msgQueue);
         return(msgQueue);
     }
 }
Пример #9
0
        //--- Methods ---

        /// <summary>
        /// Delete messages from named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messages">Enumeration of messages to delete.</param>
        /// <returns>Enumeration of messages that failed to delete.</returns>
        public IEnumerable <SqsMessageId> DeleteMessages(SqsQueueName queueName, IEnumerable <SqsMessage> messages)
        {
            foreach (var message in messages)
            {
                DeleteMessage(queueName, message.MessageReceipt);
            }
            return(new SqsMessageId[0]);
        }
Пример #10
0
        public void sending_a_message_to_unknown_queue_throws_an_amazon_sqs_exception()
        {
            // Setup
            var queue = new SqsQueueName("unknown-queue");

            // Act
            _client.SendMessage(queue, new XDoc("event").Attr("id", 1).ToCompactString());
        }
Пример #11
0
 //--- Constructors ---
 /// <summary>
 /// Constructor for creating an instance.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="client">ISqsClient instance.</param>
 public SqsQueueClient(SqsQueueName queueName, ISqsClient client)
 {
     if(client == null) {
         throw new ArgumentNullException("client");
     }
     this.QueueName = queueName;
     _client = client;
 }
Пример #12
0
 /// <summary>
 /// Send one or more message to a named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBodies">Enumeration of message bodies.</param>
 /// <returns>Enumeration of message bodies that failed to send.</returns>
 public IEnumerable <string> SendMessages(SqsQueueName queueName, IEnumerable <string> messageBodies)
 {
     foreach (var messageBody in messageBodies)
     {
         SendMessage(queueName, messageBody);
     }
     return(Enumerable.Empty <string>());
 }
Пример #13
0
 //--- Constructors ---
 /// <summary>
 /// Constructor for creating an instance.
 /// </summary>
 /// <param name="client">ISqsClient instance.</param>
 /// <param name="queueName">Queue name.</param>
 /// <param name="timerFactory">TimerFactory instance.</param>
 public SqsQueueDelayedSendClient(ISqsClient client, SqsQueueName queueName, TaskTimerFactory timerFactory)
 {
     if(client == null) {
         throw new ArgumentNullException("client");
     }
     this.QueueName = queueName;
     _client = client;
     _timedSendAccumulator = new TimedAccumulator<KeyValuePair<int, string>>(items => AsyncUtil.ForkBackgroundSender(() => BatchSendMessages(items)), SqsUtils.MAX_NUMBER_OF_BATCH_SEND_MESSAGES, AUTOFLUSH_TIME, timerFactory);
 }
Пример #14
0
        //--- Constructors ---

        /// <summary>
        /// Constructor for creating an instance.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="client">ISqsClient instance.</param>
        public SqsQueueClient(SqsQueueName queueName, ISqsClient client)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            this.QueueName = queueName;
            _client        = client;
        }
Пример #15
0
 private static T Invoke <T>(Func <T> function, SqsQueueName queueName, string sqsOperation)
 {
     try {
         return(function());
     } catch (AmazonSQSException e) {
         throw new SqsException(string.Format("There was an SQS error '{0}', from the '{1}' SQS queue", sqsOperation, queueName.Value), e);
     } catch (Exception e) {
         throw new SqsException(string.Format("There was an error '{0}', from the '{1}' SQS queue", sqsOperation, queueName.Value), e);
     }
 }
Пример #16
0
        //--- Constructors ---

        /// <summary>
        /// Constructor for creating an instance.
        /// </summary>
        /// <param name="client">ISqsClient instance.</param>
        /// <param name="queueName">Queue name.</param>
        /// <param name="timerFactory">TimerFactory instance.</param>
        public SqsQueueDelayedSendClient(ISqsClient client, SqsQueueName queueName, TaskTimerFactory timerFactory)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            this.QueueName        = queueName;
            _client               = client;
            _timedSendAccumulator = new TimedAccumulator <KeyValuePair <int, string> >(items => AsyncUtil.ForkBackgroundSender(() => BatchSendMessages(items)), SqsUtils.MAX_NUMBER_OF_BATCH_SEND_MESSAGES, AUTOFLUSH_TIME, timerFactory);
        }
Пример #17
0
 /// <summary>
 /// Delete a named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>True if the named queue was deleted</returns>
 public bool DeleteQueue(SqsQueueName queueName)
 {
     lock (_queues) {
         if (_queues.ContainsKey(queueName))
         {
             _queues.Remove(queueName);
         }
         return(true);
     }
 }
Пример #18
0
        /// <summary>
        /// Send message on named queue with a visibility delay.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messageBody">Message body.</param>
        /// <param name="delay">Time to wait until the message becomes visible.</param>
        public void SendMessage(SqsQueueName queueName, string messageBody, TimeSpan delay)
        {
            var msgQueue = GetQueue(queueName);

            AssertQueueIsNotNull(queueName, msgQueue);
            lock (msgQueue) {
                var entry = new QueueEntry(new SqsMessage(new SqsMessageId(Guid.NewGuid().ToString()), new SqsMessageReceipt(Guid.NewGuid().ToString()), messageBody), DateTime.MinValue);
                msgQueue.Add(entry);
            }
        }
Пример #19
0
 /// <summary>
 /// Create a new named queue and gets its URI.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>True if the named queue was created.</returns>
 public bool CreateQueue(SqsQueueName queueName)
 {
     lock (_queues) {
         if (!_queues.ContainsKey(queueName))
         {
             _queues[queueName] = new List <QueueEntry>();
         }
         return(true);
     }
 }
Пример #20
0
 public void Can_round_trip_message_through_queue()
 {
     var sqs = new InMemorySqsClient();
     var queueName = new SqsQueueName("bar");
     sqs.CreateQueue(queueName);
     sqs.SendMessage(queueName, "msg body");
     var messages = sqs.ReceiveMessages(queueName, 0.Seconds(), 10);
     Assert.AreEqual(1, messages.Count());
     var received = messages.First();
     Assert.AreEqual("msg body", received.Body);
 }
Пример #21
0
        /// <summary>
        /// Delete a named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <returns>True if the named queue was deleted</returns>
        public bool DeleteQueue(SqsQueueName queueName)
        {
            var response = Invoke(() =>
                                  _client.DeleteQueue(new DeleteQueueRequest {
                QueueUrl = GetQueueUrl(queueName.Value)
            }),
                                  queueName,
                                  DELETING_QUEUE
                                  );

            return(response.HttpStatusCode == HttpStatusCode.OK);
        }
Пример #22
0
        /// <summary>
        /// Create a new named queue and gets its URI.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <returns>True if the named queue was created.</returns>
        public bool CreateQueue(SqsQueueName queueName)
        {
            var response = Invoke(() =>
                                  _client.CreateQueue(new CreateQueueRequest {
                QueueName = queueName.Value
            }),
                                  queueName,
                                  CREATING_QUEUE
                                  );

            return(response.HttpStatusCode == HttpStatusCode.OK);
        }
Пример #23
0
 public void Can_create_and_delete_queues()
 {
     var sqs = new InMemorySqsClient();
     var queueName = new SqsQueueName("bar");
     sqs.CreateQueue(queueName);
     var queues = sqs.ListQueues(null);
     Assert.AreEqual(1, queues.Count());
     Assert.AreEqual("bar", queues.First());
     sqs.DeleteQueue(queueName);
     queues = sqs.ListQueues(null);
     Assert.IsFalse(queues.Any());
 }
Пример #24
0
        public void sending_a_message_with_a_delay_works()
        {
            // Setup
            var queue = new SqsQueueName("unknown-queue");

            // Act
            for(int i = 0; i < 10; i++) {
                _client.SendMessage(queue, new XDoc("event")
                                               .Start("page")
                                               .Elem("page", "/a/b/c")
                                               .End().ToCompactString(), 30.Seconds());
            }
        }
Пример #25
0
 /// <summary>
 /// Get enumeration of all messages that are currently held by the in-memory named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>Enumeration of messages.</returns>
 public IEnumerable <SqsMessage> InspectQueue(SqsQueueName queueName)
 {
     lock (_queues) {
         var msgQueue = GetQueue(queueName);
         if (msgQueue == null)
         {
             return(new SqsMessage[0]);
         }
         lock (msgQueue) {
             return(msgQueue.Select(x => x.Message).ToArray());
         }
     }
 }
Пример #26
0
 /// <summary>
 /// Removed all messages from named queue.
 /// </summary>
 /// <param name="queueName">Queue name</param>
 public void ClearQueue(SqsQueueName queueName)
 {
     lock (_queues) {
         var msgQueue = GetQueue(queueName);
         if (msgQueue == null)
         {
             return;
         }
         lock (msgQueue) {
             msgQueue.Clear();
         }
     }
 }
Пример #27
0
        /// <summary>
        /// Send message on named queue with a visibility delay.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messageBody">Message body.</param>
        /// <param name="delay">Time to wait until the message becomes visible.</param>
        public void SendMessage(SqsQueueName queueName, string messageBody, TimeSpan delay)
        {
            var response = Invoke(() =>
                                  _client.SendMessage(new SendMessageRequest {
                QueueUrl          = GetQueueUrl(queueName.Value),
                MessageBody       = messageBody,
                DelaySeconds      = (int)delay.TotalSeconds,
                MessageAttributes = GetQueueNameAttribute(queueName.Value)
            }),
                                  queueName,
                                  SENDING_MESSAGE);

            AssertSuccessfulStatusCode(response.HttpStatusCode, queueName, SENDING_MESSAGE);
        }
Пример #28
0
        /// <summary>
        /// Delete single message from named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messageReceipt">Message receipt.</param>
        /// <returns>True if message was deleted.</returns>
        public bool DeleteMessage(SqsQueueName queueName, SqsMessageReceipt messageReceipt)
        {
            var response = Invoke(() =>
                                  _client.DeleteMessage(new DeleteMessageRequest {
                QueueUrl      = GetQueueUrl(queueName.Value),
                ReceiptHandle = messageReceipt.Value
            }),
                                  queueName,
                                  DELETING_MESSAGE
                                  );

            AssertSuccessfulStatusCode(response.HttpStatusCode, queueName, DELETING_MESSAGE);
            return(response.HttpStatusCode == HttpStatusCode.OK);
        }
Пример #29
0
        /// <summary>
        /// Delete single message from named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messageReceipt">Message receipt.</param>
        /// <returns>True if message was deleted.</returns>
        public bool DeleteMessage(SqsQueueName queueName, SqsMessageReceipt messageReceipt)
        {
            var msgQueue = GetQueue(queueName);

            AssertQueueIsNotNull(queueName, msgQueue);
            lock (msgQueue) {
                var entry = msgQueue.FirstOrDefault(x => x.Message.MessageReceipt == messageReceipt);
                if (entry != null)
                {
                    msgQueue.Remove(entry);
                }
            }
            return(true);
        }
Пример #30
0
        public void creating_a_queue_that_is_already_created_multiple_times_always_returns_http_200_responses()
        {
            // This assumes that'test-queue' is a queue that has already been created
            // And that you can create queues in SQS
            var queueName = new SqsQueueName("test-queue");

            // Create the queue for the first time
            var queue1Success = _client.CreateQueue(queueName);
            Assert.IsTrue(queue1Success, "Creating queue first time failed");

            // Try to create the queue for the second time
            var queue2Success = _client.CreateQueue(queueName);
            Assert.IsTrue(queue2Success, "Creating queue second time failed");
        }
Пример #31
0
        /// <summary>
        /// Get delegate for enqueuing messages asynchronously to named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <returns>Delegate for enqueuing message asynchronously.</returns>
        public Action <string> GetEnqueueMessageCallback(SqsQueueName queueName)
        {
repeat:
            SqsQueueDelayedSendClient queue;
            var directory = _directory;

            if (!directory.TryGetValue(queueName.Value, out queue))
            {
                var newDirectory = new Dictionary <string, SqsQueueDelayedSendClient>(directory);
                newDirectory[queueName.Value] = queue = new SqsQueueDelayedSendClient(_client, queueName, _timerFactory);
                if (!SysUtil.CAS(ref _directory, directory, newDirectory))
                {
                    goto repeat;
                }
            }
            return(queue.EnqueueMessage);
        }
Пример #32
0
        public void polling_client_pulls_from_sqs_and_calls_callback()
        {
            var mockSqsClient = new MockSqsClient();
            mockSqsClient.FillQueue(15);
            var pollster = new SqsPollingClient(mockSqsClient);
            Assert.AreEqual(15, mockSqsClient.Queued.Count, "queue was accessed prematurely");
            var posted = new List<SqsMessage>();
            var fooQueue = new SqsQueueName("foo");
            pollster.Listen(new SqsPollingClientSettings(
                                queueName: fooQueue,
                                callback: messages => {
                                    posted.AddRange(messages);
                                    foreach(var msg in messages) {
                                        mockSqsClient.DeleteMessage(fooQueue, msg.MessageReceipt);
                                    }
                                },
                                longPollInterval: 0.Seconds(),
                                maxNumberOfMessages: SqsUtils.MAX_NUMBER_OF_MESSAGES_TO_FETCH,
                                waitTimeOnError: 1.Seconds()));
            Assert.IsTrue(Wait.For(() => mockSqsClient.Queued.Count == 0, 10.Seconds()), "queue did not get depleted in time");
            Assert.IsTrue(
                Wait.For(() => mockSqsClient.ReceiveCalled > 0, 5.Seconds()),
                string.Format("receive called the wrong number of times: Expected {0} != {1}", 3, mockSqsClient.ReceiveCalled)
                );
            Assert.AreEqual(15, mockSqsClient.Delivered.Count, "delivered has the wrong number of messages");

            // Compare delivered and deleted
            Assert.AreEqual(mockSqsClient.Delivered.Count(), mockSqsClient.Deleted.Count(), "The count of delivered messages and deleted messages does not match and it must");
            for(var i = 0; i < mockSqsClient.Delivered.Count(); i++) {
                Assert.AreEqual(
                    mockSqsClient.Delivered[i].MessageReceipt,
                    mockSqsClient.Deleted[i],
                    "delivered message and deleted message don't match on index " + i);
            }
            Assert.AreEqual(mockSqsClient.Delivered.Count(), posted.Count(), "The number of delivered messages and posted messages does not match and it should");
            for(var i = 0; i < mockSqsClient.Delivered.Count(); i++) {
                Assert.AreEqual(
                    mockSqsClient.Delivered[i],
                    posted[i],
                    "delivered and posted don't match");
            }
        }
Пример #33
0
        /// <summary>
        /// Delete messages from named queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="messages">Enumeration of messages to delete.</param>
        /// <returns>Enumeration of messages that failed to delete.</returns>
        public IEnumerable <SqsMessageId> DeleteMessages(SqsQueueName queueName, IEnumerable <SqsMessage> messages)
        {
            if (messages.Count() > SqsUtils.MAX_NUMBER_OF_BATCH_DELETE_MESSAGES)
            {
                throw new ArgumentException(string.Format("messageReceipts is larger than {0}, which is the maximum", SqsUtils.MAX_NUMBER_OF_BATCH_DELETE_MESSAGES));
            }
            var deleteEntries = messages.Distinct(message => message.MessageId.Value).Select(message => new DeleteMessageBatchRequestEntry {
                Id = message.MessageId.Value, ReceiptHandle = message.MessageReceipt.Value
            }).ToList();
            var response = Invoke(() =>
                                  _client.DeleteMessageBatch(new DeleteMessageBatchRequest {
                QueueUrl = GetQueueUrl(queueName.Value),
                Entries  = deleteEntries
            }),
                                  queueName,
                                  BATCH_DELETING_MESSAGES);

            AssertSuccessfulStatusCode(response.HttpStatusCode, queueName, BATCH_DELETING_MESSAGES);
            return(response.Failed.Select(failed => new SqsMessageId(failed.Id)).ToArray());
        }
Пример #34
0
 //--- Constructors ---
 /// <summary>
 /// Constructor for creating an instance.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="callback">Callback for received SQS messages.</param>
 /// <param name="longPollInterval">Max amount of time to wait for SQS message to arrive.</param>
 /// <param name="maxNumberOfMessages">Max number of SQS messages to request.</param>
 /// <param name="waitTimeOnError">Amount of time to wait until trying again to listen after an error occurred.</param>
 public SqsPollingClientSettings(SqsQueueName queueName, Action<IEnumerable<SqsMessage>> callback, TimeSpan longPollInterval, uint maxNumberOfMessages, TimeSpan waitTimeOnError)
 {
     if(callback == null) {
         throw new ArgumentNullException("callback");
     }
     if(longPollInterval == null) {
         throw new ArgumentNullException("longPollInterval");
     }
     if(longPollInterval > 20.Seconds()) {
         throw new ArgumentException("longPollInterval exceeds the limit allowed");
     }
     if(waitTimeOnError == null) {
         throw new ArgumentNullException("waitTimeOnError");
     }
     if(waitTimeOnError < 0.Seconds() || waitTimeOnError > 5.Minutes()) {
         throw new ArgumentException("waitTimeOnError must be greater than 0 up to 5 minutes");
     }
     this.QueueName = queueName;
     this.Callback = callback;
     this.LongPollInterval = longPollInterval;
     this.MaxNumberOfMessages = maxNumberOfMessages;
     this.WaitTimeOnError = waitTimeOnError;
 }
Пример #35
0
        /// <summary>
        /// Receive zero or more messages from name queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="waitTimeSeconds">Max amount of time to wait until this method returns.</param>
        /// <param name="maxNumberOfMessages">Max number of messages to request.</param>
        /// <returns>Enumeration of received messages.</returns>
        public IEnumerable <SqsMessage> ReceiveMessages(SqsQueueName queueName, TimeSpan waitTimeSeconds, uint maxNumberOfMessages)
        {
            var start = GlobalClock.UtcNow;

            // keep checking for messages until the wait-timeout kicks in
            while (true)
            {
                var msgQueue = GetQueue(queueName);
                AssertQueueIsNotNull(queueName, msgQueue);
                QueueEntry[] entries;
                var          now = GlobalClock.UtcNow;
                lock (msgQueue) {
                    var visibilityTimeout = 30.Seconds();
                    entries = msgQueue
                              .Where(x => x.VisibleTime <= now)
                              .OrderBy(x => _random.Next())
                              .Take(10)
                              .ToArray();
                    foreach (var entry in entries)
                    {
                        entry.VisibleTime = now + visibilityTimeout;
                    }
                }
                if (entries.Any())
                {
                    return(entries.Select(e => new SqsMessage(e.Message.MessageId, e.Message.MessageReceipt, e.Message.Body)).ToArray());
                }
                if ((now - start) > waitTimeSeconds)
                {
                    return(Enumerable.Empty <SqsMessage>());
                }

                // no message found; go to sleep for 100ms and try again
                AsyncUtil.Sleep(100.Milliseconds());
            }
        }
Пример #36
0
 /// <summary>
 /// Send message on named queue with a visibility delay.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBody">Message body.</param>
 /// <param name="delay">Time to wait until the message becomes visible.</param>
 public void SendMessage(SqsQueueName queueName, string messageBody, TimeSpan delay)
 {
     var msgQueue = GetQueue(queueName);
     AssertQueueIsNotNull(queueName, msgQueue);
     lock(msgQueue) {
         var entry = new QueueEntry(new SqsMessage(new SqsMessageId(Guid.NewGuid().ToString()), new SqsMessageReceipt(Guid.NewGuid().ToString()), messageBody), DateTime.MinValue);
         msgQueue.Add(entry);
     }
 }
Пример #37
0
        /// <summary>
        /// Receive zero or more messages from name queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="waitTimeSeconds">Max amount of time to wait until this method returns.</param>
        /// <param name="maxNumberOfMessages">Max number of messages to request.</param>
        /// <returns>Enumeration of received messages.</returns>
        public IEnumerable<SqsMessage> ReceiveMessages(SqsQueueName queueName, TimeSpan waitTimeSeconds, uint maxNumberOfMessages)
        {
            var start = GlobalClock.UtcNow;

            // keep checking for messages until the wait-timeout kicks in
            while(true) {
                var msgQueue = GetQueue(queueName);
                AssertQueueIsNotNull(queueName, msgQueue);
                QueueEntry[] entries;
                var now = GlobalClock.UtcNow;
                lock(msgQueue) {
                    var visibilityTimeout = 30.Seconds();
                    entries = msgQueue
                        .Where(x => x.VisibleTime <= now)
                        .OrderBy(x => _random.Next())
                        .Take(10)
                        .ToArray();
                    foreach(var entry in entries) {
                        entry.VisibleTime = now + visibilityTimeout;
                    }
                }
                if(entries.Any()) {
                    return entries.Select(e => new SqsMessage(e.Message.MessageId, e.Message.MessageReceipt, e.Message.Body)).ToArray();
                }
                if((now - start) > waitTimeSeconds) {
                    return Enumerable.Empty<SqsMessage>();
                }

                // no message found; go to sleep for 100ms and try again
                AsyncUtil.Sleep(100.Milliseconds());
            }
        }
Пример #38
0
 /// <summary>
 /// Get enumeration of all messages that are currently held by the in-memory named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>Enumeration of messages.</returns>
 public IEnumerable<SqsMessage> InspectQueue(SqsQueueName queueName)
 {
     lock(_queues) {
         var msgQueue = GetQueue(queueName);
         if(msgQueue == null) {
             return new SqsMessage[0];
         }
         lock(msgQueue) {
             return msgQueue.Select(x => x.Message).ToArray();
         }
     }
 }
Пример #39
0
 /// <summary>
 /// Removed all messages from named queue.
 /// </summary>
 /// <param name="queueName">Queue name</param>
 public void ClearQueue(SqsQueueName queueName)
 {
     lock(_queues) {
         var msgQueue = GetQueue(queueName);
         if(msgQueue == null) {
             return;
         }
         lock(msgQueue) {
             msgQueue.Clear();
         }
     }
 }
Пример #40
0
 private void AssertQueueIsNotNull(SqsQueueName queueName, List<QueueEntry> queue)
 {
     if(queue == null) {
         throw new InMemorySqsNullQueueException(string.Format("Queue '{0}' is null", queueName));
     }
 }
Пример #41
0
 public bool DeleteQueue(SqsQueueName queueName)
 {
     throw new NotImplementedException();
 }
Пример #42
0
 public void polling_client_pulls_from_sqs_and_calls_callback_but_does_not_automatically_deletes_messages()
 {
     var mockSqsClient = new MockSqsClient();
     mockSqsClient.FillQueue(15);
     var pollster = new SqsPollingClient(mockSqsClient);
     Assert.AreEqual(15, mockSqsClient.Queued.Count, "queue was accessed prematurely");
     var posted = new List<SqsMessage>();
     var queueName = new SqsQueueName("foo");
     pollster.Listen(new SqsPollingClientSettings(
                         queueName: queueName,
                         callback: posted.AddRange,
                         longPollInterval: 10.Seconds(),
                         maxNumberOfMessages: SqsUtils.MAX_NUMBER_OF_MESSAGES_TO_FETCH,
                         waitTimeOnError: 1.Seconds()));
     Assert.IsTrue(Wait.For(() => mockSqsClient.Queued.Count == 0, 10.Seconds()), "queue did not get depleted in time");
     Assert.IsTrue(
         Wait.For(() => mockSqsClient.ReceiveCalled > 0, 5.Seconds()),
         string.Format("receive called the wrong number of times: {0} != {1}", 3, mockSqsClient.ReceiveCalled)
         );
     Assert.AreEqual(15, mockSqsClient.Delivered.Count, "delivered has the wrong number of messages");
     Assert.AreNotEqual(
         mockSqsClient.Delivered.Count,
         mockSqsClient.Deleted.Count,
         "delivered and deleted don't match");
     Assert.AreEqual(
         mockSqsClient.Delivered.Count,
         posted.Count,
         "delivered and posted don't match");
 }
Пример #43
0
 public IEnumerable<string> SendMessages(SqsQueueName queueName, IEnumerable<string> messageBodies)
 {
     throw new NotImplementedException();
 }
Пример #44
0
 //--- Methods ---
 /// <summary>
 /// Enqueue message for batched, asynchronous delivery.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBody">Message body.</param>
 public void EnqueueMessage(SqsQueueName queueName, string messageBody)
 {
     GetEnqueueMessageCallback(queueName)(messageBody);
 }
Пример #45
0
 /// <summary>
 /// Get delegate for enqueuing messages asynchronously to named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>Delegate for enqueuing message asynchronously.</returns>
 public Action<string> GetEnqueueMessageCallback(SqsQueueName queueName)
 {
     repeat:
     SqsQueueDelayedSendClient queue;
     var directory = _directory;
     if(!directory.TryGetValue(queueName.Value, out queue)) {
         var newDirectory = new Dictionary<string, SqsQueueDelayedSendClient>(directory);
         newDirectory[queueName.Value] = queue = new SqsQueueDelayedSendClient(_client, queueName, _timerFactory);
         if(!SysUtil.CAS(ref _directory, directory, newDirectory)) {
             goto repeat;
         }
     }
     return queue.EnqueueMessage;
 }
Пример #46
0
 public void SendMessage(SqsQueueName queueName, string messageBody)
 {
     throw new NotImplementedException();
 }
Пример #47
0
 /// <summary>
 /// Send message on named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBody">Message body.</param>
 public void SendMessage(SqsQueueName queueName, string messageBody)
 {
     SendMessage(queueName, messageBody, TimeSpan.Zero);
 }
Пример #48
0
 /// <summary>
 /// Send message on named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBody">Message body.</param>
 public void SendMessage(SqsQueueName queueName, string messageBody)
 {
     SendMessage(queueName, messageBody, TimeSpan.Zero);
 }
Пример #49
0
 /// <summary>
 /// Send one or more message to a named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBodies">Enumeration of message bodies.</param>
 /// <returns>Enumeration of message bodies that failed to send.</returns>
 public IEnumerable<string> SendMessages(SqsQueueName queueName, IEnumerable<string> messageBodies)
 {
     foreach(var messageBody in messageBodies) {
         SendMessage(queueName, messageBody);
     }
     return Enumerable.Empty<string>();
 }
Пример #50
0
 public IEnumerable<SqsMessage> ReceiveMessages(SqsQueueName queueName, TimeSpan waitTimeSeconds, uint maxNumberOfMessages)
 {
     ReceiveCalled++;
     var take = (int)Math.Min(10, maxNumberOfMessages);
     var taken = Queued.Take(take).ToArray();
     _log.DebugFormat("receive returning {0} messages", taken.Length);
     Delivered.AddRange(taken);
     Queued.RemoveRange(0, taken.Length);
     return taken;
 }
Пример #51
0
 private List<QueueEntry> GetQueue(SqsQueueName queueName)
 {
     lock(_queues) {
         List<QueueEntry> msgQueue;
         _queues.TryGetValue(queueName, out msgQueue);
         return msgQueue;
     }
 }
Пример #52
0
 /// <summary>
 /// Create a new named queue and gets its URI.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>True if the named queue was created.</returns>
 public bool CreateQueue(SqsQueueName queueName)
 {
     lock(_queues) {
         if(!_queues.ContainsKey(queueName)) {
             _queues[queueName] = new List<QueueEntry>();
         }
         return true;
     }
 }
Пример #53
0
 //--- Methods ---
 /// <summary>
 /// Enqueue message for batched, asynchronous delivery.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageBody">Message body.</param>
 public void EnqueueMessage(SqsQueueName queueName, string messageBody)
 {
     GetEnqueueMessageCallback(queueName)(messageBody);
 }
Пример #54
0
 /// <summary>
 /// Delete single message from named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <param name="messageReceipt">Message receipt.</param>
 /// <returns>True if message was deleted.</returns>
 public bool DeleteMessage(SqsQueueName queueName, SqsMessageReceipt messageReceipt)
 {
     var msgQueue = GetQueue(queueName);
     AssertQueueIsNotNull(queueName, msgQueue);
     lock(msgQueue) {
         var entry = msgQueue.FirstOrDefault(x => x.Message.MessageReceipt == messageReceipt);
         if(entry != null) {
             msgQueue.Remove(entry);
         }
     }
     return true;
 }
Пример #55
0
 public bool DeleteMessage(SqsQueueName queueName, SqsMessageReceipt messageReceipt)
 {
     _log.DebugFormat("deleting {0}", messageReceipt);
     Deleted.Add(messageReceipt);
     return true;
 }
Пример #56
0
 /// <summary>
 /// Delete a named queue.
 /// </summary>
 /// <param name="queueName">Queue name.</param>
 /// <returns>True if the named queue was deleted</returns>
 public bool DeleteQueue(SqsQueueName queueName)
 {
     lock(_queues) {
         if(_queues.ContainsKey(queueName)) {
             _queues.Remove(queueName);
         }
         return true;
     }
 }