Add handler logic for basket repository. Add Post to CatalogController (only for price update).
This commit is contained in:
parent
5b38a49f11
commit
4d1269b8f2
@ -11,14 +11,35 @@ namespace Basket.API.Events
|
||||
public class CatalogPriceChangedHandler : IIntegrationEventHandler<CatalogPriceChanged>
|
||||
{
|
||||
private readonly IBasketRepository _repository;
|
||||
public CatalogPriceChangedHandler()
|
||||
public CatalogPriceChangedHandler(IBasketRepository repository)
|
||||
{
|
||||
//_repository = repository;
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public void Handle(CatalogPriceChanged @event)
|
||||
public async Task Handle(CatalogPriceChanged @event)
|
||||
{
|
||||
var userIds = await _repository.GetUsers();
|
||||
foreach (var id in userIds)
|
||||
{
|
||||
var basket = await _repository.GetBasket(id);
|
||||
await UpdateBasket(@event.ItemId, @event.NewPrice, basket);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateBasket(int itemId, decimal newPrice, CustomerBasket basket)
|
||||
{
|
||||
//TODO here seems to be a problem with the format
|
||||
var itemsToUpdate = basket?.Items?.Where(x => int.Parse(x.Id) == itemId).ToList();
|
||||
if (itemsToUpdate != null)
|
||||
{
|
||||
foreach (var item in itemsToUpdate)
|
||||
{
|
||||
var originalPrice = item.UnitPrice;
|
||||
item.UnitPrice = newPrice;
|
||||
item.OldUnitPrice = originalPrice;
|
||||
}
|
||||
await _repository.UpdateBasket(basket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
|
||||
public string ProductId { get; set; }
|
||||
public string ProductName { get; set; }
|
||||
public decimal UnitPrice { get; set; }
|
||||
public decimal OldUnitPrice { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
public string PictureUrl { get; set; }
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
|
||||
public interface IBasketRepository
|
||||
{
|
||||
Task<CustomerBasket> GetBasket(string customerId);
|
||||
Task<IEnumerable<string>> GetUsers();
|
||||
Task<CustomerBasket> UpdateBasket(CustomerBasket basket);
|
||||
Task<bool> DeleteBasket(string id);
|
||||
}
|
||||
|
@ -31,6 +31,18 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
|
||||
return await database.KeyDeleteAsync(id.ToString());
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetUsers()
|
||||
{
|
||||
var server = await GetServer();
|
||||
|
||||
IEnumerable<RedisKey> data = server.Keys();
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return data.Select(k => k.ToString());
|
||||
}
|
||||
|
||||
public async Task<CustomerBasket> GetBasket(string customerId)
|
||||
{
|
||||
var database = await GetDatabase();
|
||||
@ -63,14 +75,32 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Model
|
||||
{
|
||||
if (_redis == null)
|
||||
{
|
||||
//TODO: Need to make this more robust. Also want to understand why the static connection method cannot accept dns names.
|
||||
var ips = await Dns.GetHostAddressesAsync(_settings.ConnectionString);
|
||||
_logger.LogInformation($"Connecting to database {_settings.ConnectionString} at IP {ips.First().ToString()}");
|
||||
_redis = await ConnectionMultiplexer.ConnectAsync(ips.First().ToString());
|
||||
await ConnectToRedisAsync();
|
||||
}
|
||||
|
||||
return _redis.GetDatabase();
|
||||
}
|
||||
|
||||
private async Task<IServer> GetServer()
|
||||
{
|
||||
if (_redis == null)
|
||||
{
|
||||
await ConnectToRedisAsync();
|
||||
}
|
||||
var endpoint = _redis.GetEndPoints();
|
||||
|
||||
return _redis.GetServer(endpoint.First());
|
||||
}
|
||||
|
||||
private async Task ConnectToRedisAsync()
|
||||
{
|
||||
//TODO: Need to make this more robust. Also want to understand why the static connection method cannot accept dns names.
|
||||
var ips = await Dns.GetHostAddressesAsync(_settings.ConnectionString);
|
||||
_logger.LogInformation($"Connecting to database {_settings.ConnectionString} at IP {ips.First().ToString()}");
|
||||
_redis = await ConnectionMultiplexer.ConnectAsync(ips.First().ToString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,9 +79,24 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
});
|
||||
|
||||
services.AddTransient<IBasketRepository, RedisBasketRepository>();
|
||||
services.AddTransient<IIntegrationEventHandler<CatalogPriceChanged>, CatalogPriceChangedHandler>();
|
||||
|
||||
var eventBus = new EventBus();
|
||||
services.AddSingleton<IEventBus>(eventBus);
|
||||
eventBus.Subscribe<CatalogPriceChanged>(new CatalogPriceChangedHandler());
|
||||
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var catalogPriceHandler = serviceProvider.GetService<IIntegrationEventHandler<CatalogPriceChanged>>();
|
||||
eventBus.Subscribe<CatalogPriceChanged>(catalogPriceHandler);
|
||||
|
||||
//var container = new ContainerBuilder();
|
||||
//container.Populate(services);
|
||||
//container.RegisterModule(new ApplicationModule());
|
||||
|
||||
//return new AutofacServiceProvider(container.Build());
|
||||
|
||||
//var eventBus = new EventBus();
|
||||
//services.AddSingleton<IEventBus>(eventBus);
|
||||
//eventBus.Subscribe<CatalogPriceChanged>(new CatalogPriceChangedHandler(new RedisBasketRepository());
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -107,7 +107,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
||||
//hook to run integration tests until POST methods are created
|
||||
if (catalogTypeId.HasValue && catalogTypeId == 1)
|
||||
{
|
||||
_eventBus.Publish(new CatalogPriceChanged(2, 10.4M));
|
||||
_eventBus.Publish(new CatalogPriceChanged(2, 10.4M, 8.4M));
|
||||
}
|
||||
|
||||
return Ok(model);
|
||||
@ -135,6 +135,30 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
||||
return Ok(items);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Post([FromBody]CatalogItem value)
|
||||
{
|
||||
var item = await _context.CatalogItems.SingleOrDefaultAsync(i => i.Id == value.Id);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (item.Price != value.Price)
|
||||
{
|
||||
var oldPrice = item.Price;
|
||||
item.Price = value.Price;
|
||||
|
||||
_context.CatalogItems.Update(item);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
_eventBus.Publish(new CatalogPriceChanged(item.Id, item.Price, oldPrice));
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
private List<CatalogItem> ComposePicUri(List<CatalogItem> items) {
|
||||
var baseUri = _settings.Value.ExternalCatalogBaseUrl;
|
||||
items.ForEach(x =>
|
||||
|
@ -6,16 +6,17 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure.Catalog
|
||||
{
|
||||
public class CatalogPriceChanged : IIntegrationEvent
|
||||
{
|
||||
public string Message { get { return "CatalogPriceChanged here!!"; } }
|
||||
|
||||
public int ItemId { get; private set; }
|
||||
|
||||
public decimal NewPrice { get; private set; }
|
||||
|
||||
public CatalogPriceChanged(int itemId, decimal newPrice)
|
||||
public decimal OldPrice { get; set; }
|
||||
|
||||
public CatalogPriceChanged(int itemId, decimal newPrice, decimal oldPrice)
|
||||
{
|
||||
ItemId = itemId;
|
||||
NewPrice = newPrice;
|
||||
OldPrice = oldPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
|
||||
{
|
||||
@ -116,7 +117,7 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
|
||||
}
|
||||
|
||||
var consumer = new EventingBasicConsumer(channel);
|
||||
consumer.Received += (model, ea) =>
|
||||
consumer.Received += async (model, ea) =>
|
||||
{
|
||||
var eventName = ea.RoutingKey;
|
||||
if (_handlers.ContainsKey(eventName))
|
||||
@ -132,7 +133,7 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
|
||||
|
||||
foreach (var handler in handlers)
|
||||
{
|
||||
concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
|
||||
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,13 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
|
||||
{
|
||||
public interface IIntegrationEventHandler<in TIntegrationEvent> : IIntegrationEventHandler
|
||||
where TIntegrationEvent: IIntegrationEvent
|
||||
{
|
||||
void Handle(TIntegrationEvent @event);
|
||||
Task Handle(TIntegrationEvent @event);
|
||||
}
|
||||
|
||||
public interface IIntegrationEventHandler
|
||||
|
Loading…
x
Reference in New Issue
Block a user