Exemplo n.º 1
0
        public void Create_NonExistingUser_NewInventoryItemSummaryEntityCreated()
        {
            // Arrange
            var domainDataStoreFactory = NinjectDependencyResolver.Current.Resolve <IDomainDataStoreFactory>();

            domainDataStoreFactory.GetInventoryItemSummaryDataStore().RemoveAll();
            var authenticationTokenHelper = NinjectDependencyResolver.Current.Resolve <IAuthenticationTokenHelper <ISingleSignOnToken> >();
            ISingleSignOnToken token      = authenticationTokenHelper.GetAuthenticationToken();
            var service = NinjectDependencyResolver.Current.Resolve <IInventoryItemService>();

            var parameters = new ServiceRequestWithData <ISingleSignOnToken, InventoryItemServiceCreateParameters>
            {
                AuthenticationToken = token,
                Data = new InventoryItemServiceCreateParameters {
                    name = "New Inventory Item"
                }
            };

            // Act
            DateTime start = DateTime.Now;

            service.Create(parameters);
            DateTime end = DateTime.Now;

            // Assert
            IDataStore <InventoryItemSummaryEntity>  dataStore = domainDataStoreFactory.GetInventoryItemSummaryDataStore();
            IEnumerable <InventoryItemSummaryEntity> query     = dataStore.Where(inventoryItem => !inventoryItem.IsLogicallyDeleted && inventoryItem.Name == parameters.Data.name)
                                                                 .AsEnumerable();
            InventoryItemSummaryEntity result = query.Single();

            Assert.AreEqual(parameters.Data.name, result.Name);
            Console.WriteLine("Operation took: {0}", end - start);
        }
