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); }
/// <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="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(); } }
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(); } }
/// <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)); }
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)); }
public ISingleSignOnToken RenewTokenExpiry(ISingleSignOnToken token, int timeoutInMinutes = 360) { token.TimeOfExpiry = DateTime.UtcNow.AddMinutes(timeoutInMinutes); return(token); }
/// <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)); }