コード例 #1
0
        public async Task Handle(ProductChangedEvent e)
        {
            switch (e.ChangeType)
            {
            case ChangeType.Creation:
            case ChangeType.Edition:
                if (!e.NewValue.IsStarted)
                {
                    return;
                }
                await _legacyAssetsCacheUpdater.HandleProductUpserted(_convertService.Convert <ProductContract, Product>(e.NewValue), e.Timestamp);

                break;

            case ChangeType.Deletion:
                if (!e.OldValue.IsStarted)
                {
                    return;
                }
                await _legacyAssetsCacheUpdater.HandleProductRemoved(e.OldValue.ProductId, e.Timestamp);

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #2
0
        private async Task <ProductChangedEvent> PrepareProductChangedEvent(ProductUpsert productUpsert,
                                                                            string correlationToken)
        {
            // Perform Lookup to get Genre and Artist Names
            var artistName = (await _artistRepository.GetById(productUpsert.ArtistId, correlationToken)).Name;
            var genreName  = (await _genreRepository.GetById(productUpsert.GenreId, correlationToken)).Name;

            //// Provide fallback logic in the event we cannot fetch Artist or Genre name
            genreName ??= "Unknown Genre";
            artistName ??= "Unknown Artist";

            // Populate data in the event object
            var productChangedEvent = new ProductChangedEvent
            {
                Id              = productUpsert.Id,
                Title           = productUpsert.Title,
                ArtistName      = artistName,
                GenreName       = genreName,
                Price           = productUpsert.Price,
                ReleaseDate     = productUpsert.ReleaseDate ?? DateTime.UtcNow.Date,
                ParentalCaution = productUpsert.ParentalCaution,
                Upc             = productUpsert.Upc,
                Cutout          = productUpsert.Cutout
            };

            productChangedEvent.CorrelationToken = correlationToken;

            return(productChangedEvent);
        }
コード例 #3
0
        public void Handle(ProductChangedEvent @event, DatabaseContext db)
        {
            var product = @event.Product;

            if (product == null)
            {
                return;
            }

            var productReadModel = db.Set <ProductReadModel>()
                                   .FirstOrDefault(readmodel => readmodel.AggregateRootId == product.Id);

            if (productReadModel != null)
            {
                productReadModel.ChangeDetails(product.Code,
                                               product.Id,
                                               product.BoothIds,
                                               product.Name,
                                               product.Description,
                                               product.Price,
                                               product.ProductSupplierId,
                                               product.ProductSupplier.Name,
                                               product.Photo.Url,
                                               product.Photo.Width,
                                               product.Photo.Height);

                db.Set <ProductReadModel>()
                .Update(productReadModel);
            }
        }
コード例 #4
0
        private void AddOrUpdateEvent(ProductChangedEvent productChangedEvent)
        {
            try
            {
                using (var scope = _serviceProvider.CreateScope())
                {
                    var scopedProcessingService =
                        scope.ServiceProvider
                        .GetRequiredService <IProductChangedEventRepository>();

                    ProductChangedEvent evt;
                    if (productChangedEvent.EventId == Guid.Empty ||
                        (evt = scopedProcessingService.Get(productChangedEvent.EventId)) == null)
                    {
                        scopedProcessingService.Add(productChangedEvent);
                    }
                    else
                    {
                        evt.MessageSent = true;
                        scopedProcessingService.Update(evt);
                    }

                    scopedProcessingService.Save();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
コード例 #5
0
 public bool Add(ProductChangedEvent productChangedEvent)
 {
     if (productChangedEvent.Product.ProductId != null)
     {
         _context.Add(productChangedEvent.Product);
     }
     return(_context.SaveChanges() > 0);
 }
コード例 #6
0
        public bool Add(ProductChangedEvent productChangedEvent)
        {
            productChangedEvent.Product =
                _dbContext.Products
                .FirstOrDefault(_ => _.ProductId == productChangedEvent.Product.ProductId);

            productChangedEvent.EventId = Guid.NewGuid();

            _dbContext.ProductChangedEvents.Add(productChangedEvent);

            return(true);
        }
コード例 #7
0
        /// <summary>
        /// Method responsable to Add/Update/Delete follows rules and persisting data in memory.
        /// </summary>
        /// <param name="productChangedEvent"></param>
        /// <returns></returns>
        public bool Maintain(ProductChangedEvent productChangedEvent)
        {
            if (productChangedEvent.State == ProductState.Added || productChangedEvent.State == ProductState.Modified)
            {
                if (productChangedEvent.Product.ProductId != Guid.Empty)
                {
                    var product = _context.Products.Where(x => x.ProductId.Equals(productChangedEvent.Product.ProductId));

                    if (product.Equals(null))
                    {
                        this.Update(productChangedEvent); //Se existir o Id na base, atualiza o produto, senão cria.
                    }
                    else
                    {
                        this.Add(productChangedEvent);
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (productChangedEvent.State == ProductState.Deleted)
            {
                if (productChangedEvent.Product.ProductId != Guid.Empty)
                {
                    var product = _context.Products.Where(x => x.ProductId == productChangedEvent.Product.ProductId);

                    if (product != null)
                    {
                        _context.Remove(productChangedEvent.Product);
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            return(false);
        }
コード例 #8
0
        public UpdateProductCommand(string productKey, DateTime effectiveStartDate, string productName, string productDisplayName, string printIssn, string onlineIssn,
                                    string productTypeCode, string productStatusCode, string publisherProductCode, int legacyIdSpid)
        {
            ProductKey           = productKey;
            EffectiveStartDate   = effectiveStartDate;
            ProductName          = productName;
            ProductDisplayName   = productDisplayName;
            PrintIssn            = printIssn;
            OnlineIssn           = onlineIssn;
            ProductTypeCode      = productTypeCode;
            ProductStatusCode    = productStatusCode;
            PublisherProductCode = publisherProductCode;
            LegacyIdSpid         = legacyIdSpid;

            //Use Mediator to publish the messages --> https://github.com/jbogard/MediatR/wiki
            var productChangedPublishToSnsTopicEvent = new ProductChangedEvent(productName, productDisplayName, printIssn, onlineIssn,
                                                                               publisherProductCode, "product-updated");

            AddCommandEvent(productChangedPublishToSnsTopicEvent);
        }
コード例 #9
0
        public AddProductCommand(string productName, string productDisplayName, long publisherId, string printIssn, string onlineIssn, string productTypeCode,
                                 string productStatusCode, string publisherProductCode, int legacyIdSpid)
        {
            //Add Precondition checks here if required.
            //This along with property attributes will help avoid transmitting invalid commands to command handlers and enforce the fail fast principle.

            ProductName          = productName;
            ProductDisplayName   = productDisplayName;
            PublisherId          = publisherId;
            PrintIssn            = printIssn;
            OnlineIssn           = onlineIssn;
            ProductTypeCode      = productTypeCode;
            ProductStatusCode    = productStatusCode;
            PublisherProductCode = publisherProductCode;
            LegacyIdSpid         = legacyIdSpid;

            var productChangedPublishToSnsTopicEvent = new ProductChangedEvent(productName, productDisplayName, printIssn, onlineIssn,
                                                                               publisherProductCode, "product-added");

            AddCommandEvent(productChangedPublishToSnsTopicEvent);
        }
コード例 #10
0
        private async Task <ProductChangedEvent> PrepareProductChangedEvent(Product product, string correlationToken)
        {
            // Perform Lookup to get Genre and Artist Names
            Artist artist = await _artistRepository.GetById(product.ArtistId, correlationToken);

            Genre genre = await _genreRepository.GetById(product.GenreId, correlationToken);

            // Populate data in the event object
            var productChangedEvent = new ProductChangedEvent
            {
                Id    = product.Id,
                Title = product.Title,
                // Provide fallback logic in the event we cannot fetch Artist or Genre name
                ArtistName      = artist.Name ?? "Unknown Artist",
                GenreName       = genre.Name ?? "Unknown Genre",
                Price           = product.Price,
                ReleaseDate     = product.ReleaseDate ?? DateTime.Now,
                ParentalCaution = product.ParentalCaution,
                Upc             = product.Upc,
                Cutout          = product.Cutout
            };

            return(productChangedEvent);
        }
コード例 #11
0
 private async Task RaiseEvent(string productChangedTopicName, ProductChangedEvent productChangedEvent)
 {
     var topicClient = TopicClient.CreateFromConnectionString(this.serviceBusConfiguration.ConnectionString, this.serviceBusConfiguration.ProductChangedTopicName);
     await topicClient.SendAsync(BrokeredMessageFactory.CreateJsonMessage(productChangedEvent));
 }
コード例 #12
0
 public bool Update(ProductChangedEvent productChangedEvent)
 {
     return(true);
 }
コード例 #13
0
 public bool Update(ProductChangedEvent productChangedEvent)
 {
     _context.Products.Update(productChangedEvent.Product);
     return(_context.SaveChanges() > 0);
 }
コード例 #14
0
 public bool Delete(ProductChangedEvent productChangedEvent)
 {
     _context.Products.Remove(productChangedEvent.Product);
     return(_context.SaveChanges() > 0);
 }
コード例 #15
0
        public async Task Handle(ProductChangedEvent @event)
        {
            switch (@event.ChangeType)
            {
            case ChangeType.Creation:
            case ChangeType.Edition:
                if ([email protected])
                {
                    _log.WriteInfo(nameof(ProductChangedProjection),
                                   nameof(Handle),
                                   $"ProductChangedEvent received for productId: {@event.NewValue.ProductId}, but it was ignored because it has not been started yet.");
                    return;
                }

                break;

            case ChangeType.Deletion:
                if ([email protected])
                {
                    _log.WriteInfo(nameof(ProductChangedProjection),
                                   nameof(Handle),
                                   $"ProductChangedEvent received for productId: {@event.OldValue.ProductId}, but it was ignored because it has not been started yet.");
                    return;
                }

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (@event.ChangeType == ChangeType.Deletion)
            {
                CloseAllOrders();

                ValidatePositions(@event.OldValue.ProductId);

                _assetPairsCache.Remove(@event.OldValue.ProductId);
            }
            else
            {
                if (@event.NewValue.IsDiscontinued)
                {
                    CloseAllOrders();
                    RemoveQuoteFromCache();
                }

                await _tradingInstrumentsManager.UpdateTradingInstrumentsCacheAsync();

                var isAdded = _assetPairsCache.AddOrUpdate(AssetPair.CreateFromProduct(@event.NewValue,
                                                                                       _mtSettings.DefaultLegalEntitySettings.DefaultLegalEntity));

                if (@event.NewValue.TradingCurrency != AssetPairConstants.BaseCurrencyId)
                {
                    _assetPairsCache.AddOrUpdate(AssetPair.CreateFromCurrency(@event.NewValue.TradingCurrency,
                                                                              _mtSettings.DefaultLegalEntitySettings.DefaultLegalEntity));
                }

                //only for product
                if (isAdded)
                {
                    await _scheduleSettingsCacheService.UpdateScheduleSettingsAsync();
                }

                if (@event.ChangeType == ChangeType.Edition &&
                    @event.OldValue.IsTradingDisabled != @event.NewValue.IsTradingDisabled)
                {
                    await HandleTradingDisabled(@event.NewValue, @event.Username);
                }
            }

            void RemoveQuoteFromCache()
            {
                var result = _quoteCache.RemoveQuote(@event.OldValue.ProductId);

                if (result != RemoveQuoteErrorCode.None)
                {
                    _log.WriteWarning(nameof(ProductChangedProjection), nameof(RemoveQuoteFromCache), result.Message);
                }
            }

            void CloseAllOrders()
            {
                try
                {
                    foreach (var order in _orderReader.GetPending()
                             .Where(x => x.AssetPairId == @event.OldValue.ProductId))
                    {
                        _tradingEngine.CancelPendingOrder(order.Id, null,
                                                          null, OrderCancellationReason.InstrumentInvalidated);
                    }
                }
                catch (Exception exception)
                {
                    _log.WriteError(nameof(ProductChangedProjection), nameof(CloseAllOrders), exception);
                    throw;
                }
            }

            void ValidatePositions(string assetPairId)
            {
                var positions = _orderReader.GetPositions(assetPairId);

                if (positions.Any())
                {
                    _log.WriteFatalError(nameof(ProductChangedProjection), nameof(ValidatePositions),
                                         new Exception(
                                             $"{positions.Length} positions are opened for [{assetPairId}], first: [{positions.First().Id}]."));
                }
            }
        }