Пример #1
0
        public async Task UserSettledPropertySetCorrectly()
        {
            var msg  = new ServiceBusReceivedMessage();
            var args = new ProcessMessageEventArgs(
                msg,
                new Mock <ServiceBusReceiver>().Object,
                CancellationToken.None);

            Assert.IsFalse(msg.IsSettled);

            msg.IsSettled = false;
            await args.AbandonMessageAsync(msg);

            Assert.IsTrue(msg.IsSettled);

            await args.CompleteMessageAsync(msg);

            Assert.IsTrue(msg.IsSettled);

            msg.IsSettled = false;
            await args.DeadLetterMessageAsync(msg);

            Assert.IsTrue(msg.IsSettled);

            msg.IsSettled = false;
            await args.DeadLetterMessageAsync(msg, "reason");

            Assert.IsTrue(msg.IsSettled);

            msg.IsSettled = false;
            await args.DeferMessageAsync(msg);

            Assert.IsTrue(msg.IsSettled);
        }
Пример #2
0
        private async Task MessageHandler(ProcessMessageEventArgs args)
        {
            try
            {
                _logger.LogInformation($"client '{_systemInfo.ClientId}' received message '{args.Message.MessageId}'. Processing...");

                var message = await _messageParser.DeserializeAsync <TM>(args.Message.Body);

                await _messageProcessor.ProcessAsync((dynamic)message, args.CancellationToken);

                await args.CompleteMessageAsync(args.Message).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"an error has occurred while processing message '{args.Message.MessageId}': {ex.Message}");
                if (args.Message.DeliveryCount > 3)
                {
                    await args.DeadLetterMessageAsync(args.Message).ConfigureAwait(false);
                }
                else
                {
                    await args.AbandonMessageAsync(args.Message).ConfigureAwait(false);
                }
            }
        }
 public static Task AbandonByErrorAsync(this ServiceBusReceivedMessage message, ProcessMessageEventArgs client, Exception e)
 {
     return(client.AbandonMessageAsync(message, new Dictionary <string, object>
     {
         { "ErrorMessage", e.Message },
         { "Exception", e.ToString() }
     }));
 }
