using Basket.API.IntegrationEvents.Events; using Basket.API.Model; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Services; using Microsoft.Extensions.Logging; using System; using System.Net; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers { [Route("api/v1/[controller]")] [Authorize] [ApiController] public class BasketController : ControllerBase { private readonly IBasketRepository _repository; private readonly IIdentityService _identityService; private readonly IEventBus _eventBus; private readonly ILogger _logger; public BasketController( ILogger logger, IBasketRepository repository, IIdentityService identityService, IEventBus eventBus) { _logger = logger; _repository = repository; _identityService = identityService; _eventBus = eventBus; } [HttpGet("{id}")] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] public async Task> GetBasketByIdAsync(string id) { var basket = await _repository.GetBasketAsync(id); return Ok(basket ?? new CustomerBasket(id)); } [HttpPost] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] public async Task> UpdateBasketAsync([FromBody]CustomerBasket value) { var basket = await _repository.UpdateBasketAsync(value); var integrationEvent = new UserAddedCartItemToBasketIntegrationEvent("demouser@microsoft.com", value.Items[value.Items.Count - 1]); try { _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", integrationEvent.Id, Program.AppName, integrationEvent); _eventBus.Publish(integrationEvent); } catch (Exception ex) { _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName}", integrationEvent.Id, Program.AppName); throw; } return Ok(basket); } [Route("checkout")] [HttpPost] [ProducesResponseType((int)HttpStatusCode.Accepted)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] public async Task CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) { var userId = _identityService.GetUserIdentity(); basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ? guid : basketCheckout.RequestId; var basket = await _repository.GetBasketAsync(userId); if (basket == null) { return BadRequest(); } var userName = User.FindFirst(x => x.Type == "unique_name").Value; var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, userName, basketCheckout.City, basketCheckout.Street, basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName, basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket); // Once basket is checkout, sends an integration event to // ordering.api to convert basket to order and proceeds with // order creation process try { _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppName, eventMessage); _eventBus.Publish(eventMessage); } catch (Exception ex) { _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName}", eventMessage.Id, Program.AppName); throw; } return Accepted(); } // DELETE api/values/5 [HttpDelete("{id}")] [ProducesResponseType(typeof(void), (int)HttpStatusCode.OK)] public async Task DeleteBasketByIdAsync(string id) { await _repository.DeleteBasketAsync(id); } } }