Пример #1
0
        public virtual void Publish <TCommand>(TCommand command)
            where TCommand : ICommand <TAuthenticationToken>
        {
            DateTimeOffset startedAt      = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch  = Stopwatch.StartNew();
            string         responseCode   = "200";
            bool           wasSuccessfull = false;

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

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

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

                try
                {
                    var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseCommand(command))
                    {
                        CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                    };
                    brokeredMessage.Properties.Add("Type", command.GetType().FullName);
                    PrivateServiceBusPublisher.Send(brokeredMessage);
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the command being sent was too large.", 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;
                }

                Logger.LogInfo(string.Format("A command was sent of type {0}.", command.GetType().FullName));
                wasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            }
        }
Пример #2
0
        /// <summary>
        /// Publishes the provided <paramref name="command"></paramref> and waits for an event of <typeparamref name="TEvent"/> or exits if the specified timeout is expired.
        /// </summary>
        /// <param name="command">The <typeparamref name="TCommand"/> to publish.</param>
        /// <param name="condition">A delegate to be executed over and over until it returns the <typeparamref name="TEvent"/> that is desired, return null to keep trying.</param>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="F:System.Threading.Timeout.Infinite"/> (-1) to wait indefinitely.</param>
        /// <param name="eventReceiver">If provided, is the <see cref="IEventReceiver{TAuthenticationToken}" /> that the event is expected to be returned on.</param>
        public virtual TEvent PublishAndWait <TCommand, TEvent>(TCommand command, Func <IEnumerable <IEvent <TAuthenticationToken> >, TEvent> condition, int millisecondsTimeout,
                                                                IEventReceiver <TAuthenticationToken> eventReceiver = null) where TCommand : ICommand <TAuthenticationToken>
        {
            DateTimeOffset startedAt      = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch  = Stopwatch.StartNew();
            string         responseCode   = "200";
            bool           wasSuccessfull = false;

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

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

            TEvent result;

            try
            {
                if (eventReceiver != null)
                {
                    throw new NotSupportedException("Specifying a different event receiver is not yet supported.");
                }
                if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
                {
                    return((TEvent)(object)null);
                }

                result = (TEvent)(object)null;
                EventWaits.Add(command.CorrelationId, new List <IEvent <TAuthenticationToken> >());

                try
                {
                    var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseCommand(command))
                    {
                        CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                    };
                    brokeredMessage.Properties.Add("Type", command.GetType().FullName);
                    PrivateServiceBusPublisher.Send(brokeredMessage);
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the command being sent was too large.", 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;
                }
                Logger.LogInfo(string.Format("A command was sent of type {0}.", command.GetType().FullName));
                wasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            }

            SpinWait.SpinUntil(() =>
            {
                IList <IEvent <TAuthenticationToken> > events = EventWaits[command.CorrelationId];

                result = condition(events);

                return(result != null);
            }, millisecondsTimeout, sleepInMilliseconds: 1000);

            TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command/AndWait", string.Format("Command/AndWait{0}", telemetryName.Substring(7)), null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            return(result);
        }
Пример #3
0
        /// <summary>
        /// Publishes the provided <paramref name="event"/> on the event bus.
        /// </summary>
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            DateTimeOffset startedAt          = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch      = Stopwatch.StartNew();
            string         responseCode       = null;
            bool           mainWasSuccessfull = false;
            bool           telemeterOverall   = false;

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

            if (telemeteredEvent != null)
            {
                telemetryName = telemeteredEvent.TelemetryName;
            }
            telemetryName = string.Format("Event/{0}", telemetryName);

            try
            {
                if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-ServiceBus"))
                {
                    return;
                }

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

                // We only add telemetry for overall operations if two occured
                telemeterOverall = publicEventAttribute != null && privateEventAttribute != null;

                // Backwards compatibility and simplicity
                bool      wasSuccessfull;
                Stopwatch stopWatch = Stopwatch.StartNew();
                if (publicEventAttribute == null && privateEventAttribute == null)
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PublicServiceBusPublisher.Send(brokeredMessage);
                        wasSuccessfull = true;
                    }
                    catch (QuotaExceededException exception)
                    {
                        responseCode = "429";
                        Logger.LogError("The size of the event being sent was too large or the topic has reached it's limit.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Default Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(string.Format("An event was published on the public bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                }
                if (publicEventAttribute != null)
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PublicServiceBusPublisher.Send(brokeredMessage);
                        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> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Public Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }
                    Logger.LogDebug(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)
                {
                    stopWatch.Restart();
                    responseCode   = "200";
                    wasSuccessfull = false;
                    try
                    {
                        var brokeredMessage = new BrokeredMessage(MessageSerialiser.SerialiseEvent(@event))
                        {
                            CorrelationId = CorrelationIdHelper.GetCorrelationId().ToString("N")
                        };
                        brokeredMessage.Properties.Add("Type", @event.GetType().FullName);
                        PrivateServiceBusPublisher.Send(brokeredMessage);
                        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> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    catch (Exception exception)
                    {
                        responseCode = "500";
                        Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                            { "Event", @event }
                        });
                        throw;
                    }
                    finally
                    {
                        TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, "Private Bus", startedAt, stopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
                    }

                    Logger.LogDebug(string.Format("An event was published on the private bus with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
                }
                mainWasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                if (telemeterOverall)
                {
                    TelemetryHelper.TrackDependency("Azure/Servicebus/EventBus", "Event", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, mainWasSuccessfull, telemetryProperties);
                }
            }
        }
Пример #4
0
        public virtual void Publish <TCommand>(IEnumerable <TCommand> commands)
            where TCommand : ICommand <TAuthenticationToken>
        {
            IList <TCommand> sourceCommands = commands.ToList();

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

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

            foreach (TCommand command in sourceCommands)
            {
                string subTelemetryName   = string.Format("{0}/{1}", command.GetType().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> brokeredMessages      = new List <BrokeredMessage>(sourceCommands.Count);
                foreach (TCommand command in sourceCommands)
                {
                    if (!AzureBusHelper.PrepareAndValidateCommand(command, "Azure-ServiceBus"))
                    {
                        continue;
                    }

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

                    brokeredMessages.Add(brokeredMessage);
                    sourceCommandMessages.Add(string.Format("A command was sent of type {0}.", command.GetType().FullName));
                }

                try
                {
                    PrivateServiceBusPublisher.SendBatch(brokeredMessages);
                }
                catch (QuotaExceededException exception)
                {
                    responseCode = "429";
                    Logger.LogError("The size of the command being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Commands", sourceCommands }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish a command.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Commands", sourceCommands }
                    });
                    throw;
                }

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

                wasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/Servicebus/CommandBus", "Command", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            }
        }
Пример #5
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);
            }
        }