Ejemplo n.º 1
0
        /// <summary>
        /// Publishes the provided <paramref name="events"/> on the event bus.
        /// </summary>
        public virtual void Publish <TEvent>(IEnumerable <TEvent> events)
            where TEvent : IEvent <TAuthenticationToken>
        {
            IList <TEvent> sourceEvents = events.ToList();

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

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

            foreach (TEvent @event in sourceEvents)
            {
                string subTelemetryName = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
                var    telemeteredEvent = @event as ITelemeteredMessage;
                if (telemeteredEvent != null)
                {
                    subTelemetryName = telemeteredEvent.TelemetryName;
                }
                telemetryNames = string.Format("{0}{1},", telemetryNames, subTelemetryName);
            }
            if (telemetryNames.Length > 0)
            {
                telemetryNames = telemetryNames.Substring(0, telemetryNames.Length - 1);
            }
            telemetryProperties.Add("Events", telemetryNames);

            try
            {
                IList <string>          sourceEventMessages     = new List <string>();
                IList <BrokeredMessage> privateBrokeredMessages = new List <BrokeredMessage>(sourceEvents.Count);
                IList <BrokeredMessage> publicBrokeredMessages  = new List <BrokeredMessage>(sourceEvents.Count);
                foreach (TEvent @event in sourceEvents)
                {
                    if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-ServiceBus"))
                    {
                        continue;
                    }

                    var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                    {
                        CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                    };
                    brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

                    var privateEventAttribute = Attribute.GetCustomAttribute(typeof(TEvent), typeof(PrivateEventAttribute)) as PrivateEventAttribute;
                    var publicEventAttribute  = Attribute.GetCustomAttribute(typeof(TEvent), typeof(PrivateEventAttribute)) as PublicEventAttribute;

                    if
                    (
                        // Backwards compatibility and simplicity
                        (publicEventAttribute == null && privateEventAttribute == null)
                        ||
                        publicEventAttribute != null
                    )
                    {
                        publicBrokeredMessages.Add(brokeredMessage);
                        sourceEventMessages.Add(string.Format("An event was published on the public bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                    }
                    if (privateEventAttribute != null)
                    {
                        privateBrokeredMessages.Add(brokeredMessage);
                        sourceEventMessages.Add(string.Format("An event was published on the private bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                    }
                }

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

                // Backwards compatibility and simplicity
                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    PublicServiceBusPublisher.SendBatch(publicBrokeredMessages);
                    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> {
                        { "Events", publicBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", publicBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

                stopWatch.Restart();
                responseCode   = "200";
                wasSuccessfull = false;
                try
                {
                    PrivateServiceBusPublisher.SendBatch(privateBrokeredMessages);
                    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> {
                        { "Events", privateBrokeredMessages }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", privateBrokeredMessages }
                    });
                    throw;
                }
                finally
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                }

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

                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", 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);
            }
        }