예제 #1
0
        private async Task _processMessage(
            QMessage qMessage,
            Type messageType,
            Type modelType,
            object processor,
            Message receivedMessage)
        {
            _settings.Logger?.Debug("Executing processor message received.", qMessage.Id);

            await _executeAsyncMethod(Constants.MethodNames.Received,
                                      messageType, processor, _obj(receivedMessage, _settings.Logger));

            _settings.Logger?.Debug("Deserializing message body.", qMessage.Id);

            var body = Newtonsoft.Json.JsonConvert.DeserializeObject(receivedMessage.Body, modelType);

            _settings.Logger?.Debug("Executing processor message validation.", qMessage.Id);

            var validatedModel = await _executeAsyncMethod <object>(Constants.MethodNames.Validate,
                                                                    messageType, processor, _obj(receivedMessage, body, _settings.Logger));

            if (validatedModel != null)
            {
                _settings.Logger?.Debug("Executing processor message processing.", qMessage.Id);

                var reply = await _executeAsyncMethod <QReply>(Constants.MethodNames.Process,
                                                               messageType, processor, _obj(receivedMessage, validatedModel, _settings.Logger));

                if (reply != null && !string.IsNullOrEmpty(reply.ReplyToQueueUrl))
                {
                    await SendAsync(reply.Message, reply.ReplyToQueueUrl);
                }

                if (_settings.DeleteIfSuccess)
                {
                    await DeleteAsync(qMessage);
                }
            }
            else
            {
                _settings.Logger?.Debug("Message with id {Id} was marked invalid by processor and execution has stopped.",
                                        qMessage.Id);

                if (_settings.DeleteIfInvalid)
                {
                    await DeleteAsync(qMessage);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Delete a message from a queue.
        /// </summary>
        /// <param name="message">The QMessage to delete.</param>
        /// <returns>Task</returns>
        /// <exception cref="Exception">Throws if delete fails.</exception>
        public async Task DeleteAsync(
            QMessage message)
        {
            var result = await
                         _sqsClient.DeleteMessageAsync(new DeleteMessageRequest(_settings.QueueUrl,
                                                                                message.AwsSqsMessage.ReceiptHandle));

            if (result.HttpStatusCode == HttpStatusCode.OK)
            {
                _settings.Logger?.Debug("Message id {id} deleted from queue.", message.Id);
            }
            else
            {
                throw new Exception($"Error deleting message id {message.Id} to queue {_settings.QueueUrl}.");
            }
        }
예제 #3
0
        /// <summary>
        /// Send an SQS message to the specified queue url.
        /// </summary>
        /// <param name="message">QMessage to send.</param>
        /// <param name="queueUrl">Queue url to send to.</param>
        /// <returns>Task</returns>
        /// <exception cref="Exception">Throws if not successful.</exception>
        public async Task SendAsync(
            QMessage message,
            string queueUrl)
        {
            var result = await _sqsClient.SendMessageAsync(new SendMessageRequest()
            {
                MessageBody       = message.Body,
                QueueUrl          = queueUrl,
                MessageAttributes = message.MessageAttributes
            });

            if (result.HttpStatusCode == HttpStatusCode.OK)
            {
                _settings.Logger?.Debug("Sent message {MessageId} to queue {queueUrl}.", result.MessageId, queueUrl);
            }
            else
            {
                throw new Exception($"Error sending message to queue {queueUrl}.");
            }
        }
예제 #4
0
        /// <summary>
        /// Polls the queue url specified in the QBrokerSettings and processes according to the added processors.
        /// </summary>
        /// <returns>Task</returns>
        /// <exception cref="Exception"></exception>
        public async Task FetchAsync()
        {
            while (true)
            {
                _settings.Logger?.Information("Fetching queue messages.");

                var received = await _readMessages();

                if (received.HttpStatusCode != HttpStatusCode.OK)
                {
                    throw new Exception($"Unable to read messages from queue {_settings.QueueUrl}. AWS responded with code {received.HttpStatusCode}.");
                }

                if (received.Messages.Count <= 0)
                {
                    return;
                }

                _settings.Logger?.Information("Processing {Count} messages.", received.Messages.Count);

                foreach (var receivedMessage in received.Messages)
                {
                    QMessage qMessage;

                    try
                    {
                        qMessage = new QMessage(receivedMessage);
                    }
                    catch (ArgumentException)
                    {
                        _settings.Logger?
                        .Debug("Message id {Id} does not appear to be a valid QBroker message and will be skipped.",
                               receivedMessage.MessageId);
                        continue;
                    }

                    _settings.Logger?.Debug("Processing message with id {Id}.", qMessage.Id);

                    var messageVersion = Semver.SemVersion.Parse(qMessage.Version);
                    var compare        = SemVersion.Compare(messageVersion, Constants.Library.SemVersion);
                    switch (compare)
                    {
                    case -1:
                        _settings.Logger?.Warning(
                            "Message id {id} was created using version {messageVersion} which is older than this version {currentVersion}",
                            qMessage.Id, messageVersion, Constants.Library.Version);
                        break;

                    case 1:
                        _settings.Logger?.Warning(
                            "Message id {id} was created using version {messageVersion} which is newer than this version {currentVersion}",
                            qMessage.Id, messageVersion, Constants.Library.Version);
                        break;
                    }

                    if (!_messageTypes.ContainsKey(qMessage.Name))
                    {
                        _settings.Logger?.Debug("Skipping message id {Id}. No processor found for message name.", qMessage.Id);
                        continue;
                    }

                    var messageType = _messageTypes[qMessage.Name];
                    var modelType   = _modelTypes[qMessage.Name];

                    var processor = _serviceProvider == null
                        ? Activator.CreateInstance(messageType)
                        : ActivatorUtilities.CreateInstance(_serviceProvider, messageType);

                    try
                    {
                        await _processMessage(qMessage, messageType, modelType, processor, receivedMessage);
                    }
                    catch (Exception e)
                    {
                        _settings.Logger?.Debug("Executing processor message error for message id {id}.", qMessage.Id);

                        await _executeAsyncMethod(Constants.MethodNames.Error, messageType, processor,
                                                  _obj(receivedMessage, e, _settings.Logger));

                        if (_settings.DeleteIfError)
                        {
                            await DeleteAsync(qMessage);
                        }
                    }
                }

                if (_settings.FetchUntilEmpty)
                {
                    continue;
                }
                break;
            }
        }