Ejemplo n.º 1
0
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <TAuthenticationToken>
        {
            if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-EventHub"))
            {
                return;
            }

            try
            {
                var brokeredMessage = new Microsoft.ServiceBus.Messaging.EventData(Encoding.UTF8.GetBytes(MessageSerialiser.SerialiseEvent(@event)));
                brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

                EventHubPublisher.Send(brokeredMessage);
            }
            catch (QuotaExceededException exception)
            {
                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)
            {
                Logger.LogError("An issue occurred while trying to publish an event.", exception: exception, metaData: new Dictionary <string, object> {
                    { "Event", @event }
                });
                throw;
            }
            Logger.LogInfo(string.Format("An event was published with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
        }
Ejemplo n.º 2
0
        public virtual void Publish <TEvent>(TEvent @event)
            where TEvent : IEvent <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/EventHub" }
            };
            string telemetryName    = string.Format("{0}/{1}", @event.GetType().FullName, @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-EventHub"))
                {
                    return;
                }

                try
                {
                    var brokeredMessage = new Microsoft.ServiceBus.Messaging.EventData(Encoding.UTF8.GetBytes(MessageSerialiser.SerialiseEvent(@event)));
                    brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

                    EventHubPublisher.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/EventHub/EventBus", "Event", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            }
            Logger.LogInfo(string.Format("An event was published with the id '{0}' was of type {1}.", @event.Id, @event.GetType().FullName));
        }
Ejemplo n.º 3
0
        public virtual void Publish <TEvent>(IEnumerable <TEvent> events)
            where TEvent : IEvent <TAuthenticationToken>
        {
            IList <TEvent> sourceEvents        = events.ToList();
            IList <string> sourceEventMessages = new List <string>();
            IList <Microsoft.ServiceBus.Messaging.EventData> brokeredMessages = new List <Microsoft.ServiceBus.Messaging.EventData>(sourceEvents.Count);

            foreach (TEvent @event in sourceEvents)
            {
                if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-EventHub"))
                {
                    continue;
                }

                var brokeredMessage = new Microsoft.ServiceBus.Messaging.EventData(Encoding.UTF8.GetBytes(MessageSerialiser.SerialiseEvent(@event)));
                brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

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

            try
            {
                EventHubPublisher.SendBatch(brokeredMessages);
            }
            catch (QuotaExceededException exception)
            {
                Logger.LogError("The size of the event being sent was too large.", exception: exception, metaData: new Dictionary <string, object> {
                    { "Events", sourceEvents }
                });
                throw;
            }
            catch (Exception exception)
            {
                Logger.LogError("An issue occurred while trying to publish a event.", exception: exception, metaData: new Dictionary <string, object> {
                    { "Events", sourceEvents }
                });
                throw;
            }

            foreach (string message in sourceEventMessages)
            {
                Logger.LogInfo(message);
            }
        }
Ejemplo n.º 4
0
        private async Task SendEventsAsync(IEnumerable <EventData> events, long transmissionSequenceNumber, CancellationToken cancellationToken)
        {
            if (events == null)
            {
                return;
            }

            try
            {
                List <MessagingEventData> batch = new List <MessagingEventData>();

                foreach (EventData eventData in events)
                {
                    MessagingEventData messagingEventData = eventData.ToMessagingEventData();
                    batch.Add(messagingEventData);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                MessagingFactory factory = this.connectionData.MessagingFactories[transmissionSequenceNumber % ConcurrentConnections];
                EventHubClient   hubClient;
                lock (factory)
                {
                    hubClient = factory.CreateEventHubClient(this.connectionData.EventHubName);
                }

                await hubClient.SendBatchAsync(batch);

                this.ReportListenerHealthy();
            }
            catch (Exception e)
            {
                this.ReportListenerProblem("Diagnostics data upload has failed." + Environment.NewLine + e.ToString());
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the event bus.
        /// </summary>
        protected virtual void ReceiveEvent(PartitionContext context, EventData eventData)
        {
            DateTimeOffset startedAt     = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch = Stopwatch.StartNew();
            string         responseCode  = "200";
            // Null means it was skipped
            bool?              wasSuccessfull            = true;
            string             telemetryName             = string.Format("Cqrs/Handle/Event/{0}", eventData.SequenceNumber);
            ISingleSignOnToken authenticationToken       = null;
            Guid?              guidAuthenticationToken   = null;
            string             stringAuthenticationToken = null;
            int?intAuthenticationToken = null;

            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/EventHub" }
            };
            object value;

            if (eventData.Properties.TryGetValue("Type", out value))
            {
                telemetryProperties.Add("MessageType", value.ToString());
            }
            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                       string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset),
                                                                                       ExtractSignature(eventData),
                                                                                       SigningTokenConfigurationKey,
                                                                                       () =>
                    {
                        wasSuccessfull = null;
                        telemetryName  = string.Format("Cqrs/Handle/Event/Skipped/{0}", eventData.SequenceNumber);
                        responseCode   = "204";
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                        Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to event settings.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                        TelemetryHelper.TrackEvent("Cqrs/Handle/Event/Skipped", telemetryProperties);
                    }
                                                                                       );

                    if (wasSuccessfull != null)
                    {
                        if (@event != null)
                        {
                            telemetryName       = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
                            authenticationToken = @event.AuthenticationToken as ISingleSignOnToken;
                            if (AuthenticationTokenIsGuid)
                            {
                                guidAuthenticationToken = @event.AuthenticationToken as Guid?;
                            }
                            if (AuthenticationTokenIsString)
                            {
                                stringAuthenticationToken = @event.AuthenticationToken as string;
                            }
                            if (AuthenticationTokenIsInt)
                            {
                                intAuthenticationToken = @event.AuthenticationToken as int?;
                            }

                            var telemeteredMessage = @event as ITelemeteredMessage;
                            if (telemeteredMessage != null)
                            {
                                telemetryName = telemeteredMessage.TelemetryName;
                            }

                            telemetryName = string.Format("Cqrs/Handle/Event/{0}", telemetryName);
                        }
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                    }
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }

                    wasSuccessfull = true;
                    responseCode   = "200";
                    return;
                }
                catch (UnAuthorisedMessageReceivedException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but was not authorised.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
                    wasSuccessfull = false;
                    responseCode   = "401";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (NoHandlersRegisteredException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but no handlers were found to process it.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
                    wasSuccessfull = false;
                    responseCode   = "501";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (NoHandlerRegisteredException exception)
                {
                    TelemetryHelper.TrackException(exception, null, telemetryProperties);
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'s but no handler was found to process it.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
                    wasSuccessfull = false;
                    responseCode   = "501";
                    telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                    telemetryProperties.Add("ExceptionMessage", exception.Message);
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;

                    case 9:
                        telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                        telemetryProperties.Add("ExceptionMessage", exception.Message);
                        break;
                    }
                    wasSuccessfull = false;
                    responseCode   = "500";
                }
                finally
                {
                    // Eventually just accept it
                    context.CheckpointAsync(eventData);

                    TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles--, telemetryProperties);

                    mainStopWatch.Stop();
                    if (guidAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            guidAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else if (intAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            intAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else if (stringAuthenticationToken != null)
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            stringAuthenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }
                    else
                    {
                        TelemetryHelper.TrackRequest
                        (
                            telemetryName,
                            authenticationToken,
                            startedAt,
                            mainStopWatch.Elapsed,
                            responseCode,
                            wasSuccessfull == null || wasSuccessfull.Value,
                            telemetryProperties
                        );
                    }

                    TelemetryHelper.Flush();
                }
            }
        }
        /// <summary>
        /// Receives a <see cref="EventData"/> from the command bus, identifies a key and queues it accordingly.
        /// </summary>
        protected override void ReceiveCommand(PartitionContext context, EventData eventData)
        {
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
#if NET452
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
#if NET452
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());
#endif
#if NETSTANDARD2_0
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
#endif
                    ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                    CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
#if NET452
                    Logger.LogInfo(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, command.GetType().FullName));