Exemplo n.º 2
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();
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the command bus.
        /// </summary>
        protected virtual void ReceiveCommand(BrokeredMessage message)
        {
            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/Command/{0}", message.MessageId);
            ISingleSignOnToken authenticationToken       = null;
            Guid?              guidAuthenticationToken   = null;
            string             stringAuthenticationToken = null;
            int?intAuthenticationToken = null;

            IDictionary <string, string> telemetryProperties = ExtractTelemetryProperties(message, "Azure/Servicebus");

            TelemetryHelper.TrackMetric("Cqrs/Handle/Command", CurrentHandles++, telemetryProperties);
            var brokeredMessageRenewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                Logger.LogDebug(string.Format("A command message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();


                ICommand <TAuthenticationToken> command = AzureBusHelper.ReceiveCommand(messageBody, ReceiveCommand,
                                                                                        string.Format("id '{0}'", message.MessageId),
                                                                                        ExtractSignature(message),
                                                                                        SigningTokenConfigurationKey,
                                                                                        () =>
                {
                    wasSuccessfull = null;
                    telemetryName  = string.Format("Cqrs/Handle/Command/Skipped/{0}", message.MessageId);
                    responseCode   = "204";
                    // Remove message from queue
                    try
                    {
                        message.Complete();
                    }
                    catch (MessageLockLostException exception)
                    {
                        throw new MessageLockLostException(string.Format("The lock supplied for the skipped command message '{0}' is invalid.", message.MessageId), exception);
                    }
                    Logger.LogDebug(string.Format("A command message arrived with the id '{0}' but processing was skipped due to event settings.", message.MessageId));
                    TelemetryHelper.TrackEvent("Cqrs/Handle/Command/Skipped", telemetryProperties);
                },
                                                                                        () =>
                {
                    AzureBusHelper.RefreshLock(brokeredMessageRenewCancellationTokenSource, message, "command");
                }
                                                                                        );

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

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

                        telemetryName = string.Format("Cqrs/Handle/Command/{0}", telemetryName);
                    }
                    // Remove message from queue
                    try
                    {
                        message.Complete();
                    }
                    catch (MessageLockLostException exception)
                    {
                        throw new MessageLockLostException(string.Format("The lock supplied for command '{0}' of type {1} is invalid.", command.Id, command.GetType().Name), exception);
                    }
                }
                Logger.LogDebug(string.Format("A command message arrived and was processed with the id '{0}'.", message.MessageId));
            }
            catch (MessageLockLostException exception)
            {
                IDictionary <string, string> subTelemetryProperties = new Dictionary <string, string>(telemetryProperties);
                subTelemetryProperties.Add("TimeTaken", mainStopWatch.Elapsed.ToString());
                TelemetryHelper.TrackException(exception, null, subTelemetryProperties);
                if (ThrowExceptionOnReceiverMessageLockLostExceptionDuringComplete)
                {
                    Logger.LogError(exception.Message, exception: exception);
                    // Indicates a problem, unlock message in queue
                    message.Abandon();
                    wasSuccessfull = false;
                }
                else
                {
                    Logger.LogWarning(exception.Message, exception: exception);
                    try
                    {
                        message.DeadLetter("LockLostButHandled", "The message was handled but the lock was lost.");
                    }
                    catch (Exception)
                    {
                        // Oh well, move on.
                        message.Abandon();
                    }
                }
                responseCode = "599";
            }
            catch (UnAuthorisedMessageReceivedException exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("A command message arrived with the id '{0}' but was not authorised.", message.MessageId), exception: exception);
                message.DeadLetter("UnAuthorisedMessageReceivedException", exception.Message);
                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("A command message arrived with the id '{0}' but no handlers were found to process it.", message.MessageId), exception: exception);
                message.DeadLetter("NoHandlersRegisteredException", exception.Message);
                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("A command message arrived with the id '{0}' but no handler was found to process it.", message.MessageId), exception: exception);
                message.DeadLetter("NoHandlerRegisteredException", exception.Message);
                wasSuccessfull = false;
                responseCode   = "501";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            catch (Exception exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("A command message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
                message.Abandon();
                wasSuccessfull = false;
                responseCode   = "500";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            finally
            {
                // Cancel the lock of renewing the task
                brokeredMessageRenewCancellationTokenSource.Cancel();
                TelemetryHelper.TrackMetric("Cqrs/Handle/Command", 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();
            }
        }
Exemplo n.º 4
0
        protected virtual void ReceiveEvent(IMessageReceiver client, BrokeredMessage message)
#endif
        {
            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}", message.MessageId);
            ISingleSignOnToken authenticationToken       = null;
            Guid?              guidAuthenticationToken   = null;
            string             stringAuthenticationToken = null;
            int?intAuthenticationToken = null;

            IDictionary <string, string> telemetryProperties = ExtractTelemetryProperties(message, "Azure/Servicebus");

            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            var brokeredMessageRenewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                    string messageBody = message.GetBodyAsString();

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                       string.Format("id '{0}'", message.MessageId),
                                                                                       ExtractSignature(message),
                                                                                       SigningTokenConfigurationKey,
                                                                                       () =>
                    {
                        wasSuccessfull = null;
                        telemetryName  = string.Format("Cqrs/Handle/Event/Skipped/{0}", message.MessageId);
                        responseCode   = "204";
                        // Remove message from queue
                        try
                        {
#if NET452
                            message.Complete();
#endif
#if NETSTANDARD2_0
                            client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                        }
                        catch (AggregateException aggregateException)
                        {
                            if (aggregateException.InnerException is MessageLockLostException)
                            {
                                throw new MessageLockLostException(string.Format("The lock supplied for the skipped event message '{0}' is invalid.", message.MessageId), aggregateException.InnerException);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (MessageLockLostException exception)
                        {
                            throw new MessageLockLostException(string.Format("The lock supplied for the skipped event message '{0}' is invalid.", message.MessageId), exception);
                        }
                        Logger.LogDebug(string.Format("An event message arrived with the id '{0}' but processing was skipped due to event settings.", message.MessageId));
                        TelemetryHelper.TrackEvent("Cqrs/Handle/Event/Skipped", telemetryProperties);
                    },
                                                                                       () =>
                    {
#if NET452
                        AzureBusHelper.RefreshLock(brokeredMessageRenewCancellationTokenSource, message, "event");
#endif
#if NETSTANDARD2_0
                        AzureBusHelper.RefreshLock(client, brokeredMessageRenewCancellationTokenSource, message, "event");
#endif
                    }
                                                                                       );

                    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
                        try
                        {
#if NET452
                            message.Complete();
#endif
#if NETSTANDARD2_0
                            client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                        }
                        catch (AggregateException aggregateException)
                        {
                            if (aggregateException.InnerException is MessageLockLostException)
                            {
                                throw new MessageLockLostException(string.Format("The lock supplied for event '{0}' of type {1} is invalid.", @event.Id, @event.GetType().Name), aggregateException.InnerException);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (MessageLockLostException exception)
                        {
                            throw new MessageLockLostException(string.Format("The lock supplied for event '{0}' of type {1} is invalid.", @event.Id, @event.GetType().Name), exception);
                        }
                    }
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the id '{0}'.", message.MessageId));

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }
                }
                catch (AggregateException aggregateException)
                {
                    throw aggregateException.InnerException;
                }
            }
            catch (MessageLockLostException exception)
            {
                IDictionary <string, string> subTelemetryProperties = new Dictionary <string, string>(telemetryProperties);
                subTelemetryProperties.Add("TimeTaken", mainStopWatch.Elapsed.ToString());
                TelemetryHelper.TrackException(exception, null, subTelemetryProperties);
                if (ThrowExceptionOnReceiverMessageLockLostExceptionDuringComplete)
                {
                    Logger.LogError(exception.Message, exception: exception);
                    // Indicates a problem, unlock message in queue
#if NET452
                    message.Abandon();
#endif
#if NETSTANDARD2_0
                    client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                    wasSuccessfull = false;
                }
                else
                {
                    Logger.LogWarning(exception.Message, exception: exception);
                    try
                    {
#if NET452
                        message.DeadLetter("LockLostButHandled", "The message was handled but the lock was lost.");
#endif
#if NETSTANDARD2_0
                        client.DeadLetterAsync(message.SystemProperties.LockToken, "LockLostButHandled", "The message was handled but the lock was lost.").Wait(1500);
#endif
                    }
                    catch (Exception)
                    {
                        // Oh well, move on.
#if NET452
                        message.Abandon();
#endif
#if NETSTANDARD2_0
                        client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                    }
                }
                responseCode = "599";
            }
            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 id '{0}' but was not authorised.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("UnAuthorisedMessageReceivedException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "UnAuthorisedMessageReceivedException", exception.Message).Wait(1500);
#endif
                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 id '{0}' but no handlers were found to process it.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("NoHandlersRegisteredException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "NoHandlersRegisteredException", exception.Message).Wait(1500);
#endif
                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 id '{0}' but no handler was found to process it.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("NoHandlerRegisteredException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "NoHandlerRegisteredException", exception.Message).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "501";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            catch (Exception exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
#if NET452
                message.Abandon();
#endif
#if NETSTANDARD2_0
                client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "500";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            finally
            {
                // Cancel the lock of renewing the task
                brokeredMessageRenewCancellationTokenSource.Cancel();
                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();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Receives <see cref="EventData"/> from the command bus.
        /// </summary>
        protected virtual void ReceiveCommand(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/Command/{0}", eventData.SequenceNumber);
            ISingleSignOnToken authenticationToken = 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/Command", CurrentHandles++, telemetryProperties);
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    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));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());

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

                    if (wasSuccessfull != null)
                    {
                        if (command != null)
                        {
                            telemetryName       = string.Format("{0}/{1}", command.GetType().FullName, command.Id);
                            authenticationToken = command.AuthenticationToken as ISingleSignOnToken;

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

                            telemetryName = string.Format("Cqrs/Handle/Command/{0}", telemetryName);
                        }
                        // Remove message from queue
                        context.CheckpointAsync(eventData);
                    }
                    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));

                    wasSuccessfull = true;
                    responseCode   = "200";
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    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);

                    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/Command", CurrentHandles--, telemetryProperties);

                    mainStopWatch.Stop();
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        authenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );

                    TelemetryHelper.Flush();
                }
            }
        }
 ISingleSignOnToken IDefaultSingleSignOnTokenFactory.RenewTokenExpiry(ISingleSignOnToken token, int timeoutInMinutes = 360)
 {
     return(RenewTokenExpiry(token, timeoutInMinutes));
 }
