Example #1
0
        public async Task SeedAsync(CatalogContext context, IHostingEnvironment env, IOptions <CatalogSettings> settings, ILogger <CatalogContextSeed> logger)
        {
            var policy = CreatePolicy(logger, nameof(CatalogContextSeed));

            await policy.ExecuteAsync(async() =>
            {
                var useCustomizationData = settings.Value.UseCustomizationData;
                var contentRootPath      = env.ContentRootPath;
                var picturePath          = env.WebRootPath;

                if (!context.CatalogBrands.Any())
                {
                    await context.CatalogBrands.AddRangeAsync(useCustomizationData
                                                ? GetCatalogBrandsFromFile(contentRootPath, logger)
                                                : GetPreconfiguredCatalogBrands());

                    await context.SaveChangesAsync();
                }

                if (!context.CatalogTypes.Any())
                {
                    await context.CatalogTypes.AddRangeAsync(useCustomizationData
                                                ? GetCatalogTypesFromFile(contentRootPath, logger)
                                                : GetPreconfiguredCatalogTypes());

                    await context.SaveChangesAsync();
                }

                if (!context.CatalogItems.Any())
                {
                    await context.CatalogItems.AddRangeAsync(useCustomizationData
                                                ? GetCatalogItemsFromFile(contentRootPath, context, logger)
                                                : GetPreconfiguredItems());

                    await context.SaveChangesAsync();

                    GetCatalogItemPictures(contentRootPath, picturePath);
                }
            });
        }
Example #2
0
        public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt)
        {
            _logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id);

            //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
            //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
            await ResilientTransaction.New(_catalogContext).ExecuteAsync(async() =>
            {
                // Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
                await _catalogContext.SaveChangesAsync();
                await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction);
            });
        }
        public async Task <IActionResult> CreateProduct([FromBody] CatalogItem product)
        {
            //call item construction
            var item = new CatalogItem

            {
                CatalogBrandId = product.CatalogBrandId,
                CatalogTypeId  = product.CatalogTypeId,
                Description    = product.Description,
                Name           = product.Name,
                //PictureFileName = product.PictureFileName,
                Price = product.Price
            };

            //add item to catalog items table
            _catalogContext.CatalogItems.Add(item);

            //save changes
            await _catalogContext.SaveChangesAsync();

            return(CreatedAtAction(nameof(GetItemById), new { id = item.Id }));
        }
 public async Task SaveEventAndCatalogContextChangesAsync(int orderId, string orderStatus, IntegrationEvent evt)
 {
     //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
     //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
     await ResilientTransaction.New(_catalogContext)
     .ExecuteAsync(async() =>
     {
         // Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
         await _catalogContext.SaveChangesAsync();
         await _eventLogService.SaveEventAsync(orderId, orderStatus, evt,
                                               _catalogContext.Database.CurrentTransaction.GetDbTransaction());
     });
 }
        public async Task <IActionResult> PutCatalogItem(int id, CatalogItem productToUpdate)
        {
            if (id != productToUpdate.Id)
            {
                return(BadRequest());
            }


            try
            {
                var catalogItem = await _context.CatalogItems.SingleOrDefaultAsync(i => i.Id == productToUpdate.Id);

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

                if (raiseProductPriceChangedEvent)
                {
                    var priceChangedEvent = new ProductPriceChangedIntegrationEvent(catalogItem.Id, productToUpdate.Price, oldPrice);
                    catalogIntegrationEventService.PublishThroughEventBusAsync(priceChangedEvent);
                }
                _context.Entry(productToUpdate).State = EntityState.Modified;

                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CatalogItemExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(NoContent());
        }
        public async Task <int?> DeleteProduct(CatalogContext context, int id)
        {
            var itemToDelete = await context.CatalogItems.SingleOrDefaultAsync(it => it.Id == id);

            if (itemToDelete == null)
            {
                return(null);
            }

            context.CatalogItems.Remove(itemToDelete);
            await context.SaveChangesAsync();

            return(itemToDelete.Id);
        }
Example #7
0
        public static async Task SeedAsync(CatalogContext context)
        {
            //this line of code will be able to apply pending migrations folder and create table for us
            //no need to manually run the update-database command
            context.Database.Migrate();

            //Only seed when table don't have any data
            if (!context.CatalogBrands.Any())
            {
                context.CatalogBrands.AddRange(GetPreconfiguredCatalogBrands());
                await context.SaveChangesAsync();
            }
            if (!context.CatalogTypes.Any())
            {
                context.CatalogTypes.AddRange(GetPreconfiguredCatalogTypes());
                await context.SaveChangesAsync();
            }
            if (!context.Catalogs.Any())
            {
                context.Catalogs.AddRange(GetPreconfiguredItems());
                await context.SaveChangesAsync();
            }
        }
Example #8
0
        public async Task <IActionResult> UpdateProduct([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
            //{
            //    //Create Integration Event to be published through the Event Bus
            //    var priceChangedEvent = new ProductPriceChangedIntegrationEvent(catalogItem.Id, productToUpdate.Price, oldPrice);

            //    // Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction
            //    await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(priceChangedEvent);

            //    // Publish through the Event Bus and mark the saved event as published
            //    await _catalogIntegrationEventService.PublishThroughEventBusAsync(priceChangedEvent);
            //}
            //else // Just save the updated product because the Product's Price hasn't changed.
            //{
            await _catalogContext.SaveChangesAsync();

            //}

            return(CreatedAtAction(nameof(GetItemById), new { id = productToUpdate.Id }, null));
        }
        public async Task <int?> UpdateProduct(CatalogContext context, CatalogItem catalogItemToUpdate)
        {
            var catalogItem = await context.CatalogItems.SingleOrDefaultAsync(it => it.Id == catalogItemToUpdate.Id);

            if (catalogItem == null)
            {
                return(null);
            }

            catalogItem = catalogItemToUpdate;
            context.CatalogItems.Update(catalogItem);
            await context.SaveChangesAsync();

            return(catalogItem.Id);
        }
Example #10
0
        public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
        {
            _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);

            await Task.Delay(10 * 1000);

            foreach (var orderStockItem in @event.OrderStockItems)
            {
                var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);

                catalogItem.RemoveStock(orderStockItem.Units);
            }

            await _catalogContext.SaveChangesAsync();
        }