#endif
#if NETSTANDARD2_0
                    Logger.LogInfo(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset, command.GetType().FullName));
#endif

                    Type commandType = command.GetType();

                    string targetQueueName = commandType.FullName;

                    try
                    {
                        object rsn = commandType.GetProperty("Rsn").GetValue(command, null);
                        targetQueueName = string.Format("{0}.{1}", targetQueueName, rsn);
                    }
                    catch
                    {
#if NET452
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3} but with no Rsn property.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, commandType));
#endif
#if NETSTANDARD2_0
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3} but with no Rsn property.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset, commandType));
#endif
                        // Do nothing if there is no rsn. Just use command type name
                    }

                    CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                    EnqueueCommand(targetQueueName, command);

                    // remove the original message from the incoming queue
                    context.CheckpointAsync(eventData);

#if NET452
                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                    case 9:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;
                    }
                }
            }
            // Eventually just accept it
            context.CheckpointAsync(eventData);
        }
Ejemplo n.º 7
0
        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   = "200";
            bool           wasSuccessfull = false;

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

            foreach (TEvent @event in sourceEvents)
            {
                string subTelemetryName = string.Format("{0}/{1}", @event.GetType().FullName, @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 <Microsoft.ServiceBus.Messaging.EventData> brokeredMessages = new List <Microsoft.ServiceBus.Messaging.EventData>(sourceEvents.Count);
                foreach (TEvent @event in sourceEvents)
                {
                    if (!AzureBusHelper.PrepareAndValidateEvent(@event, "Azure-EventHub"))
                    {
                        continue;
                    }

                    var brokeredMessage = new Microsoft.ServiceBus.Messaging.EventData(Encoding.UTF8.GetBytes(MessageSerialiser.SerialiseEvent(@event)));
                    brokeredMessage.Properties.Add("Type", @event.GetType().FullName);

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

                try
                {
                    EventHubPublisher.SendBatch(brokeredMessages);
                    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", sourceEvents }
                    });
                    throw;
                }
                catch (Exception exception)
                {
                    responseCode = "500";
                    Logger.LogError("An issue occurred while trying to publish a event.", exception: exception, metaData: new Dictionary <string, object> {
                        { "Events", sourceEvents }
                    });
                    throw;
                }

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

                wasSuccessfull = true;
            }
            finally
            {
                mainStopWatch.Stop();
                TelemetryHelper.TrackDependency("Azure/EventHub/EventBus", "Event", telemetryName, null, startedAt, mainStopWatch.Elapsed, responseCode, wasSuccessfull, telemetryProperties);
            }
        }