Пример #4
0
            private async Task _processor_ProcessMessageAsync(ProcessMessageEventArgs arg)
            {
                try
                {
                    var body = arg.Message.Body.ToMemory();
                    await _procmessage(body);

                    await arg.CompleteMessageAsync(arg.Message);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, $"ServiceBusProcessor for queue {_queueName} processed message {arg.Message.MessageId} with error");
                    await arg.AbandonMessageAsync(arg.Message);
                }
            }
        private async Task MessageHandler(ProcessMessageEventArgs args)
        {
            string body = args.Message.Body.ToString();

            try
            {
                Console.WriteLine($"Message received - {body}");
                await args.CompleteMessageAsync(args.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Unable to process message {ex}");
                await args.AbandonMessageAsync(args.Message);
            }
        }
Пример #6
0
        private async Task MessageHandler(ProcessMessageEventArgs args)
        {
            telemetryProvider.TrackTrace("Trace Receiver");
            string body = args.Message.Body.ToString();

            try
            {
                action.ReceiveMessage(body);
                await args.CompleteMessageAsync(args.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Unable to process message {ex}");
                await args.AbandonMessageAsync(args.Message);
            }
        }
        //protected override async Task MessageReceivedHandler(ServiceBusReceivedMessage receivedMessage, CancellationToken token)
        protected override async Task MessageReceivedHandler(ProcessMessageEventArgs receivedMessage)//, CancellationToken token)
        {
            try
            {
                await base.MessageReceivedHandler(receivedMessage);//, token);

                //await Client.CompleteMessageAsync(receivedMessage.Message);
                await receivedMessage.CompleteMessageAsync(receivedMessage.Message);
            }
            catch
            {
                //await Client.AbandonMessageAsync(receivedMessage);
                await receivedMessage.AbandonMessageAsync(receivedMessage.Message);

                throw;
            }
        }
Пример #8
0
        private async Task ProcessMessageAsync(ProcessMessageEventArgs args)
        {
            ServiceBusReceivedMessage message = args?.Message;

            if (message is null)
            {
                Logger.LogWarning("Received message on Azure Service Bus message pump '{JobId}' was null, skipping", JobId);
                return;
            }

            if (_isHostShuttingDown)
            {
                Logger.LogWarning("Abandoning message with ID '{MessageId}' as the Azure Service Bus message pump is shutting down", message.MessageId);
                await args.AbandonMessageAsync(message);

                return;
            }

            if (String.IsNullOrEmpty(message.CorrelationId))
            {
                Logger.LogTrace("No operation ID was found on the message '{MessageId}' during processing in the Azure Service Bus message pump '{JobId}'", message.MessageId, JobId);
            }

            AzureServiceBusMessageContext messageContext  = message.GetMessageContext(JobId);
            MessageCorrelationInfo        correlationInfo = message.GetCorrelationInfo(Settings.Options.Correlation?.TransactionIdPropertyName ?? PropertyNames.TransactionId);
            ServiceBusReceiver            receiver        = args.GetServiceBusReceiver();

            using (IServiceScope serviceScope = ServiceProvider.CreateScope())
            {
                var correlationInfoAccessor = serviceScope.ServiceProvider.GetService <ICorrelationInfoAccessor <MessageCorrelationInfo> >();
                if (correlationInfoAccessor is null)
                {
                    Logger.LogTrace("No message correlation configured in Azure Service Bus message pump '{JobId}' while processing message '{MessageId}'", JobId, message.MessageId);
                    await _messageRouter.RouteMessageAsync(receiver, args.Message, messageContext, correlationInfo, args.CancellationToken);
                }
                else
                {
                    correlationInfoAccessor.SetCorrelationInfo(correlationInfo);
                    using (LogContext.Push(new MessageCorrelationInfoEnricher(correlationInfoAccessor)))
                    {
                        await _messageRouter.RouteMessageAsync(receiver, args.Message, messageContext, correlationInfo, args.CancellationToken);
                    }
                }
            }
        }
 ///<inheritdoc cref="ServiceBusReceiver.AbandonMessageAsync(ServiceBusReceivedMessage, IDictionary{string, object}, CancellationToken)"/>
 public virtual async Task AbandonMessageAsync(
     ServiceBusReceivedMessage message,
     IDictionary <string, object> propertiesToModify = default,
     CancellationToken cancellationToken             = default)
 {
     if (_receiver != null)
     {
         await _receiver.AbandonMessageAsync(message, propertiesToModify, cancellationToken).ConfigureAwait(false);
     }
     else if (_eventArgs != null)
     {
         await _eventArgs.AbandonMessageAsync(message, propertiesToModify, cancellationToken).ConfigureAwait(false);
     }
     else
     {
         await _sessionEventArgs.AbandonMessageAsync(message, propertiesToModify, cancellationToken).ConfigureAwait(false);
     }
 }
        private async Task MessageHandler(ProcessMessageEventArgs args)
        {
            try
            {
                var message = _messageParser.Resolve <TM>(args.Message.Body);

                await _messageProcessor.ProcessAsync((dynamic)message, args.CancellationToken);

                await args.CompleteMessageAsync(args.Message).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"an error has occurred while processing message '{args.Message.MessageId}': {ex.Message}");
                if (args.Message.DeliveryCount > 3)
                {
                    await args.DeadLetterMessageAsync(args.Message).ConfigureAwait(false);
                }
                else
                {
                    await args.AbandonMessageAsync(args.Message).ConfigureAwait(false);
                }
            }
        }
Пример #11
0
        public void UserSettledPropertySetCorrectlyOnException()
        {
            var msg          = new ServiceBusReceivedMessage();
            var mockReceiver = new Mock <ServiceBusReceiver>();

            mockReceiver
            .Setup(receiver => receiver.AbandonMessageAsync(
                       It.IsAny <ServiceBusReceivedMessage>(),
                       It.IsAny <IDictionary <string, object> >(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            mockReceiver
            .Setup(receiver => receiver.DeferMessageAsync(
                       It.IsAny <ServiceBusReceivedMessage>(),
                       It.IsAny <IDictionary <string, object> >(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            mockReceiver
            .Setup(receiver => receiver.CompleteMessageAsync(
                       It.IsAny <ServiceBusReceivedMessage>(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            mockReceiver
            .Setup(receiver => receiver.DeadLetterMessageAsync(
                       It.IsAny <ServiceBusReceivedMessage>(),
                       It.IsAny <IDictionary <string, object> >(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            mockReceiver
            .Setup(receiver => receiver.DeadLetterMessageAsync(
                       It.IsAny <ServiceBusReceivedMessage>(),
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            var args = new ProcessMessageEventArgs(
                msg,
                mockReceiver.Object,
                CancellationToken.None);

            Assert.IsFalse(msg.IsSettled);

            msg.IsSettled = false;
            Assert.That(async() => await args.AbandonMessageAsync(msg),
                        Throws.InstanceOf <Exception>());
            Assert.IsFalse(msg.IsSettled);

            Assert.That(async() => await args.CompleteMessageAsync(msg),
                        Throws.InstanceOf <Exception>());
            Assert.IsFalse(msg.IsSettled);

            msg.IsSettled = false;
            Assert.That(async() => await args.DeadLetterMessageAsync(msg),
                        Throws.InstanceOf <Exception>());
            Assert.IsFalse(msg.IsSettled);

            msg.IsSettled = false;
            Assert.That(async() => await args.DeadLetterMessageAsync(msg, "reason"),
                        Throws.InstanceOf <Exception>());
            Assert.IsFalse(msg.IsSettled);

            msg.IsSettled = false;
            Assert.That(async() => await args.DeferMessageAsync(msg),
                        Throws.InstanceOf <Exception>());
            Assert.IsFalse(msg.IsSettled);
        }
Пример #12
0
        private static async Task MessageHandler(ProcessMessageEventArgs args)
        {
            Console.WriteLine("Processing message '{0}'", args.Message.ToString());

            var message = args.Message;

            JobPayload    jobPayload;
            DevopsMessage devopsMessage = null;
            Job           driverJob     = null;

            try
            {
                // The DevopsMessage does the communications with AzDo
                devopsMessage = new DevopsMessage(message);

                // The Body contains the parameters for the application to run
                // We can't use message.Body.FromObjectAsJson since the raw json returned by AzDo is not valid
                jobPayload = JobPayload.Deserialize(message.Body.ToArray());

                await devopsMessage.SendTaskStartedEventAsync();

                var arguments = String.Join(' ', jobPayload.Args);

                Console.WriteLine("Invoking crank with arguments: " + arguments);

                // The DriverJob manages the application's lifetime and standard output
                driverJob = new Job("crank", arguments);

                driverJob.OnStandardOutput = log => Console.WriteLine(log);

                Console.WriteLine("Processing...");

                driverJob.Start();

                // Pump application standard output while it's running
                while (driverJob.IsRunning)
                {
                    if ((DateTime.UtcNow - driverJob.StartTimeUtc) > jobPayload.Timeout)
                    {
                        throw new Exception("Job timed out. The timeout can be increased in the queued message.");
                    }

                    var logs = driverJob.FlushStandardOutput().ToArray();

                    // Send any page of logs to the AzDo task log feed
                    if (logs.Any())
                    {
                        var success = await devopsMessage.SendTaskLogFeedsAsync(String.Join("\r\n", logs));

                        if (!success)
                        {
                            Console.ForegroundColor = ConsoleColor.DarkYellow;
                            Console.WriteLine("SendTaskLogFeedsAsync failed. If the task was canceled, this jobs should be ignored stopped.");
                            Console.ResetColor();
                        }
                    }

                    await Task.Delay(TaskLogFeedDelay);
                }

                // Mark the task as completed
                await devopsMessage.SendTaskCompletedEventAsync(succeeded : driverJob.WasSuccessful);

                // Create a task log entry
                var taskLogObjectString = await devopsMessage?.CreateTaskLogAsync();

                if (String.IsNullOrEmpty(taskLogObjectString))
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine("CreateTaskLogAsync failed. The job is probably canceled.");
                    Console.ResetColor();
                }
                else
                {
                    var taskLogObject = JsonSerializer.Deserialize <Dictionary <string, object> >(taskLogObjectString);

                    var taskLogId = taskLogObject["id"].ToString();

                    await devopsMessage?.AppendToTaskLogAsync(taskLogId, driverJob.OutputBuilder.ToString());

                    // Attach task log to the timeline record
                    await devopsMessage?.UpdateTaskTimelineRecordAsync(taskLogObjectString);
                }

                // Mark the message as completed
                await args.CompleteMessageAsync(message);

                driverJob.Stop();

                Console.WriteLine("Job completed");
            }
            catch (Exception e)
            {
                Console.WriteLine("Job failed: " + e.ToString());

                Console.WriteLine("Stopping the task and releasing the message...");

                try
                {
                    await devopsMessage?.SendTaskCompletedEventAsync(succeeded : false);
                }
                catch (Exception f)
                {
                    Console.WriteLine("Failed to complete the task: " + f.ToString());
                }

                try
                {
                    // TODO: Should the message still be copmleted instead of abandonned?
                    await args.AbandonMessageAsync(message);
                }
                catch (Exception f)
                {
                    Console.WriteLine("Failed to abandon the message: " + f.ToString());
                }
            }
            finally
            {
                driverJob?.Dispose();
            }
        }
Пример #13
0
        private static async Task MessageHandler(ProcessMessageEventArgs args)
        {
            Console.WriteLine($"{LogNow} Processing message '{args.Message}'");

            var message = args.Message;

            JobPayload    jobPayload;
            DevopsMessage devopsMessage = null;
            Job           driverJob     = null;

            try
            {
                // The DevopsMessage does the communications with AzDo
                devopsMessage = new DevopsMessage(message);

                // The Body contains the parameters for the application to run
                // We can't use message.Body.FromObjectAsJson since the raw json returned by AzDo is not valid
                jobPayload = JobPayload.Deserialize(message.Body.ToArray());

                // The only way to detect if a Task still needs to be executed is to download all the details of all tasks (there is no API to retrieve the status of a single task.

                var records = await devopsMessage.GetRecordsAsync();

                if (records == null)
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.WriteLine($"{LogNow} Could not retrieve records...");
                    Console.ResetColor();

                    return;
                }

                var record = records.Value.FirstOrDefault(x => x.Id == devopsMessage.TaskInstanceId);

                if (record != null && record.State == "completed")
                {
                    Console.WriteLine($"{LogNow} Job is completed ({record.Result}), skipping...");

                    // Mark the message as completed
                    await args.CompleteMessageAsync(message);
                }
                else
                {
                    if (!String.IsNullOrWhiteSpace(jobPayload.Condition))
                    {
                        try
                        {
                            var condition = Engine.Execute(jobPayload.Condition).GetCompletionValue().AsBoolean();

                            if (!condition)
                            {
                                await devopsMessage?.SendTaskCompletedEventAsync(DevopsMessage.ResultTypes.Skipped);

                                Console.WriteLine($"{LogNow} Job skipped based on condition [{jobPayload.Condition}]");

                                // Mark the message as completed
                                await args.CompleteMessageAsync(message);

                                return;
                            }
                        }
                        catch
                        {
                            Console.WriteLine($"{LogNow} Could not evaluate codition [{jobPayload.Condition}], ignoring ...");
                        }
                    }

                    // Inform AzDo that the job is started
                    await devopsMessage.SendTaskStartedEventAsync();

                    var arguments = String.Join(' ', jobPayload.Args);

                    Console.WriteLine($"{LogNow} Invoking crank with arguments: {arguments}");

                    // The DriverJob manages the application's lifetime and standard output
                    driverJob = new Job("crank", arguments);

                    driverJob.OnStandardOutput = log => Console.WriteLine(log);

                    driverJob.Start();

                    // Pump application standard output while it's running
                    while (driverJob.IsRunning)
                    {
                        if ((DateTime.UtcNow - driverJob.StartTimeUtc) > jobPayload.Timeout)
                        {
                            throw new Exception($"{LogNow} Job timed out ({jobPayload.Timeout}). The timeout can be increased in the queued message.");
                        }

                        var logs = driverJob.FlushStandardOutput().ToArray();

                        // Send any page of logs to the AzDo task log feed
                        if (logs.Any())
                        {
                            var success = await devopsMessage.SendTaskLogFeedsAsync(String.Join("\r\n", logs));

                            if (!success)
                            {
                                Console.ForegroundColor = ConsoleColor.DarkYellow;
                                Console.WriteLine($"{LogNow} SendTaskLogFeedsAsync failed. If the task was canceled, this jobs should be stopped.");
                                Console.ResetColor();

                                driverJob.Stop();
                            }
                        }

                        // Check if task is still active (not canceled)

                        records = await devopsMessage.GetRecordsAsync();

                        record = records.Value.FirstOrDefault(x => x.Id == devopsMessage.TaskInstanceId);

                        if (record != null && record?.State == "completed")
                        {
                            Console.WriteLine($"{LogNow} Job is completed ({record.Result}), interrupting...");

                            driverJob.Stop();
                        }

                        await Task.Delay(TaskLogFeedDelay);
                    }

                    // Mark the task as completed
                    await devopsMessage.SendTaskCompletedEventAsync(driverJob.WasSuccessful?DevopsMessage.ResultTypes.Succeeded : DevopsMessage.ResultTypes.Failed);

                    // Create a task log entry
                    var taskLogObjectString = await devopsMessage?.CreateTaskLogAsync();

                    if (String.IsNullOrEmpty(taskLogObjectString))
                    {
                        Console.ForegroundColor = ConsoleColor.DarkYellow;
                        Console.WriteLine($"{LogNow} CreateTaskLogAsync failed. The job is probably canceled.");
                        Console.ResetColor();
                    }
                    else
                    {
                        var taskLogObject = JsonSerializer.Deserialize <Dictionary <string, object> >(taskLogObjectString);

                        var taskLogId = taskLogObject["id"].ToString();

                        await devopsMessage?.AppendToTaskLogAsync(taskLogId, driverJob.OutputBuilder.ToString());

                        // Attach task log to the timeline record
                        await devopsMessage?.UpdateTaskTimelineRecordAsync(taskLogObjectString);
                    }

                    // Mark the message as completed
                    await args.CompleteMessageAsync(message);

                    driverJob.Stop();

                    Console.WriteLine($"{LogNow} Job completed");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"{LogNow} Job failed: {e}");

                Console.WriteLine("Stopping the task and releasing the message...");

                try
                {
                    await devopsMessage?.SendTaskCompletedEventAsync(DevopsMessage.ResultTypes.Failed);
                }
                catch (Exception f)
                {
                    Console.WriteLine($"{LogNow} Failed to complete the task: {f}");
                }

                try
                {
                    // TODO: Should the message still be copmleted instead of abandonned?
                    await args.AbandonMessageAsync(message);
                }
                catch (Exception f)
                {
                    Console.WriteLine($"{LogNow} Failed to abandon the message: {f}");
                }
            }
            finally
            {
                try
                {
                    driverJob?.Dispose();
                }
                catch (Exception e)
                {
                    Console.WriteLine($"{LogNow} Failed to dispose the job : {e}");
                }
            }
        }