Ejemplo n.º 1
0
        /// <summary>
        /// Publishes the provided <paramref name="command"/> on the command bus.
        /// </summary>
        public virtual void Publish <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            if (command == null)
            {
                Logger.LogDebug("No command to publish.");
                return;
            }
            Type           commandType        = command.GetType();
            DateTimeOffset startedAt          = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch      = Stopwatch.StartNew();
            string         responseCode       = "200";
            bool           mainWasSuccessfull = false;
            bool           telemeterOverall   = false;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/Servicebus" }
            };
            string telemetryName      = string.Format("{0}/{1}/{2}", commandType.FullName, command.GetIdentity(), command.Id);
            var    telemeteredCommand = command as ITelemeteredMessage;

            if (telemeteredCommand != null)
            {
                telemetryName = telemeteredCommand.TelemetryName;
            }
            else
            {
                telemetryName = string.Format("Command/{0}", telemetryName);
            }

            try
            {
                if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
                {
                    return;
                }

                bool?isPublicBusRequired  = BusHelper.IsPublicBusRequired(commandType);
                bool?isPrivateBusRequired = BusHelper.IsPrivateBusRequired(commandType);

                // We only add telemetry for overall operations if two occurred
                telemeterOverall = isPublicBusRequired != null && isPublicBusRequired.Value && isPrivateBusRequired != null && isPrivateBusRequired.Value;

                // Backwards compatibility and simplicity
                bool      wasSuccessfull;
                Stopwatch stopWatch = Stopwatch.StartNew();
                if ((isPublicBusRequired == null || !isPublicBusRequired.Value) && (isPrivateBusRequired == null || !isPrivateBusRequired.Value))
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = CreateBrokeredMessage(MessageSerialiser.SerialiseCommand, commandType, command);
                        int count           = 1;
                        do
                        {
                            try
                            {
#if NET452
                                PublicServiceBusPublisher.Send(brokeredMessage);
#endif
#if NETSTANDARD2_0
                                PublicServiceBusPublisher.SendAsync(brokeredMessage).Wait();
#endif
                                break;
                            }
                            catch (TimeoutException)
                            {
                                if (count >= TimeoutOnSendRetryMaximumCount)
                                {
                                    throw;
                                }
                            }
                            count++;
                        } while (true);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the command being sent was too large or the topic has reached it's limit.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Command", telemetryName, "Default Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(string.Format("A command was published on the public bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                }
                if ((isPublicBusRequired != null && isPublicBusRequired.Value))
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = CreateBrokeredMessage(MessageSerialiser.SerialiseCommand, commandType, command);
                        int count           = 1;
                        do
                        {
                            try
                            {
#if NET452
                                PublicServiceBusPublisher.Send(brokeredMessage);
#endif
#if NETSTANDARD2_0
                                PublicServiceBusPublisher.SendAsync(brokeredMessage).Wait();
#endif
                                break;
                            }
                            catch (TimeoutException)
                            {
                                if (count >= TimeoutOnSendRetryMaximumCount)
                                {
                                    throw;
                                }
                            }
                            count++;
                        } while (true);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the command being sent was too large or the topic has reached it's limit.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Command", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(string.Format("A command was published on the public bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                }
                if (isPrivateBusRequired != null && isPrivateBusRequired.Value)
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = CreateBrokeredMessage(MessageSerialiser.SerialiseCommand, commandType, command);
                        int count           = 1;
                        do
                        {
                            try
                            {
#if NET452
                                PrivateServiceBusPublisher.Send(brokeredMessage);
#endif
#if NETSTANDARD2_0
                                PrivateServiceBusPublisher.SendAsync(brokeredMessage).Wait();
#endif
                                break;
                            }
                            catch (TimeoutException)
                            {
                                if (count >= TimeoutOnSendRetryMaximumCount)
                                {
                                    throw;
                                }
                            }
                            count++;
                        } while (true);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the command being sent was too large or the topic has reached it's limit.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an command.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Command", command }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Command", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }

                    Logger.LogDebug(string.Format("An command was published on the private bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                }
                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                if (telemeterOverall)
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, mainWasSuccessfull, telemetryProperties);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Publishes the provided <paramref name="commands"/> on the command bus.
        /// </summary>
        public virtual void Publish <TCommand>(IEnumerable <TCommand> commands)
            where TCommand : ICommand <TAuthenticationToken>
        {
            if (commands == null)
            {
                Logger.LogDebug("No commands to publish.");
                return;
            }
            IList <TCommand> sourceCommands = commands.ToList();

            if (!sourceCommands.Any())
            {
                Logger.LogDebug("An empty collection of commands to publish.");
                return;
            }

            DateTimeOffset startedAt          = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch      = Stopwatch.StartNew();
            string         responseCode       = "200";
            bool           mainWasSuccessfull = false;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/Servicebus" }
            };
            string telemetryName  = "Commands";
            string telemetryNames = string.Empty;

            foreach (TCommand command in sourceCommands)
            {
                Type   commandType        = command.GetType();
                string subTelemetryName   = string.Format("{0}/{1}", commandType.FullName, command.Id);
                var    telemeteredCommand = command as ITelemeteredMessage;
                if (telemeteredCommand != null)
                {
                    subTelemetryName = telemeteredCommand.TelemetryName;
                }
                telemetryNames = string.Format("{0}{1},", telemetryNames, subTelemetryName);
            }
            if (telemetryNames.Length > 0)
            {
                telemetryNames = telemetryNames.Substring(0, telemetryNames.Length - 1);
            }
            telemetryProperties.Add("Commands", telemetryNames);

            try
            {
                IList <string>          sourceCommandMessages   = new List <string>();
                IList <BrokeredMessage> privateBrokeredMessages = new List <BrokeredMessage>(sourceCommands.Count);
                IList <BrokeredMessage> publicBrokeredMessages  = new List <BrokeredMessage>(sourceCommands.Count);
                foreach (TCommand command in sourceCommands)
                {
                    if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
                    {
                        continue;
                    }

                    Type commandType = command.GetType();

                    BrokeredMessage brokeredMessage = CreateBrokeredMessage(MessageSerialiser.SerialiseCommand, commandType, command);

                    bool?isPublicBusRequired  = BusHelper.IsPublicBusRequired(commandType);
                    bool?isPrivateBusRequired = BusHelper.IsPrivateBusRequired(commandType);

                    // Backwards compatibility and simplicity
                    if ((isPublicBusRequired == null || !isPublicBusRequired.Value) && (isPrivateBusRequired == null || !isPrivateBusRequired.Value))
                    {
                        publicBrokeredMessages.Add(brokeredMessage);
                        sourceCommandMessages.Add(string.Format("A command was published on the public bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                    }
                    if ((isPublicBusRequired != null && isPublicBusRequired.Value))
                    {
                        publicBrokeredMessages.Add(brokeredMessage);
                        sourceCommandMessages.Add(string.Format("A command was published on the public bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                    }
                    if (isPrivateBusRequired != null && isPrivateBusRequired.Value)
                    {
                        privateBrokeredMessages.Add(brokeredMessage);
                        sourceCommandMessages.Add(string.Format("A command was published on the private bus with the id '{0}' was of type {1}.", command.Id, commandType.FullName));
                    }
                }

                bool      wasSuccessfull;
                Stopwatch stopWatch = Stopwatch.StartNew();

                // Backwards compatibility and simplicity
                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    int count = 1;
                    do
                    {
                        try
                        {
                            if (publicBrokeredMessages.Any())
                            {
#if NET452
                                PublicServiceBusPublisher.SendBatch(publicBrokeredMessages);
#endif
#if NETSTANDARD2_0
                                PublicServiceBusPublisher.SendAsync(publicBrokeredMessages).Wait();
#endif
                            }
                            else
                            {
                                Logger.LogDebug("An empty collection of public commands to publish post validation.");
                            }
                            break;
                        }
                        catch (TimeoutException)
                        {
                            if (count >= TimeoutOnSendRetryMaximumCount)
                            {
                                throw;
                            }
                        }
                        count++;
                    } while (true);
                    wasSuccessfull = true;
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", publicBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", publicBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    int count = 1;
                    do
                    {
                        try
                        {
                            if (privateBrokeredMessages.Any())
                            {
#if NET452
                                PrivateServiceBusPublisher.SendBatch(privateBrokeredMessages);
#endif
#if NETSTANDARD2_0
                                PrivateServiceBusPublisher.SendAsync(privateBrokeredMessages).Wait();
#endif
                            }
                            else
                            {
                                Logger.LogDebug("An empty collection of private commands to publish post validation.");
                            }
                            break;
                        }
                        catch (TimeoutException)
                        {
                            if (count >= TimeoutOnSendRetryMaximumCount)
                            {
                                throw;
                            }
                        }
                        count++;
                    } while (true);
                    wasSuccessfull = true;
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", privateBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Command", privateBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

                foreach (string message in sourceCommandMessages)
                {
                    Logger.LogInfo(message);
                }

                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, mainWasSuccessfull, telemetryProperties);
            }
        }