Ejemplo n.º 8
0
        public async Task SendEventsAsync(IReadOnlyCollection <EventData> events, long transmissionSequenceNumber, CancellationToken cancellationToken)
        {
            // Get a reference to the current connections array first, just in case there is another thread wanting to clean
            // up the connections with CleanUpAsync(), we won't get a null reference exception here.
            EventHubConnection[] currentConnections = Interlocked.CompareExchange <EventHubConnection[]>(ref this.connections, this.connections, this.connections);

            if (currentConnections == null || events == null || events.Count == 0)
            {
                return;
            }

            try
            {
                // Since event hub limits each message/batch to be a certain size, we need to
                // keep checking the size for exceeds and split into a new batch as needed

                List <List <MessagingEventData> > batches = new List <List <MessagingEventData> >();
                int batchByteSize = 0;

                foreach (EventData eventData in events)
                {
                    int messageSize;
                    MessagingEventData messagingEventData = eventData.ToMessagingEventData(out messageSize);

                    // If we don't have a batch yet, or the addition of this message will exceed the limit for this batch, then
                    // start a new batch.
                    if (batches.Count == 0 ||
                        batchByteSize + messageSize > EventHubMessageSizeLimit)
                    {
                        batches.Add(new List <MessagingEventData>());
                        batchByteSize = 0;
                    }

                    batchByteSize += messageSize;

                    List <MessagingEventData> currentBatch = batches[batches.Count - 1];
                    currentBatch.Add(messagingEventData);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                EventHubClient hubClient = currentConnections[transmissionSequenceNumber % ConcurrentConnections].HubClient;

                List <Task> tasks = new List <Task>();
                foreach (List <MessagingEventData> batch in batches)
                {
                    tasks.Add(hubClient.SendBatchAsync(batch));
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                this.healthReporter.ReportHealthy();
            }
            catch (Exception e)
            {
                string errorMessage = nameof(EventHubOutput) + ": diagnostics data upload has failed." + Environment.NewLine + e.ToString();
                this.healthReporter.ReportProblem(errorMessage);
            }
        }
Ejemplo n.º 9
0
        protected virtual void ReceiveEvent(PartitionContext context, EventData eventData)
        {
            IDictionary <string, string> telemetryProperties = new Dictionary <string, string> {
                { "Type", "Azure/EventHub" }
            };

            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                       string.Format("partition key '{0}', sequence number '{1}' and offset '{2}'", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset),
                                                                                       () =>
                    {
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                        Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but processing was skipped due to event settings.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    }
                                                                                       );

                    // Remove message from queue
                    context.CheckpointAsync(eventData);
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }

                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                    case 9:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;
                    }
                }
            }
            // Eventually just accept it
            context.CheckpointAsync(eventData);
            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles--, telemetryProperties);
        }