Example #11
0
        public async Task <IActionResult> UpdateProduct([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);


            await _catalogContext.SaveChangesAsync();


            return(CreatedAtAction(nameof(GetItemById), new { id = productToUpdate.Id }, null));
        }
        // PUT: odata/Products(5)
        public async Task <IHttpActionResult> Put([FromODataUri] int key, Delta <Product> patch)
        {
            Validate(patch.GetEntity());

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            Product product = await db.Products.FindAsync(key);

            if (product == null)
            {
                return(NotFound());
            }

            patch.Put(product);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ProductExists(key))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(Updated(product));
        }
Example #13
0
        public async Task Consume(ConsumeContext <OrderStatusChangedToPaidIntegrationEvent> context)
        {
            //we're not blocking stock/inventory
            foreach (var orderStockItem in context.Message.OrderStockItems)
            {
                var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);

                catalogItem.RemoveStock(orderStockItem.Units);
            }

            await _catalogContext.SaveChangesAsync();

            var orderStockSentForOrder = new OrderStockSentForOrderIntegrationEvent(context.Message.OrderId);
            await _endpoint.Publish(orderStockSentForOrder);
        }
Example #14
0
        public async Task <User> Register(User user, string password)
        {
            byte[] passwordHash, passwordSalt;

            CreatePasswordHash(password, out passwordHash, out passwordSalt);

            // user.PasswordHash = passwordHash;
            // user.PasswordSalt = passwordSalt;

            await _context.Users.AddAsync(user);

            await _context.SaveChangesAsync();

            return(user);
        }
Example #15
0
            public async Task <Response> Handle(Command message)
            {
                var book   = mapper.Map <Book>(message.Request);
                var author = await context.Auhtors.SingleOrDefaultAsync(a => a.Id == book.AuthorId);

                if (author == null)
                {
                    throw new EntityNotFoundException($"Could not find an author with id {book.AuthorId}");
                }
                context.Books.Add(book);
                await context.SaveChangesAsync();

                return(new Response {
                    Id = book.Id
                });
            }
        public async Task <ActionResult> UpdateProductAsync(int id, [FromBody] string description)
        {
            var product = await _catalogContext.Products.SingleOrDefaultAsync(i => i.Id == id);

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

            product.Description = description;
            _catalogContext.Products.Update(product);

            await _catalogContext.SaveChangesAsync();

            return(NoContent());
        }
Example #17
0
        public async Task Handle(ProductCreateCommand command,
                                 CancellationToken cancellationToken
                                 )
        {
            await _context.AddAsync(new Product
            {
                Price       = command.Price,
                Description = command.Description,
                Name        = command.Name
            },
                                    cancellationToken)
            .ConfigureAwait(false);

            await _context.SaveChangesAsync(cancellationToken)
            .ConfigureAwait(false);
        }
