private IDomainEvent?CreateEvent(DomainEventMessage message) { var types = this.GetType().Assembly.GetTypes(); var type = types.FirstOrDefault(x => x.Name == message.EventType); if (type == null) { return(null); } try { var domainEvent = Activator.CreateInstance(type); var properties = type.GetProperties().Where(x => x.CanRead && x.CanWrite).ToDictionary(x => x.Name, x => x); foreach (var p in properties) { if (message.Data.ContainsKey(p.Key)) { p.Value.SetValue(domainEvent, Convert.ChangeType(message.Data[p.Key], p.Value.PropertyType)); } } return((IDomainEvent)domainEvent !); } catch (Exception e) { _logger.LogError(e.Message); return(null); } }
public async Task <HandlerResult> HandleAsync(DomainEventMessage <TestEvent> @event) { var properties = new Dictionary <string, object> { ["CorrelationId"] = @event.CorrelationId, ["MessageId"] = @event.MessageId, ["MessageType"] = @event.MessageTypeName }; using (logger.BeginScope(properties)) { TestEvent.Instances.Add(@event.MessageId, @event.Data); if (@event.Data.IntValue == int.MinValue) { var x = 0; _ = 1 / x; } if (@event.Data.IntValue > 0) { return(await Task.FromResult(HandlerResult.Success).ConfigureAwait(false)); } else if (@event.Data.IntValue == 0) { return(await Task.FromResult(HandlerResult.Retry).ConfigureAwait(false)); } else { return(await Task.FromResult(HandlerResult.Failed).ConfigureAwait(false)); } } }
public async Task <HandlerResult> HandleAsync(DomainEventMessage <WidgetStageChangedEvent> @event) { using (LogContext.PushProperty("MessageId", @event.MessageId)) using (LogContext.PushProperty("CorrelationId", @event.CorrelationId)) using (LogContext.PushProperty("WidgetId", @event.Data.WidgetId)) { logger.LogDebug($"Handling {typeof(WidgetStageChangedEvent).Name} for WebApiStarter {@event.Data.WidgetId}"); using (IServiceScope scope = serviceProvider.CreateScope()) { var service = scope.ServiceProvider.GetRequiredService <IWidgetService>(); var lockProvider = scope.ServiceProvider.GetRequiredService <IDistributedLockProvider>(); var lockName = $"WidgetId:{@event.Data.WidgetId}"; logger.LogDebug($"Acquiring lock for {lockName}"); await using (await lockProvider.AcquireLockAsync(lockName).ConfigureAwait(false)) { logger.LogDebug($"Acquired lock for {lockName}"); var entity = await service.GetWidget(@event.Data.WidgetId).ConfigureAwait(false); // simulate more work with sleep Thread.Sleep(TimeSpan.FromSeconds(5)); logger.LogInformation($"widget was observed changing it's state with body: {JsonConvert.SerializeObject(@event.Data)} and entity: {JsonConvert.SerializeObject(entity)}"); } } logger.LogDebug($"Successfully handled {typeof(WidgetStageChangedEvent).Name} for WebApiStarter {@event.Data.WidgetId}"); return(HandlerResult.Success); } }
private async Task HandleMessage <TMessage>(DomainEventMessage <TMessage> message, CancellationToken ct) { using (var repository = _repositoryFactory()) { var correlationId = message.CorrelationId; if (false == correlationId.HasValue) { return; } var processId = _buildId(correlationId.Value); var process = await repository.GetById <TProcess>(processId, _bucketId); process.ApplyEvent(message.DomainEvent); var undispatched = process.GetUndispatchedCommands() .Select(_dispatcher.Dispatch); await Task.WhenAll(undispatched); var commitId = _buildCommitId(message.Commit.CommitId, processId); await repository.Save(process, commitId, bucketId : _bucketId); } }
/// <summary> /// Handle message event /// </summary> /// <param name="event"></param> /// <returns></returns> public async Task Handle(DomainEventMessage <SqlReportApiCreationEvent> @event) { using (LogContext.PushProperty("MessageId", @event.MessageId)) using (LogContext.PushProperty("CorrelationId", @event.CorrelationId)) { await Handle(@event.Data); } }
public void ShouldBeAbleToAssignData() { // act var @event = new DomainEventMessage() { Data = new TestEvent() }; // assert Assert.IsType <TestEvent>(@event.Data); }
public async Task <HandlerResult> HandleAsync(DomainEventMessage <TestEvent> @event) { var properties = new Dictionary <string, object> { ["CorrelationId"] = @event.CorrelationId, ["MessageId"] = @event.MessageId, ["MessageType"] = @event.MessageTypeName }; var correlationId = CorrelationContext.GetCorrelationId(); if (@event.Data.IntValue == Int32.MaxValue && correlationId != @event.CorrelationId) { throw new ArgumentException($"CorrelationId {@event.CorrelationId} should equal {correlationId}"); } using (logger.BeginScope(properties)) { TestEvent.Instances.Add(@event.MessageId, @event.Data); if (@event.Data.IntValue == int.MinValue) { var x = 0; _ = 1 / x; } if (@event.Data.IntValue > 0) { return(await Task.FromResult(HandlerResult.Success).ConfigureAwait(false)); } else if (@event.Data.IntValue == 0) { return(await Task.FromResult(HandlerResult.Retry).ConfigureAwait(false)); } else { return(await Task.FromResult(HandlerResult.Failed).ConfigureAwait(false)); } } }
public Task Handle(DomainEventMessage <TestEvent> @event) { TestEvent.Instance = @event.Data; TestEvent.CorrelationId = @event.CorrelationId; return(Task.FromResult(0)); }
private async Task OnMessageCallbackAsync(Message message) { var messageTypeName = message.ApplicationProperties[Constants.MESSAGE_TYPE_KEY] as string; var properties = new Dictionary <string, object> { ["CorrelationId"] = message.Properties.CorrelationId, ["MessageId"] = message.Properties.MessageId, ["MessageType"] = messageTypeName }; // if message has correlationId, set it so that handling can be found by initial correlation if (!string.IsNullOrWhiteSpace(message.Properties.CorrelationId)) { CorrelationContext.SetCorrelationId(message.Properties.CorrelationId); } using (logger.BeginScope(properties)) { logger.LogInformation($"Received message {message.Properties.MessageId}"); try { string body = DomainEventMessage.GetBody(message); logger.LogTrace("Received message {MessageId} with body: {MessageBody}", message.Properties.MessageId, body); logger.LogDebug($"Event type key: {messageTypeName}"); if (!eventTypeLookup.ContainsKey(messageTypeName)) { logger.LogError($"Message {message.Properties.MessageId} rejected because message type was not registered for type {messageTypeName}"); receiver.Reject(message); return; } var dataType = eventTypeLookup[messageTypeName]; logger.LogDebug($"Event type: {dataType}"); var handlerType = typeof(IDomainEventHandler <>).MakeGenericType(dataType); logger.LogDebug($"Event type handler interface: {handlerType}"); var handler = provider.GetService(handlerType); if (handler == null) { logger.LogError($"Message {message.Properties.MessageId} rejected because handler was not found for type {messageTypeName}"); receiver.Reject(message); return; } logger.LogDebug($"Event type handler: {handler.GetType()}"); dynamic domainEvent; try { domainEvent = DomainEventMessage.CreateGenericInstance(dataType, message); logger.LogDebug($"Successfully deserialized body to {dataType}"); } catch (Exception ex) { logger.LogError(ex, ex.Message); receiver.Reject(message); return; } HandlerResult result; dynamic dhandler = handler; try { result = await dhandler.HandleAsync(domainEvent).ConfigureAwait(false); } catch (Exception ex) { logger.LogError(ex, $"Message {message.Properties.MessageId} caught unhandled exception {ex.Message}"); result = HandlerResult.Failed; } logger.LogInformation($"Handler executed for message {message.Properties.MessageId} and returned result of {result}"); switch (result) { case HandlerResult.Success: receiver.Accept(message); logger.LogInformation($"Message {message.Properties.MessageId} accepted"); break; case HandlerResult.Retry: var deliveryCount = message.Header.DeliveryCount; var delay = 10 * deliveryCount; var scheduleTime = DateTime.UtcNow.AddSeconds(delay); // create a new message to be queued with scheduled delivery time var retry = new Message(body) { Header = message.Header, Footer = message.Footer, Properties = message.Properties, ApplicationProperties = message.ApplicationProperties }; retry.ApplicationProperties[Constants.SCHEDULED_ENQUEUE_TIME_UTC] = scheduleTime; receiver.Enqueue(retry); receiver.Accept(message); logger.LogInformation($"Message {message.Properties.MessageId} requeued with delay of {delay} seconds for {scheduleTime}"); break; case HandlerResult.Failed: receiver.Reject(message); break; case HandlerResult.Release: receiver.Release(message); break; default: throw new NotImplementedException($"Unknown HandlerResult value of {result}"); } } catch (Exception ex) { logger.LogError(ex, $"Message {message.Properties.MessageId} rejected because of unhandled exception {ex.Message}"); receiver.Reject(message); } } }