/// <summary>
        /// Fetches any pending events from the current transaction and publishes these through the event bus one by one.
        /// Each event passes through several states, making it easier to track when and if an event fails to be published.
        /// If any failures are detected, publishing that event will NOT be retried (no logic for handling this exists at this point).
        /// </summary>
        /// <param name="transactionId">The transaction id of the DbContextTransaction the given events where created during.</param>
        public async Task PublishEventsThroughEventBusAsync(Guid transactionId)
        {
            var pendingEvents = await _integrationEventLogService.RetrieveEventLogsPendingToPublishAsync(transactionId);

            foreach (var logEvent in pendingEvents)
            {
                try
                {
                    await _integrationEventLogService.MarkEventAsInProgressAsync(logEvent.EventId);

                    _logger.LogDebug("Event {0} status marked as in progress.", logEvent.EventId);

                    await _eventBus.Publish(logEvent.IntegrationEvent, logEvent.EventType);

                    _logger.LogDebug("Published event {0} with content: {1}", logEvent.EventId, logEvent.Content);

                    await _integrationEventLogService.MarkEventAsPublishedAsync(logEvent.EventId);

                    _logger.LogDebug("Event {0} status marked as published.", logEvent.EventId);
                }
                catch (Exception ex)
                {
                    await _integrationEventLogService.MarkEventAsFailedAsync(logEvent.EventId);

                    _logger.LogError(ex, "Event {0} status marked as failed", logEvent.EventId);
                }
            }
        }
        public async Task PublishEventsThroughEventBusAsync(Guid transactionId)
        {
            var pendingLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync(transactionId);

            foreach (var logEvt in pendingLogEvents)
            {
                _logger.LogInformation(
                    "----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", logEvt.Id,
                    logEvt.IntegrationEvent);

                try
                {
                    await _eventLogService.MarkEventAsInProgressAsync(logEvt.Id);

                    _eventBus.Publish(logEvt.IntegrationEvent);
                    await _eventLogService.MarkEventAsPublishedAsync(logEvt.Id);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId}", logEvt.Id);

                    await _eventLogService.MarkEventAsFailedAsync(logEvt.Id);
                }
            }
        }
示例#3
0
    private async Task PublishPendingIntegrationEvents(CancellationToken cancellationToken)
    {
        var pendingLogEvents = await _eventLogService
                               .RetrieveScopedEventsPendingToPublishAsync();

        foreach (var logEvt in pendingLogEvents)
        {
            try
            {
                await _eventLogService.MarkEventAsInProgressAsync(logEvt.EventId);

                _logger.LogInformation("----- Publishing integration event: {IntegrationEventId}", logEvt.EventId);
                await _eventsPublisher.Publish(logEvt.IntegrationEvent, cancellationToken);

                _logger.LogInformation("----- Published integration event: {IntegrationEventId}", logEvt.EventId);

                await _eventLogService.MarkEventAsPublishedAsync(logEvt.EventId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId}", logEvt.EventId);
                await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId);
            }
        }
    }
示例#4
0
        /// <summary>
        /// Publish the events through the event bus async
        /// </summary>
        /// <param name="transactionId"></param>
        /// <returns></returns>
        public async Task PublishEventsThroughEventBusAsync(Guid transactionId)
        {
            // Retrieve all the pending events to be published
            var pendingLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync(transactionId);

            // Loop through each integration event
            foreach (var logEvt in pendingLogEvents)
            {
                // Log publishing the event
                _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", logEvt.EventId, Program.AppName, logEvt.IntegrationEvent);

                try
                {
                    // Mark the event as in progress
                    await _eventLogService.MarkEventAsInProgressAsync(logEvt.EventId);

                    // Publish the event
                    _eventBus.Publish(logEvt.IntegrationEvent);
                    // Mark the event as published
                    await _eventLogService.MarkEventAsPublishedAsync(logEvt.EventId);
                }
                catch (Exception ex)
                {
                    // In case of exception, log the exception
                    _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId} from {AppName}", logEvt.EventId, Program.AppName);
                    // Mark the event as failed
                    await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId);
                }
            }
        }