Example #18
0
        public async Task Handle(ProductInStockUpdateStockCommand command, CancellationToken cancellationToken)
        {
            _logger.LogInformation("--- ProductInStockUpdateStockCommand started");

            var products = command.Items.Select(item => item.ProductId);
            var stocks   = await _context.Stock
                           .Where(x => products.Contains(x.ProductId))
                           .ToListAsync(cancellationToken);

            _logger.LogInformation("--- Retrieving products from database");

            foreach (var item in command.Items)
            {
                var entry = stocks.SingleOrDefault(x => x.ProductId == item.ProductId);

                if (item.Action == ProductInStockAction.Subtract)
                {
                    if (entry is null || item.Stock > entry.Stock)
                    {
                        _logger.LogError($"Product {entry.ProductId} - does not have enough stock");
                        throw new ArgumentException($"Product {entry.ProductId} - does not have enough stock");
                    }
                    _logger.LogInformation($"--- Product {entry.ProductId} - stock subtracted - new stock {entry.Stock}");
                    entry.Stock -= item.Stock;
                }
                else
                {
                    if (entry is null)
                    {
                        entry = new ProductInStock
                        {
                            ProductId = item.ProductId
                        };

                        await _context.AddAsync(entry, cancellationToken);

                        _logger.LogInformation($"--- New Stock created for {entry.ProductId} - because it has not a previous stock");
                    }
                    entry.Stock += item.Stock;
                    _logger.LogInformation($"--- Product {entry.ProductId} - stock increased - new stock {entry.Stock}");
                }
            }

            await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

            _logger.LogInformation("--- ProductInStockUpdateStockCommand ended");
        }
Example #19
0
        public async Task CreateRequestForCommandAsync <T>(Guid id)
        {
            var exists = await ExistAsync(id);

            var request = exists ?
                          throw new DomainException($"Request with {id} already exists") :
                                new ClientRequest()
                                {
                                    Id   = id,
                                    Name = typeof(T).Name,
                                    Time = DateTime.UtcNow
                                };

            _context.Add(request);

            await _context.SaveChangesAsync();
        }
Example #20
0
        public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
        {
            using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}"))
            {
                _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);

                //we're not blocking stock/inventory
                foreach (var orderStockItem in @event.OrderStockItems)
                {
                    var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);

                    catalogItem.RemoveStock(orderStockItem.Units);
                }

                await _catalogContext.SaveChangesAsync();
            }
        }
Example #21
0
        public async Task <ActionResult> CreateProductAsync([FromBody] CatalogItem product)
        {
            var item = new CatalogItem
            {
                CatalogBrandId  = product.CatalogBrandId,
                CatalogTypeId   = product.CatalogTypeId,
                Description     = product.Description,
                Name            = product.Name,
                PictureFileName = product.PictureFileName,
                Price           = product.Price
            };

            _catalogContext.CatalogItems.Add(item);

            await _catalogContext.SaveChangesAsync();

            return(CreatedAtAction(nameof(ItemByIdAsync), new { id = item.Id }, null));
        }
        public async Task <int?> CreateProduct(CatalogContext context, CatalogItem catalogItemToCreate)
        {
            var item = new CatalogItem
            {
                CatalogBrandId  = catalogItemToCreate.CatalogBrandId,
                CatalogTypeId   = catalogItemToCreate.CatalogTypeId,
                Description     = catalogItemToCreate.Description,
                Name            = catalogItemToCreate.Name,
                PictureFileName = catalogItemToCreate.PictureFileName,
                PictureUrl      = catalogItemToCreate.PictureUrl,
                Price           = catalogItemToCreate.Price
            };

            context.CatalogItems.Add(item);
            await context.SaveChangesAsync();

            return(item.Id);
        }
        public async Task <IActionResult> CreateProduct(
            [FromBody] CatalogItem Product
            )
        {
            var item = new CatalogItem
            {
                CatalogBrandId = Product.CatalogBrandId,
                CatalogTypeId  = Product.CatalogTypeId,
                Description    = Product.Description,
                Name           = Product.PictureUrl,
                Price          = Product.Price
            };

            _CatalogContext.catalogItems.Add(item);
            await _CatalogContext.SaveChangesAsync();

            //GetItemsbyId (item.Id)
            return(CreatedAtAction(nameof(GetItemById), new { id = item.Id }));
        }