Exemplo n.º 7
0
        protected virtual void ReceiveEvent(BrokeredMessage message)
        {
            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}", message.MessageId);
            ISingleSignOnToken authenticationToken = null;

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

            if (message.Properties.TryGetValue("Type", out value))
            {
                telemetryProperties.Add("MessageType", value.ToString());
            }
            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            var brokeredMessageRenewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();

                IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                   string.Format("id '{0}'", message.MessageId),
                                                                                   () =>
                {
                    wasSuccessfull = null;
                    telemetryName  = string.Format("Cqrs/Handle/Event/Skipped/{0}", message.MessageId);
                    responseCode   = "204";
                    // Remove message from queue
                    try
                    {
                        message.Complete();
                    }
                    catch (MessageLockLostException exception)
                    {
                        throw new MessageLockLostException(string.Format("The lock supplied for the skipped event message '{0}' is invalid.", message.MessageId), exception);
                    }
                    Logger.LogDebug(string.Format("An event message arrived with the id '{0}' but processing was skipped due to event settings.", message.MessageId));
                    TelemetryHelper.TrackEvent("Cqrs/Handle/Event/Skipped", telemetryProperties);
                },
                                                                                   () =>
                {
                    AzureBusHelper.RefreshLock(brokeredMessageRenewCancellationTokenSource, message, "event");
                }
                                                                                   );

                if (wasSuccessfull != null)
                {
                    if (@event != null)
                    {
                        telemetryName       = string.Format("{0}/{1}", @event.GetType().FullName, @event.Id);
                        authenticationToken = @event.AuthenticationToken as ISingleSignOnToken;

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

                        telemetryName = string.Format("Cqrs/Handle/Event/{0}", telemetryName);
                    }
                    // Remove message from queue
                    try
                    {
                        message.Complete();
                    }
                    catch (MessageLockLostException exception)
                    {
                        throw new MessageLockLostException(string.Format("The lock supplied for event '{0}' of type {1} is invalid.", @event.Id, @event.GetType().Name), exception);
                    }
                }
                Logger.LogDebug(string.Format("An event message arrived and was processed with the id '{0}'.", message.MessageId));

                IList <IEvent <TAuthenticationToken> > events;
                if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                {
                    events.Add(@event);
                }
            }
            catch (Exception exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
                message.Abandon();
                wasSuccessfull = false;
                responseCode   = "500";
            }
            finally
            {
                // Cancel the lock of renewing the task
                brokeredMessageRenewCancellationTokenSource.Cancel();
                TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles--, telemetryProperties);

                mainStopWatch.Stop();
                TelemetryHelper.TrackRequest
                (
                    telemetryName,
                    authenticationToken,
                    startedAt,
                    mainStopWatch.Elapsed,
                    responseCode,
                    wasSuccessfull == null || wasSuccessfull.Value,
                    telemetryProperties
                );

                TelemetryHelper.Flush();
            }
        }
        /// <summary>
        /// Renew the value of <see cref="ISingleSignOnToken.TimeOfExpiry"/>.
        /// </summary>
        /// <param name="token">The <see cref="ISingleSignOnToken"/> to renew.</param>
        /// <param name="timeoutInMinutes">The amount of time in minutes to set the <see cref="ISingleSignOnToken.TimeOfExpiry"/> to. This is from <see cref="DateTime.UtcNow"/>.</param>
