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); } }); }
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); }
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(); } }
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); }
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(); }
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)); }
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); }
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); }
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()); }
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); }
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"); }
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(); }
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(); } }
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 })); }
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)); }
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))) }); }
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)); }
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)); }