コード例 #1
0
        protected void MoveMessageToDlq <T>(IMessage <T> message)
        {
            // Move the Message to the DLQ (Also need to delete from the current queue)
            var messageBody = GetSqsMessageBody(message);

            Log.DebugFormat("Message {0} has failed {1} times, moving to DLQ.", message.Id, message.RetryAttempts);

            string dlqName = string.Empty;

            try
            {
                var queueNames = new VersionedQueueNames(messageBody.GetType());
                dlqName = queueNames.Dlq;
                var dlqUrl = this.SqsClient.GetOrCreateQueueUrl(dlqName);

                // Put in DLQ before deleting, we can't 'lose' the message.
                this.RepublishFailedMessageToQueue(message, dlqUrl, queueNames.Dlq);

                // Note: If this 'DeleteMessage' command fails, it does not matter.
                this.SqsClient.DeleteMessage(messageBody.QueueUrl, messageBody.ReceiptHandle);
            }
            catch (Exception ex)
            {
                Log.Error(string.Format("An error occurred trying to move the message {0} to the DLQ '{1}'.", message.Id, dlqName), ex);
            }
        }
コード例 #2
0
        public void OnMessageProcessingFailedDoesNotUpdateMessageVisibilityIfMovingMessageToDlq()
        {
            var message     = this.CreateNewMessage();
            var messageBody = message.GetBody();
            var queueNames  = new VersionedQueueNames(messageBody.GetType());
            var dlqUrl      = "http://queue.com/dlq/";

            // GetOrCreateQueue
            // PublishMessage (To DLQ) -> Test that a new MessageId is assigned!
            // Delete Message
            this.SqsClient
            .Setup(x => x.GetOrCreateQueueUrl(queueNames.Dlq))
            .Returns(dlqUrl)
            .Verifiable();

            this.SqsClient
            .Setup(x => x.PublishMessage(dlqUrl, Convert.ToBase64String(message.ToBytes())))
            .Returns(new SendMessageResponse())
            .Verifiable();

            this.SqsClient
            .Setup(x => x.DeleteMessage(messageBody.QueueUrl, messageBody.ReceiptHandle))
            .Verifiable();

            this.MessageProcessor.OnMessageProcessingFailed(message, null, true);

            this.SqsClient.VerifyAll();

            // Verify that 'UpdateMessageVisibility' is NOT called.
            this.SqsClient.Verify(x => x.ChangeMessageVisibility(messageBody.QueueUrl, messageBody.ReceiptHandle, It.IsAny <decimal>()), Times.Never());
        }
コード例 #3
0
        private string DetermineQueueName(string queueName, byte[] messageBytes)
        {
            var messageBodyType     = messageBytes.ToMessage(typeof(IMessage)).Body.GetType();
            var versionedQueueNames = new VersionedQueueNames(messageBodyType);
            var queueExt            = queueName.Substring(queueName.LastIndexOf('.') + 1).ToLowerInvariant();

            switch (queueExt)
            {
            case "inq":
                return(versionedQueueNames.In);

            case "priorityq":
                return(versionedQueueNames.Priority);

            case "outq":
                return(versionedQueueNames.Out);

            case "dlq":
                return(versionedQueueNames.Dlq);

            default:
                // It's not a standard queue, should be a custom queue.
                return(queueName);
            }
        }
コード例 #4
0
        /*
         * private string GetQueueName(Type messageType, long priority)
         * {
         *  // TODO: Use assembly qualified name for versioned queue's?
         *  var stronglyTypedMessage = typeof(Message<>).MakeGenericType(messageType);
         *  var messageInstance = (IMessage)Activator.CreateInstance(stronglyTypedMessage);
         *  messageInstance.Priority = priority;
         *
         *  // Use reflection to call the extension method
         *  var methods = typeof(MessageExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mi => mi.Name == "ToInQueueName");
         *
         *  MethodInfo method = null;
         *  foreach (var methodInfo in methods)
         *  {
         *      var paramType = methodInfo.GetParameters()[0].ParameterType;
         *      if (paramType.GetGenericArguments().Count() == 1)
         *      {
         *          // we are looking for  Func<TSource, bool>, the other has 3
         *          method = methodInfo;
         *      }
         *  }
         *
         *  if (method == null)
         *  {
         *      throw new NullReferenceException("Could not find 'ToInQueueName' extension method.");
         *  }
         *
         *  // Execute the extension method
         *  method = method.MakeGenericMethod(messageType);
         *  return (string)method.Invoke(messageInstance, new object[] { messageInstance });
         * }
         */

        private IList <string> GetNewQueueNames(Type messageType)
        {
            // Use reflection to call the extension method
            var queueNames = typeof(VersionedQueueNames);
            var properties = queueNames.GetProperties(BindingFlags.Instance | BindingFlags.Public);

            var newQueueNames      = new List <string>();
            var queueNamesInstance = new VersionedQueueNames(messageType);

            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(string))
                {
                    newQueueNames.Add((string)queueNames.InvokeMember(property.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, queueNamesInstance, null));
                }
            }

            return(newQueueNames);
        }