示例#5
0
        public async Task <ActionResult> UpdateProductAsync([FromBody] CatalogItem productToUpdate)
        {
            var catalogItem = await _catalogContext.CatalogItems.SingleOrDefaultAsync(i => i.Id == productToUpdate.Id);

            if (catalogItem == null)
            {
                return(NotFound(new { Message = $"Item with id {productToUpdate.Id} not found." }));
            }

            var oldPrice = catalogItem.Price;
            var raiseProductPriceChangedEvent = oldPrice != productToUpdate.Price;

            // Update current product
            catalogItem = productToUpdate;
            _catalogContext.CatalogItems.Update(catalogItem);

            if (raiseProductPriceChangedEvent) // Save product's data and publish integration event through the Event Bus if price has changed
            {
                _logger.LogInformation(" [x] CatalogController.UpdateProduct(): Price has changed, integration event is being prepared...");

                var productPriceChangeEvent = new ProductPriceChangedIntegrationEvent(productToUpdate.Id,
                                                                                      oldPrice, productToUpdate.Price);

                var strategy = _catalogContext.Database.CreateExecutionStrategy();
                _logger.LogInformation(" [x] CatalogController.UpdateProductAsync(): Beginning new transaction to save event and commit changes.");
                await strategy.Execute(async() => {
                    using (var transaction = _catalogContext.Database.BeginTransaction())
                    {
                        await _eventLogService.SaveEventAsync(productPriceChangeEvent, transaction);
                        await _catalogContext.SaveChangesAsync();
                        transaction.Commit();
                        _logger.LogInformation(" [x] CatalogController.UpdateProductAsync(): Transaction ({0}) has been committed.", transaction.TransactionId);
                    }
                });

                try
                {
                    await _eventLogService.MarkEventAsInProgressAsync(productPriceChangeEvent.Id);

                    _eventBus.Publish(productPriceChangeEvent);
                    await _eventLogService.MarkEventAsPublishedAsync(productPriceChangeEvent.Id);
                }

                catch (Exception e)
                {
                    _logger.LogError(e, " [x] CatalogController.UpdateProductAsync(): Fail when publishing integration event {0}.", productPriceChangeEvent.Id);
                    await _eventLogService.MarkEventAsFailedAsync(productPriceChangeEvent.Id);
                }
            }
            else // Just save the updated product because the Product's Price hasn't changed.
            {
                await _catalogContext.SaveChangesAsync();
            }

            return(Ok());
        }
        public async Task PublishThroughEventBusAsync(IntegrationEvent evt)
        {
            try {
                _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt);

                await _eventLogService.MarkEventAsInProgressAsync(evt.Id);

                _eventBus.Publish(evt);
                await _eventLogService.MarkEventAsPublishedAsync(evt.Id);
            } catch (Exception ex) {
                _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt);
                await _eventLogService.MarkEventAsFailedAsync(evt.Id);
            }
        }
示例#7
0
        public async Task PublishThroughEventBusAsync(IntegrationEvent evt)
        {
            try
            {
                await _eventLogService.MarkEventAsInProgressAsync(evt.Id);

                _eventBus.Publish(evt);
                await _eventLogService.MarkEventAsPublishedAsync(evt.Id);
            }
            catch (Exception)
            {
                await _eventLogService.MarkEventAsFailedAsync(evt.Id);
            }
        }
        public async Task PublishEventsThroughEventBusAsync()
        {
            var pendingLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync();

            foreach (var logEvt in pendingLogEvents)
            {
                try
                {
                    await _eventLogService.MarkEventAsInProgressAsync(logEvt.EventId);

                    _eventBus.Publish(logEvt.IntegrationEvent);
                    await _eventLogService.MarkEventAsPublishedAsync(logEvt.EventId);
                }
                catch (Exception)
                {
                    await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId);
                }
            }
        }
示例#9
0
        public async Task PublishThroughEventBusAsync(IntegrationEvent @event)
        {
            try
            {
                await _eventLogService.MarkEventAsInProgressAsync(@event.Id);

                await _eventBus.PublishAsync(@event);

                await _eventLogService.MarkEventAsPublishedAsync(@event.Id);

                _logger.Information($"PublishThroughEventBusAsync {@event}");
            }
            catch (Exception ex)
            {
                await _eventLogService.MarkEventAsFailedAsync(@event.Id);

                _logger.Error($"PublishThroughEventBusAsync erorr {@event}");
            }
        }
        public async Task PublishEventsAsync(Guid transactionId)
        {
            var pendingEventLogs = await _integrationEventLogService.GetPendingEventLogEntries(transactionId);

            foreach (var eventLog in pendingEventLogs)
            {
                try
                {
                    await _integrationEventLogService.MarkEventAsInProgressAsync(eventLog.EventId);

                    _eventBus.Publish(eventLog.IntegrationEvent);
                    await _integrationEventLogService.MarkEventAsPublishedAsync(eventLog.EventId);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error publishing");
                    await _integrationEventLogService.MarkEventAsFailedAsync(eventLog.EventId);
                }
            }
        }
        public async Task PublishEventsThroughEventBusAsync()
        {
            IEnumerable <IntegrationEventLogEntry> pendingLogEvents = await _eventLogService.RetrieveEventLogsPendingToPublishAsync();

            foreach (var logEvt in pendingLogEvents)
            {
                try
                {
                    await _eventLogService.MarkEventAsInProgressAsync(logEvt.EventId);

                    _eventBus.Publish(logEvt.IntegrationEvent);
                    await _eventLogService.MarkEventAsPublishedAsync(logEvt.EventId);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId} from ProductService", logEvt.EventId);

                    await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId);
                }
            }
        }