#pragma warning disable 1066 // I like the explicit nature of informing what the default value should be of any implementation if not provided.
        ISingleSignOnToken IDefaultSingleSignOnTokenFactory.RenewTokenExpiry(ISingleSignOnToken token, int timeoutInMinutes = 360)
#pragma warning restore 1066
        {
            return(RenewTokenExpiry(token, timeoutInMinutes));
        }
Exemplo n.º 9
0
        public ISingleSignOnToken RenewTokenExpiry(ISingleSignOnToken token, int timeoutInMinutes = 360)
        {
            token.TimeOfExpiry = DateTime.UtcNow.AddMinutes(timeoutInMinutes);

            return(token);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Build a message handler that implements telemetry capturing as well as off thread handling.
        /// </summary>
        public virtual Action <TMessage> BuildTelemeteredActionHandler <TMessage, TAuthenticationToken>(ITelemetryHelper telemetryHelper, Action <TMessage> handler, bool holdMessageLock, string source)
            where TMessage : IMessage
        {
            Action <TMessage> registerableMessageHandler = message =>
            {
                DateTimeOffset startedAt      = DateTimeOffset.UtcNow;
                Stopwatch      mainStopWatch  = Stopwatch.StartNew();
                string         responseCode   = "200";
                bool           wasSuccessfull = true;

                string             telemetryName       = message.GetType().FullName;
                var                telemeteredMessage  = message as ITelemeteredMessage;
                string             messagePrefix       = null;
                ISingleSignOnToken authenticationToken = null;
                var                @event = message as IEvent <TAuthenticationToken>;
                if (@event != null)
                {
                    messagePrefix       = "Event/";
                    telemetryName       = string.Format("{0}/{1}", telemetryName, @event.Id);
                    authenticationToken = @event.AuthenticationToken as ISingleSignOnToken;
                }
                else
                {
                    var command = message as ICommand <TAuthenticationToken>;
                    if (command != null)
                    {
                        messagePrefix       = "Command/";
                        telemetryName       = string.Format("{0}/{1}", telemetryName, command.Id);
                        authenticationToken = command.AuthenticationToken as ISingleSignOnToken;
                    }
                }

                if (telemeteredMessage != null)
                {
                    telemetryName = telemeteredMessage.TelemetryName;
                }

                telemetryHelper.TrackEvent(string.Format("Cqrs/Handle/{0}{1}/Started", messagePrefix, telemetryName));

                try
                {
                    handler(message);
                }
                catch (Exception exception)
                {
                    telemetryHelper.TrackException(exception);
                    wasSuccessfull = false;
                    responseCode   = "500";
                    throw;
                }
                finally
                {
                    telemetryHelper.TrackEvent(string.Format("Cqrs/Handle/{0}{1}/Finished", messagePrefix, telemetryName));

                    mainStopWatch.Stop();
                    telemetryHelper.TrackRequest
                    (
                        string.Format("Cqrs/Handle/{0}{1}", messagePrefix, telemetryName),
                        authenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull,
                        new Dictionary <string, string> {
                        { "Type", source }
                    }
                    );

                    telemetryHelper.Flush();
                }
            };

            return(BuildActionHandler(registerableMessageHandler, holdMessageLock));
        }