コード例 #5
0
        protected override void PublishMessage <T>(IMessage <T> message)
        {
            // TODO: Refactor to reusable method. Also use when sending notification messages?
            var messageQueueName = new VersionedQueueNames(typeof(T)).In; // message.ToInQueueName();

            if (!this.QueueUrls.ContainsKey(messageQueueName))
            {
                throw new InvalidOperationException(string.Format("No queue is registered for the message type {0}.", typeof(T).Name));
            }

            // TODO: If a notification response is required, clients should use the 'MessageQueueClient'.
            // TODO: Should messaegs from the Producer be auto-configured to be one-way only?
            // TODO: Need to test DLQ, and write tests to verify all messages are being processed.
            // TODO: Look at using in-memory for these unit tests
            message.Options = (int)MessageOption.None; //// Do not send a reply to the out queue.

            Log.DebugFormat("Publishing message to queue {0}.", messageQueueName);
            var response =
                this.SqsClient.PublishMessage(
                    new SendMessageRequest().WithQueueUrl(this.GetQueueNameOrUrl(message))
                    .WithMessageBody(Convert.ToBase64String(message.ToBytes())));
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: adam-26/ServiceStack.Redis
        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo("Client.exe.config"));
            // var Log4Net = log4net.LogManager.GetLogger(typeof(Program));

            // For some reason, in a console app you need to set the LogFactory manually!
            ServiceStack.Logging.LogManager.LogFactory = new ServiceStack.Logging.Log4Net.Log4NetFactory("Client.exe.config");
            var Log = LogManager.GetLogger(typeof(Program));

            /*
             * Log.Info("Info");
             * Log.Debug("Debug");
             * Log.Warn("Warn");
             * Log.Error("Error");
             * Log.Fatal("Fatal");
             */

            Log.Info("===== Starting Client =====");
            IMessageQueueClient      c;
            AwsSqsMessageQueueClient sqsMessageQueueClient;

            // var svc = new InMemoryTransientMessageService();
            // var svc = new RedisMqServer(new PooledRedisClientManager(new[] { "localhost:6379" }));
            var svc = MessageServerFactory.CreateMessageService();

            // Register the handlers before creating any client objects.
            using (var messageQueueClient = svc.MessageFactory.CreateMessageQueueClient())
            {
                Log.Info("===== Message Queue Client Started =====");
                Log.Info("Type 'EXIT' to close.");
                // svc.Start();

                while (true)
                {
                    // The MqClient should result in a message in the out q, as the messages are not configured to be one-way
                    messageQueueClient.Publish(new Hello {
                        Text = "This comes from the client"
                    });

                    // This message should return a response.
                    messageQueueClient.Publish(new Hello3 {
                        Text = "This comes from the client #3"
                    });

                    Log.Info("Waiting for message response.");
                    var responseQueueName = new VersionedQueueNames(typeof(Hello3Response)).In;  // QueueNames<Hello3Response>.In;
                    var response          = messageQueueClient.Get(responseQueueName, TimeSpan.FromSeconds(20));
                    if (response != null)
                    {
                        var obj = response.ToMessage <Hello3Response>().GetBody();
                        Log.InfoFormat("Message response received: {0}", obj.ResponseText);
                        sqsMessageQueueClient = messageQueueClient as AwsSqsMessageQueueClient;
                        if (sqsMessageQueueClient != null)
                        {
                            sqsMessageQueueClient.DeleteMessageFromQueue(responseQueueName, obj.ReceiptHandle);
                        }

                        Log.InfoFormat("Deleted response message from queue: {0}", obj.QueueName);
                    }
                    else
                    {
                        Log.Info("No message response received.");
                    }

                    // ================== REQ/REPLY MQ ===============
                    var uniqueCallbackQ = "mq:c1" + ":" + Guid.NewGuid().ToString("N");
                    messageQueueClient.Publish(new Message <Hello4>(new Hello4 {
                        Text = "This comes from the client #4"
                    })
                    {
                        ReplyTo = uniqueCallbackQ
                    });

                    Log.Info("Waiting for message response.");
                    var uniqueResponse = messageQueueClient.Get(uniqueCallbackQ, TimeSpan.FromSeconds(20));
                    if (uniqueResponse != null)
                    {
                        var obj = uniqueResponse.ToMessage <Hello4Response>().GetBody();
                        Log.InfoFormat("Message response received: {0}", obj.ResponseText);
                        sqsMessageQueueClient = messageQueueClient as AwsSqsMessageQueueClient;
                        if (sqsMessageQueueClient != null)
                        {
                            sqsMessageQueueClient.DeleteMessageFromQueue(uniqueCallbackQ, obj.ReceiptHandle);
                        }

                        Log.InfoFormat("Deleted response message from queue: {0}", obj.QueueName);
                    }
                    else
                    {
                        Log.Info("No message response received.");
                    }

                    // Optionally, delete the mq.
                    sqsMessageQueueClient = messageQueueClient as AwsSqsMessageQueueClient;
                    if (sqsMessageQueueClient != null)
                    {
                        sqsMessageQueueClient.DeleteQueue(uniqueCallbackQ);
                    }
                    // ===============================================

                    // TODO: TEST - messageQueueClient.WaitForNotifyOnAny()

                    var text = Console.ReadLine() ?? string.Empty;
                    if (text.ToUpperInvariant() == "EXIT")
                    {
                        break;
                    }
                }
            }

            Log.Info("Stopping Client.");
        }
コード例 #7
0
        protected override string GetQueueNameOrUrl <T>(IMessage <T> message)
        {
            var messageQueueName = new VersionedQueueNames(typeof(T)).In;

            return(this.QueueUrls[messageQueueName]);
        }