Example #24
0
        public async Task SetUp()
        {
            _fixture = new Fixture();

            _products = _fixture.CreateMany <Product>(10).ToList();

            var options = new DbContextOptionsBuilder <CatalogContext>()
                          .UseInMemoryDatabase(databaseName: $"Catalog_{Guid.NewGuid()}")
                          .Options;

            _dbContext = new CatalogContext(options);
            await _dbContext.Products.AddRangeAsync(_products);

            await _dbContext.SaveChangesAsync();

            _model = _fixture.Create <UpdateProductInputModel>();

            _validator = new UpdateProductModelValidator(_dbContext);
        }
            public async Task <CallResult> DeleteCourseFromLearningPlanAsync(string userId, int courseId)
            {
                ThrowIfDisposed();

                var currentSubscription = await CatalogContext.Subscriptions.FindAsync(userId, courseId);

                if (currentSubscription != null)
                {
                    CatalogContext.Subscriptions.Remove(currentSubscription);

                    await CatalogContext.SaveChangesAsync();

                    return(CallResult.Success);
                }

                var message = string.Format(Resources.EntityNotFound_Subscription, userId, courseId);

                return(CallResult.Failed(message));
            }
Example #26
0
        public async Task <IActionResult> CreateEvent(
            [FromBody] CatalogEvent @event
            )
        {
            var item = new CatalogEvent
            {
                CatalogCompanyId = @event.CatalogCompanyId,
                CatalogTypeId    = @event.CatalogTypeId,
                Description      = @event.Description,
                Name             = @event.Name,
                PictureUrl       = @event.PictureUrl,
                Price            = @event.Price
            };

            _catalogContext.CatalogEvents.Add(item);
            await _catalogContext.SaveChangesAsync();

            return(CreatedAtAction(nameof(GetEventById), new { id = item.Id }));
        }
        public static async Task CreateCatalog(
            [ServiceBusTrigger("catalog-create-command", Connection = "ServiceBusConnection")] Message commandMessage,
            [ServiceBus("catalog-created", Connection = "ServiceBusConnection")] IAsyncCollector <Message> newCatalogTopic,
            ILogger log)
        {
            var newCatalog = JsonConvert.DeserializeObject <Catalog>(Encoding.UTF8.GetString(commandMessage.Body));

            using (var dbcontext = new CatalogContext(new DbContextOptionsBuilder <CatalogContext>().UseSqlServer(Environment.GetEnvironmentVariable("DbConnection")).Options))
            {
                dbcontext.Catalogs.Add(newCatalog);
                await dbcontext.SaveChangesAsync();
            }

            await newCatalogTopic.AddAsync(
                new Message()
            {
                CorrelationId = commandMessage.CorrelationId,
                Body          = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new CatalogCreated(newCatalog.ID, newCatalog.Name)))
            });
        }
Example #28
0
        public async Task <IActionResult> CreateProduct(
            [FromBody] CatalogEventItem product)
        {
            var item = new CatalogEventItem
            {
                CatalogCategoryId = product.CatalogCategoryId,
                CatalogTypeId     = product.CatalogTypeId,
                Description       = product.Description,
                Name       = product.Name,
                PictureUrl = product.PictureUrl,
                Schedule   = product.Schedule,
                Price      = product.Price
            };

            _catalogContext.CatalogEventItems.Add(item);
            await _catalogContext.SaveChangesAsync();

            //GetItembyID
            return(CreatedAtAction(nameof(GetItemById), new { id = item.Id }));
        }
            public async Task <CallResult <SubscriptionChange> > SetFinishStateAsync(int courseId, string userId)
            {
                ThrowIfDisposed();

                var subscription = await CatalogContext.Subscriptions.FindAsync(userId, courseId);

                if (subscription == null)
                {
                    var message = string.Format(Resources.EntityNotFound_Subscription, userId, courseId);
                    return(CallResult <SubscriptionChange> .Failed(message));
                }

                subscription.FinishDate = DateTime.UtcNow.Date;
                subscription.State      = LearningState.Finished;

                await CatalogContext.SaveChangesAsync();

                var subscriptionChange = new SubscriptionChange(subscription.FinishDate.Value);

                return(CallResult <SubscriptionChange> .Success(subscriptionChange));
            }
Example #30
0
        public async Task <IActionResult> CreateProduct([FromBody] CatalogItem product)
        {
            if (product == null || string.IsNullOrEmpty(product.ItemName) || product.Price < 0)
            {
                return(BadRequest("Bad damn product!!!"));
            }

            var item = new CatalogItem
            {
                ItemName    = product.ItemName,
                Price       = product.Price,
                BrandId     = product.BrandId,
                TypeId      = product.TypeId,
                Description = product.Description,
                PictureUrl  = product.PictureUrl
            };

            _context.CatalogItems.Add(item);
            await _context.SaveChangesAsync();

            return(Ok(item));
        }