diff --git a/src/Web/Interfaces/IPublishEventService.cs b/src/Web/Interfaces/IPublishEventService.cs new file mode 100644 index 000000000..61d6ba46b --- /dev/null +++ b/src/Web/Interfaces/IPublishEventService.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Microsoft.eShopWeb.Web.Interfaces; + +public enum EventType +{ + PageOpenings, + AddToCart, + Checkout +} + + +public interface IPublishEventService +{ + void PublishEvent(EventType eventType, IDictionary properties); +} diff --git a/src/Web/Pages/Basket/Checkout.cshtml.cs b/src/Web/Pages/Basket/Checkout.cshtml.cs index 7bdad4373..e91602c61 100644 --- a/src/Web/Pages/Basket/Checkout.cshtml.cs +++ b/src/Web/Pages/Basket/Checkout.cshtml.cs @@ -13,23 +13,26 @@ namespace Microsoft.eShopWeb.Web.Pages.Basket; -public class CheckoutModel : PageModel +public class CheckoutModel : PageBase { private readonly IBasketService _basketService; private readonly IOrderService _orderService; private string _username = null; private readonly IBasketViewModelService _basketViewModelService; - private readonly IAppLogger _logger; - + private readonly IAppLogger _logger; + private readonly IPublishEventService _publishService; + public CheckoutModel(IBasketService basketService, IBasketViewModelService basketViewModelService, IOrderService orderService, - IAppLogger logger) + IAppLogger logger, + IPublishEventService publishEventService) : base(publishEventService) { _basketService = basketService; _orderService = orderService; _basketViewModelService = basketViewModelService; - _logger = logger; + _logger = logger; + _publishService = publishEventService; } public BasketViewModel BasketModel { get; set; } = new BasketViewModel(); @@ -52,7 +55,15 @@ public async Task OnPost(IEnumerable items) var updateModel = items.ToDictionary(b => b.Id.ToString(), b => b.Quantity); await _basketService.SetQuantities(BasketModel.Id, updateModel); - await _orderService.CreateOrderAsync(BasketModel.Id, new Address("123 Main St.", "Kent", "OH", "United States", "44240")); + await _orderService.CreateOrderAsync(BasketModel.Id, new Address("123 Main St.", "Kent", "OH", "United States", "44240")); + + var dictionary = new Dictionary + { + { "Username", BasketModel.BuyerId}, + { "Total", BasketModel.Total().ToString()} + }; + + _publishService.PublishEvent(EventType.Checkout, dictionary); await _basketService.DeleteBasketAsync(BasketModel.Id); } catch (EmptyBasketOnCheckoutException emptyBasketOnCheckoutException) @@ -66,7 +77,7 @@ public async Task OnPost(IEnumerable items) } private async Task SetBasketModelAsync() - { + { GetOrSetBasketCookieAndUserName(); BasketModel = await _basketViewModelService.GetOrCreateBasketForUser(_username); } diff --git a/src/Web/Pages/Basket/Index.cshtml.cs b/src/Web/Pages/Basket/Index.cshtml.cs index ad42bf784..56afed532 100644 --- a/src/Web/Pages/Basket/Index.cshtml.cs +++ b/src/Web/Pages/Basket/Index.cshtml.cs @@ -14,13 +14,16 @@ namespace Microsoft.eShopWeb.Web.Pages.Basket; public class IndexModel : PageModel { private readonly IBasketService _basketService; - private readonly IBasketViewModelService _basketViewModelService; - + private readonly IBasketViewModelService _basketViewModelService; + private readonly IPublishEventService _publishService; + public IndexModel(IBasketService basketService, - IBasketViewModelService basketViewModelService) + IBasketViewModelService basketViewModelService, + IPublishEventService publishService) //: base(publishService) { _basketService = basketService; - _basketViewModelService = basketViewModelService; + _basketViewModelService = basketViewModelService; + _publishService = publishService; } public BasketViewModel BasketModel { get; set; } = new BasketViewModel(); @@ -41,6 +44,14 @@ public async Task OnPost(CatalogItemViewModel productDetails) var basket = await _basketService.AddItemToBasket(username, productDetails.Id, productDetails.Price); + var dictionary = new Dictionary + { + { "Username", username}, + { "ProductId", productDetails.Id.ToString()}, + { "Price", productDetails.Price.ToString() } + }; + + _publishService.PublishEvent(EventType.AddToCart, dictionary); BasketModel = await _basketViewModelService.Map(basket); return RedirectToPage(); diff --git a/src/Web/Pages/Basket/Success.cshtml.cs b/src/Web/Pages/Basket/Success.cshtml.cs index c8e9ac06c..048e380ec 100644 --- a/src/Web/Pages/Basket/Success.cshtml.cs +++ b/src/Web/Pages/Basket/Success.cshtml.cs @@ -1,11 +1,16 @@ using Microsoft.AspNetCore.Mvc.RazorPages; - +using Microsoft.eShopWeb.Web.Interfaces; + namespace Microsoft.eShopWeb.Web.Pages.Basket; -public class SuccessModel : PageModel -{ +public class SuccessModel : PageBase +{ + + public SuccessModel(IPublishEventService publishEventService) : base(publishEventService) + { + } + public void OnGet() { - } } diff --git a/src/Web/Pages/PageBase.cs b/src/Web/Pages/PageBase.cs new file mode 100644 index 000000000..3c0568f0b --- /dev/null +++ b/src/Web/Pages/PageBase.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.eShopWeb.Web.Interfaces; + +namespace Microsoft.eShopWeb.Web.Pages; + +public abstract class PageBase : PageModel +{ + public PageBase(IPublishEventService publishEventService) + { + publishEventService.PublishEvent(EventType.PageOpenings, new Dictionary {{ "PageName", this.GetType().Name }}); + } +} diff --git a/src/Web/Properties/serviceDependencies.json b/src/Web/Properties/serviceDependencies.json new file mode 100644 index 000000000..6d97b246e --- /dev/null +++ b/src/Web/Properties/serviceDependencies.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights" + } + } +} \ No newline at end of file diff --git a/src/Web/Properties/serviceDependencies.local.json b/src/Web/Properties/serviceDependencies.local.json new file mode 100644 index 000000000..22c7f0839 --- /dev/null +++ b/src/Web/Properties/serviceDependencies.local.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "appInsights1": { + "type": "appInsights.sdk" + } + } +} \ No newline at end of file diff --git a/src/Web/Services/PublishEventService.cs b/src/Web/Services/PublishEventService.cs new file mode 100644 index 000000000..1344075c5 --- /dev/null +++ b/src/Web/Services/PublishEventService.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Microsoft.ApplicationInsights; +using Microsoft.eShopWeb.Web.Interfaces; +namespace Microsoft.eShopWeb.Web.Services; + +public class PublishEventService : IPublishEventService +{ + private readonly TelemetryClient _telemetryClient; + + public PublishEventService(TelemetryClient telemetryClient) + { + _telemetryClient = telemetryClient; + } + + + public void PublishEvent(EventType eventType, IDictionary properties) + { + try + { + _telemetryClient.TrackEvent(eventType.ToString(), properties); + } + catch + { + //ignore; + } + } +} diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index aff300f53..c0d290fd9 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -19,6 +19,8 @@ using Microsoft.EntityFrameworkCore; using Microsoft.eShopWeb.Infrastructure.Data; using Microsoft.eShopWeb.Web.Configuration; +using Microsoft.eShopWeb.Web.Interfaces; +using Microsoft.eShopWeb.Web.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -143,8 +145,11 @@ public void ConfigureServices(IServiceCollection services) services.AddBlazorServices(); services.AddDatabaseDeveloperPageExceptionFilter(); + services.AddApplicationInsightsTelemetry(); + services.AddScoped(); - _services = services; // used to debug registered services + _services = services; // used to debug registered services + } diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 6b770b498..18fde0665 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 2c903c3d4..a3428ffec 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -15,5 +15,8 @@ "System": "Warning" }, "AllowedHosts": "*" + }, + "ApplicationInsights": { + "InstrumentationKey": "00000000-0000-0000-0000-000000000000" } }