Updates to .NET 6.0 (#1786)

* Seeking feedback: Build and run on .Net 6 preview 6 (#1734)

* Updgrade build and hosting machines to .net6 latest

* Target .net 6

* ILogger is ambiguous?

* More ILogger ambiguity

* Use preview 6... seeing errors in preview 7...

* Of course the SDK version is different :)

* downgrade the last nonworking component

* Only restore the packages we need for the one off service stuck in .net 5

* Downgrade development docker files to use the preview 6 sdk

* Updates `basket-api` to .NET 6 (#1742)

* Use global usings

* Use file-scoped namespaces

* Updates docker images to preview 7

* Created a new migration plan

* Included global usings for identity project

* Updated docker file to preview version to 7

* Updated dockerfiles

* Merged conent from Startup.cs to Program.cs

* Removed Starup.cs

* Removed unnecessary files

* Revert "Removed unnecessary files"

This reverts commit 536bddcd96b54673401cedbe802520dce12b3472.

* Revert "Removed Starup.cs"

This reverts commit 46175d7aa97475d88ec46bce39ed498c7037d924.

* Revert "Merged conent from Startup.cs to Program.cs"

This reverts commit 2766ea86dfef9220fe3f0c27a37a9a6c18153078.

* Removed extra spaces

* Updated basket-api project file

* Update src/Services/Basket/Basket.API/Grpc/BasketService.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Moved the fully qualified namespace on top

* Updated relevant packages in basket.api project

* Updated relevant packages in identity.api project

Co-authored-by: David Pine <david.pine@microsoft.com>

* Updates all the services to .NET 6.0 (#1770)

* Created global using file for catalog.api

* Moved individual usings statements to globalusing

* Updated catalog.api project

* Fixed local run bug for catalog.api

* Included globalusing for payment.api

* Refactored namespace statement for payment.api

* Moved namespaces to ordering.domain project

* Included globalusing for ordering.domain project

* Included globalusings for ordering.infrastructure project

* Refactored namespaces for ordering.infrastructure project

* Updated relevant packages in ordering.infrastructure project

* Included globalusings for ordering.signalrHub project

* Moved all the namespace to globalusings

* Updated packages in ordering.signalrHub csproj file

* Refactored namespace statements in catalog.api project

* Fixed namespace name in ordering.domain

* Included global usings for ordering.api project

* Moved all usings to globalusing file

* Updated ordering.api csproj project

* Fixed bug in statup.cs

* Updated ordering.unittests.csproj file

* Included globalusings in webhooks.api project

* Moved using statements to globalusing file in webhooks.api

* Included globalusing for web.bff.shoppping aggregator project

* Moved namespaces to globalusing shopping aggregator

* Included globalusing mobile.bff.shoppping project

* Moved namespaces to globalusing file

* Included globalusing for eventbus project

* Moved namespaces to global usings for eventbus

* Included globalusing for EventBusRabbitMQ project

* Moved using statements to EventBusRabbitMQ project

* Included global using in EventBusServiceBus project

* Moved using statements to globalusing for EventBusServiceBus

* Included globalusing file for IntegrationEventLogEF project

* Move using statements to globalusing file

* Updated packages of IntegrationEventLogEF project

* Included globalusing to Devspaces.Support project

* Moved using statements to globalusing Devspaces

* Updated dependent packages for Devspaces.Support.csproj

* Fixed bug in Basket API

* Fixed bug in catalog.api

* Fixed bug Identity.API

* Included globalusing to Basket.UnitTest project

* Moved namespaces to Basket.UnitTest project

* Updated packages of Basket.UnitTest csproj

* Included globalusing for Basket.FunctionalTests project

* Included file-scoped namespaces Basket.FunctionalTests

* Updated packages of Basket.FunctionalTests.csproj file

* Updated catalog unit test project to Net 6.0

* Included global usings for Catalog.FunctionalTests

* Included file-scope namespace catalog.functionaltests

* Updated packages of catalog.functionaltest csproj

* Included MigrateDbContext method in HostExtensions

* Included globalusing for ordering.UnitTests project

* Included file-scope statement for Ordering.UnitTest project

* Included globalusing for Ordering.FunctionalTests

* Included file-scope namespace statement for using

* Updated packages in  Ordering.FunctionalTests.csproj

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.API/Startup.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToPaidDomainEvent.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

Co-authored-by: David Pine <david.pine@microsoft.com>

* Updates WebMVC to .NET 6.0 (#1773)

* Included globalusing WebMVC

* Included file scope namespaces for all files

* Updated dockerfile

* Updated packages to WebMVC

* Fixes few bugs in Net 6.0 service migration (#1774)

* Created global using file for catalog.api

* Moved individual usings statements to globalusing

* Updated catalog.api project

* Fixed local run bug for catalog.api

* Included globalusing for payment.api

* Refactored namespace statement for payment.api

* Moved namespaces to ordering.domain project

* Included globalusing for ordering.domain project

* Included globalusings for ordering.infrastructure project

* Refactored namespaces for ordering.infrastructure project

* Updated relevant packages in ordering.infrastructure project

* Included globalusings for ordering.signalrHub project

* Moved all the namespace to globalusings

* Updated packages in ordering.signalrHub csproj file

* Refactored namespace statements in catalog.api project

* Fixed namespace name in ordering.domain

* Included global usings for ordering.api project

* Moved all usings to globalusing file

* Updated ordering.api csproj project

* Fixed bug in statup.cs

* Updated ordering.unittests.csproj file

* Included globalusings in webhooks.api project

* Moved using statements to globalusing file in webhooks.api

* Included globalusing for web.bff.shoppping aggregator project

* Moved namespaces to globalusing shopping aggregator

* Included globalusing mobile.bff.shoppping project

* Moved namespaces to globalusing file

* Included globalusing for eventbus project

* Moved namespaces to global usings for eventbus

* Included globalusing for EventBusRabbitMQ project

* Moved using statements to EventBusRabbitMQ project

* Included global using in EventBusServiceBus project

* Moved using statements to globalusing for EventBusServiceBus

* Included globalusing file for IntegrationEventLogEF project

* Move using statements to globalusing file

* Updated packages of IntegrationEventLogEF project

* Included globalusing to Devspaces.Support project

* Moved using statements to globalusing Devspaces

* Updated dependent packages for Devspaces.Support.csproj

* Fixed bug in Basket API

* Fixed bug in catalog.api

* Fixed bug Identity.API

* Included globalusing to Basket.UnitTest project

* Moved namespaces to Basket.UnitTest project

* Updated packages of Basket.UnitTest csproj

* Included globalusing for Basket.FunctionalTests project

* Included file-scoped namespaces Basket.FunctionalTests

* Updated packages of Basket.FunctionalTests.csproj file

* Updated catalog unit test project to Net 6.0

* Included global usings for Catalog.FunctionalTests

* Included file-scope namespace catalog.functionaltests

* Updated packages of catalog.functionaltest csproj

* Included MigrateDbContext method in HostExtensions

* Included globalusing for ordering.UnitTests project

* Included file-scope statement for Ordering.UnitTest project

* Included globalusing for Ordering.FunctionalTests

* Included file-scope namespace statement for using

* Updated packages in  Ordering.FunctionalTests.csproj

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.API/Startup.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToPaidDomainEvent.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Update src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Apply suggestions from code review

Co-authored-by: David Pine <david.pine@microsoft.com>

* Fixed bugs in Mobile.BFF.Shopping project

* Fixed bugs in Web.Bff.Shopping aggregator project

* Fixed bugs in EventBusServiceBus project

* Fixed bug in Mobile.Bff.Shopping project

Co-authored-by: David Pine <david.pine@microsoft.com>

* Updates webhook client project to .NET 6.0 (#1777)

* Included globalusing file for webhookclient

* Included file scope namespaces for Webhookclient

* Updated packages in WebHookClient project

* Updates webspa project to Net 6.0 (#1778)

* Included globalusing in webspa project

* Included file scoped namespace for webspa project

* Updated packages in WebSPA project

* Updates the Application.FunctionalTests project to .NET 6.0 (#1781)

* Included globalusing in Application.FunctionalTests project

* Included file scoped namespace

* Renamed Azure.Messaging.ServiceBus namespace

* Updates .NET version of Dockerfile to 6.0 (#1785)

* Updatated package versions to RC2

* Updated package versions to RC2

* Updated Dockerfiles to .NET 6 RC2

* Changed docker file tag to 6.0

* Updated Program class

* Updated globalusing file

* Removed preview tag reference from Dockerfile.develop file

* Updated dotnet version to .NET 6.0

* Updated all packages to the .NET 6.0

* Removed RC tag from dockerfile

* Fixed bundleconfig json

* Updated readme files

* Fixed ingress yaml indentation

* Included globalusing for WebStatus project

* Updated WebStatus project to .NET 6.0

* Included scoped namespace

* Updated Dockerfile of WebStatus to .NET 6.0

Co-authored-by: Josh Coleman <83677148+JcolemanNR@users.noreply.github.com>
Co-authored-by: David Pine <david.pine@microsoft.com>
This commit is contained in:
Sumit Ghosh 2021-11-15 19:02:23 +05:30 committed by GitHub
parent 42abcad37e
commit 630cb35cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
537 changed files with 15927 additions and 17245 deletions

View File

@ -22,7 +22,7 @@ on:
env:
SERVICE: catalog-api
IMAGE: catalog.api
DOTNET_VERSION: 5.0.x
DOTNET_VERSION: 6.0.x
PROJECT_PATH: Services/Catalog/Catalog.API
TESTS_PATH: Services/Catalog/Catalog.UnitTests

View File

@ -22,7 +22,7 @@ on:
env:
SERVICE: ordering-api
IMAGE: ordering.api
DOTNET_VERSION: 5.0.x
DOTNET_VERSION: 6.0.x
PROJECT_PATH: Services/Ordering/Ordering.API
TESTS_PATH: Services/Ordering/Ordering.UnitTests

View File

@ -72,9 +72,9 @@ In the future, more features will be implemented in the advanced scenario.
**NEWS / ANNOUNCEMENTS**
Do you want to be up-to-date on .NET Architecture guidance and reference apps like eShopOnContainers? --> Subscribe by "WATCHING" this new GitHub repo: https://github.com/dotnet-architecture/News
## Updated for .NET 5
## Updated for .NET 6
eShopOnContainers is updated to .NET 5 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions with several significant changes.
eShopOnContainers is updated to .NET 6 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions with several significant changes.
**See more details in the [Release notes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Release-notes) wiki page**.
@ -86,7 +86,7 @@ eShopOnContainers is updated to .NET 5 "wave" of technologies. Not just compilat
### Architecture overview
This reference application is cross-platform at the server and client-side, thanks to .NET 5 services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS, or Windows/UWP plus any browser for the client web apps.
This reference application is cross-platform at the server and client-side, thanks to .NET 6 services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS, or Windows/UWP plus any browser for the client web apps.
The architecture proposes a microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using HTTP as the communication protocol between the client apps and the microservices and supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus (a light message broker, to choose between RabbitMQ or Azure Service Bus, underneath) plus other features defined at the [roadmap](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Roadmap).
![](img/eshop_logo.png)

View File

@ -2,8 +2,11 @@
Following are the most important branches:
- `dev`: Contains the latest code **and it is the branch actively developed**. Note that **all PRs must be against the `dev` branch to be considered**. This branch is developed using `.NET 5`
- `main`: Synced time to time from `dev`.It contains "stable" code, although not the latest one. Right now, this branch contains changes specific to `.NET Core 3.1`
- `dev`: Contains the latest code **and it is the branch actively developed**. Note that **all PRs must be against the `dev` branch to be considered**. This branch is developed using `.NET 6`
- `release/net-5`: Contains the code changes specific to the `.NET 5`
- `release/net-3.1.1`: Contains the code changes specific to the `.NET 3.1`
> [!DISCLAIMER]: The `main` branch contains the old code base and will get obsolete in the future. So it's recommended to refer to different [tags](https://github.com/dotnet-architecture/eShopOnContainers/tags) to avoid any confusion.
Any other branch is considered temporary and could be deleted at any time. Do not submit any PR against them!

View File

@ -11,6 +11,7 @@ metadata:
namespace: default
spec:
rules:
- host: localhost
http:
paths:
- path: /webmvc
@ -34,6 +35,7 @@ metadata:
namespace: default
spec:
rules:
- host: localhost
http:
paths:
- path: /identity

View File

@ -1,9 +1,7 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config
public class UrlsConfig
{
public class UrlsConfig
{
public class CatalogOperations
{
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
@ -34,5 +32,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config
public string GrpcCatalog { get; set; }
public string GrpcOrdering { get; set; }
}
}

View File

@ -1,19 +1,10 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class BasketController : ControllerBase
{
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class BasketController : ControllerBase
{
private readonly ICatalogService _catalog;
private readonly IBasketService _basket;
@ -35,8 +26,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
}
// Retrieve the current basket
var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId);
var basket = await _basket.GetByIdAsync(data.BuyerId) ?? new BasketData(data.BuyerId);
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
// group by product id to avoid duplicates
var itemsCalculated = data
@ -93,7 +83,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
}
// Retrieve the current basket
var currentBasket = await _basket.GetById(data.BasketId);
var currentBasket = await _basket.GetByIdAsync(data.BasketId);
if (currentBasket == null)
{
return BadRequest($"Basket with id {data.BasketId} not found.");
@ -135,7 +125,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
//item.PictureUri =
// Step 2: Get current basket status
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
// Step 3: Merge current status with new product
currentBasket.Items.Add(new BasketDataItem()
{
@ -152,5 +142,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
return Ok();
}
}
}

View File

@ -1,14 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
[Route("")]
public class HomeController : Controller
{
[Route("")]
public class HomeController : Controller
{
[HttpGet()]
[HttpGet]
public IActionResult Index()
{
return new RedirectResult("~/swagger");
}
}
}

View File

@ -1,17 +1,10 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
using System.Net;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class OrderController : ControllerBase
{
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class OrderController : ControllerBase
{
private readonly IBasketService _basketService;
private readonly IOrderingService _orderingService;
@ -32,7 +25,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
return BadRequest("Need a valid basketid");
}
// Get the basket data and build a order draft based on it
var basket = await _basketService.GetById(basketId);
var basket = await _basketService.GetByIdAsync(basketId);
if (basket == null)
{
@ -41,5 +34,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
return await _orderingService.GetOrderDraftAsync(basket);
}
}
}

View File

@ -1,8 +1,8 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# It's important to keep lines from here down to "COPY . ." identical in all Dockerfiles

View File

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/sdk:5.0
FROM mcr.microsoft.com/dotnet/sdk:6.0
ARG BUILD_CONFIGURATION=Debug
ENV ASPNETCORE_ENVIRONMENT=Development
ENV DOTNET_USE_POLLING_FILE_WATCHER=true

View File

@ -1,12 +1,5 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters
{
namespace Basket.API.Infrastructure.Filters
{
public class AuthorizeCheckOperationFilter : IOperationFilter

View File

@ -0,0 +1,41 @@
global using CatalogApi;
global using Devspaces.Support;
global using Grpc.Core.Interceptors;
global using Grpc.Core;
global using GrpcBasket;
global using GrpcOrdering;
global using HealthChecks.UI.Client;
global using Microsoft.AspNetCore.Authentication.JwtBearer;
global using Microsoft.AspNetCore.Authentication;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Diagnostics.HealthChecks;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Microsoft.OpenApi.Models;
global using Serilog;
global using Swashbuckle.AspNetCore.SwaggerGen;
global using System.Collections.Generic;
global using System.IdentityModel.Tokens.Jwt;
global using System.Linq;
global using System.Net.Http.Headers;
global using System.Net.Http;
global using System.Net;
global using System.Text.Json;
global using System.Threading.Tasks;
global using System.Threading;
global using System;

View File

@ -1,12 +1,7 @@
using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
public class GrpcExceptionInterceptor : Interceptor
{
public class GrpcExceptionInterceptor : Interceptor
{
private readonly ILogger<GrpcExceptionInterceptor> _logger;
public GrpcExceptionInterceptor(ILogger<GrpcExceptionInterceptor> logger)
@ -37,5 +32,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastruct
return default;
}
}
}
}

View File

@ -1,16 +1,7 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler
{
public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ILogger<HttpClientAuthorizationDelegatingHandler> _logger;
@ -50,5 +41,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastruct
return await _httpContextAccessor.HttpContext
.GetTokenAsync(ACCESS_TOKEN);
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>Mobile.Shopping.HttpAggregator</AssemblyName>
<RootNamespace>Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator</RootNamespace>
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>

View File

@ -1,7 +1,7 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class AddBasketItemRequest
{
public class AddBasketItemRequest
{
public int CatalogItemId { get; set; }
public string BasketId { get; set; }
@ -12,5 +12,4 @@
{
Quantity = 1;
}
}
}

View File

@ -1,13 +1,10 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
public class BasketData
{
public class BasketData
{
public string BuyerId { get; set; }
public List<BasketDataItem> Items { get; set; } = new List<BasketDataItem>();
public List<BasketDataItem> Items { get; set; } = new();
public BasketData()
{
@ -17,6 +14,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
BuyerId = buyerId;
}
}
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class BasketDataItem
{
public class BasketDataItem
{
public string Id { get; set; }
public int ProductId { get; set; }
@ -16,6 +15,4 @@
public int Quantity { get; set; }
public string PictureUrl { get; set; }
}
}

View File

@ -1,7 +1,7 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class CatalogItem
{
public class CatalogItem
{
public int Id { get; set; }
public string Name { get; set; }
@ -9,5 +9,4 @@
public decimal Price { get; set; }
public string PictureUri { get; set; }
}
}

View File

@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
public class OrderData
{
public class OrderData
{
public string OrderNumber { get; set; }
public DateTime Date { get; set; }
@ -42,7 +38,5 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
public string Buyer { get; set; }
public List<OrderItemData> OrderItems { get; } = new List<OrderItemData>();
}
public List<OrderItemData> OrderItems { get; } = new();
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class OrderItemData
{
public class OrderItemData
{
public int ProductId { get; set; }
public string ProductName { get; set; }
@ -14,6 +13,4 @@
public int Units { get; set; }
public string PictureUrl { get; set; }
}
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class UpdateBasketItemData
{
public class UpdateBasketItemData
{
public string BasketItemId { get; set; }
public int NewQty { get; set; }
@ -11,6 +10,4 @@
{
NewQty = 0;
}
}
}

View File

@ -1,11 +1,8 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
public class UpdateBasketItemsRequest
{
public class UpdateBasketItemsRequest
{
public string BasketId { get; set; }
public ICollection<UpdateBasketItemData> Updates { get; set; }
@ -14,6 +11,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
Updates = new List<UpdateBasketItemData>();
}
}
}

View File

@ -1,13 +1,8 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
public class UpdateBasketRequest
{
public class UpdateBasketRequest
{
public string BuyerId { get; set; }
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; }
}
}

View File

@ -1,13 +1,10 @@
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
public class UpdateBasketRequestItemData
{
public class UpdateBasketRequestItemData
{
public string Id { get; set; } // Basket id
public int ProductId { get; set; } // Catalog item id
public int Quantity { get; set; } // Quantity
}
}

View File

@ -1,10 +1,4 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator;
using Serilog;
BuildWebHost(args).Run();
await BuildWebHost(args).RunAsync();
IWebHost BuildWebHost(string[] args) =>
WebHost
.CreateDefaultBuilder(args)

View File

@ -1,13 +1,7 @@
using GrpcBasket;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public class BasketService : IBasketService
{
public class BasketService : IBasketService
{
private readonly Basket.BasketClient _basketClient;
private readonly ILogger<BasketService> _logger;
@ -17,7 +11,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
_logger = logger;
}
public async Task<BasketData> GetById(string id)
public async Task<BasketData> GetByIdAsync(string id)
{
_logger.LogDebug("grpc client created, request = {@id}", id);
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
@ -86,5 +80,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
return map;
}
}
}

View File

@ -1,13 +1,7 @@
using CatalogApi;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public class CatalogService : ICatalogService
{
public class CatalogService : ICatalogService
{
private readonly Catalog.CatalogClient _client;
public CatalogService(Catalog.CatalogClient client)
@ -39,5 +33,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
Price = (decimal)catalogItemResponse.Price
};
}
}
}

View File

@ -1,13 +1,9 @@
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public interface IBasketService
{
public interface IBasketService
{
Task<BasketData> GetById(string id);
Task<BasketData> GetByIdAsync(string id);
Task UpdateAsync(BasketData currentBasket);
}
}

View File

@ -1,13 +1,8 @@
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public interface ICatalogService
{
public interface ICatalogService
{
Task<CatalogItem> GetCatalogItemAsync(int id);
Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
}
}

View File

@ -1,10 +1,6 @@
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public interface IOrderApiClient
{
public interface IOrderApiClient
{
Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
}
}

View File

@ -1,10 +1,6 @@
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public interface IOrderingService
{
public interface IOrderingService
{
Task<OrderData> GetOrderDraftAsync(BasketData basketData);
}
}

View File

@ -1,15 +1,7 @@
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public class OrderApiClient : IOrderApiClient
{
public class OrderApiClient : IOrderApiClient
{
private readonly HttpClient _apiClient;
private readonly ILogger<OrderApiClient> _logger;
private readonly UrlsConfig _urls;
@ -36,5 +28,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
PropertyNameCaseInsensitive = true
});
}
}
}

View File

@ -1,13 +1,7 @@
using GrpcOrdering;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
public class OrderingService : IOrderingService
{
public class OrderingService : IOrderingService
{
private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
private readonly ILogger<OrderingService> _logger;
@ -75,5 +69,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
return command;
}
}
}

View File

@ -1,32 +1,7 @@
using CatalogApi;
using Devspaces.Support;
using GrpcBasket;
using GrpcOrdering;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator;
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
public class Startup
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
@ -97,10 +72,10 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
});
});
}
}
}
public static class ServiceCollectionExtensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
{
services.AddOptions();
@ -218,5 +193,4 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
return services;
}
}
}

View File

@ -1,11 +1,8 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
public class UrlsConfig
{
public class UrlsConfig
{
public class CatalogOperations
{
// grpc call under REST must go trough port 80
@ -40,6 +37,5 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
public string GrpcCatalog { get; set; }
public string GrpcOrdering { get; set; }
}
}

View File

@ -1,19 +1,10 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class BasketController : ControllerBase
{
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class BasketController : ControllerBase
{
private readonly ICatalogService _catalog;
private readonly IBasketService _basket;
@ -35,7 +26,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
}
// Retrieve the current basket
var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId);
var basket = await _basket.GetByIdAsync(data.BuyerId) ?? new BasketData(data.BuyerId);
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
// group by product id to avoid duplicates
@ -93,7 +84,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
}
// Retrieve the current basket
var currentBasket = await _basket.GetById(data.BasketId);
var currentBasket = await _basket.GetByIdAsync(data.BasketId);
if (currentBasket == null)
{
return BadRequest($"Basket with id {data.BasketId} not found.");
@ -133,7 +124,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
//item.PictureUri =
// Step 2: Get current basket status
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
// Step 3: Search if exist product into basket
var product = currentBasket.Items.SingleOrDefault(i => i.ProductId == item.Id);
if (product != null)
@ -160,5 +151,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
return Ok();
}
}
}

View File

@ -1,14 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
[Route("")]
public class HomeController : Controller
{
[Route("")]
public class HomeController : Controller
{
[HttpGet()]
[HttpGet]
public IActionResult Index()
{
return new RedirectResult("~/swagger");
}
}
}

View File

@ -1,19 +1,13 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using System.Net;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class OrderController : ControllerBase
{
[Route("api/v1/[controller]")]
[Authorize]
[ApiController]
public class OrderController : ControllerBase
{
private readonly IBasketService _basketService;
private readonly IOrderingService _orderingService;
public OrderController(IBasketService basketService, IOrderingService orderingService)
{
_basketService = basketService;
@ -26,12 +20,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
[ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)]
public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
{
if (string.IsNullOrEmpty(basketId))
if (string.IsNullOrWhiteSpace(basketId))
{
return BadRequest("Need a valid basketid");
}
// Get the basket data and build a order draft based on it
var basket = await _basketService.GetById(basketId);
var basket = await _basketService.GetByIdAsync(basketId);
if (basket == null)
{
@ -40,5 +34,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
return await _orderingService.GetOrderDraftAsync(basket);
}
}
}

View File

@ -1,8 +1,8 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# It's important to keep lines from here down to "COPY . ." identical in all Dockerfiles

View File

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/sdk:5.0
FROM mcr.microsoft.com/dotnet/sdk:6.0
ARG BUILD_CONFIGURATION=Debug
ENV ASPNETCORE_ENVIRONMENT=Development
ENV DOTNET_USE_POLLING_FILE_WATCHER=true

View File

@ -1,10 +1,4 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters
{
namespace Basket.API.Infrastructure.Filters
{
@ -30,10 +24,11 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters
{
new OpenApiSecurityRequirement
{
[ oAuthScheme ] = new [] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" }
[ oAuthScheme ] = new[] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" }
}
};
}
}
}
}

View File

@ -0,0 +1,41 @@
global using CatalogApi;
global using Devspaces.Support;
global using Grpc.Core.Interceptors;
global using Grpc.Core;
global using GrpcBasket;
global using GrpcOrdering;
global using HealthChecks.UI.Client;
global using Microsoft.AspNetCore.Authentication.JwtBearer;
global using Microsoft.AspNetCore.Authentication;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Diagnostics.HealthChecks;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Diagnostics.HealthChecks;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Microsoft.OpenApi.Models;
global using Serilog;
global using Swashbuckle.AspNetCore.SwaggerGen;
global using System.Collections.Generic;
global using System.IdentityModel.Tokens.Jwt;
global using System.Linq;
global using System.Net.Http.Headers;
global using System.Net.Http;
global using System.Net;
global using System.Text.Json;
global using System.Threading.Tasks;
global using System.Threading;
global using System;

View File

@ -1,12 +1,7 @@
using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
public class GrpcExceptionInterceptor : Interceptor
{
public class GrpcExceptionInterceptor : Interceptor
{
private readonly ILogger<GrpcExceptionInterceptor> _logger;
public GrpcExceptionInterceptor(ILogger<GrpcExceptionInterceptor> logger)
@ -24,11 +19,11 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
return new AsyncUnaryCall<TResponse>(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose);
}
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> task)
{
try
{
var response = await t;
var response = await task;
return response;
}
catch (RpcException e)
@ -37,5 +32,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
return default;
}
}
}
}

View File

@ -1,16 +1,8 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
{
public class HttpClientAuthorizationDelegatingHandler
public class HttpClientAuthorizationDelegatingHandler
: DelegatingHandler
{
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor)
@ -23,12 +15,12 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
var authorizationHeader = _httpContextAccessor.HttpContext
.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(authorizationHeader))
if (!string.IsNullOrWhiteSpace(authorizationHeader))
{
request.Headers.Add("Authorization", new List<string>() { authorizationHeader });
}
var token = await GetToken();
var token = await GetTokenAsync();
if (token != null)
{
@ -38,12 +30,11 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure
return await base.SendAsync(request, cancellationToken);
}
async Task<string> GetToken()
Task<string> GetTokenAsync()
{
const string ACCESS_TOKEN = "access_token";
return await _httpContextAccessor.HttpContext
return _httpContextAccessor.HttpContext
.GetTokenAsync(ACCESS_TOKEN);
}
}
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class AddBasketItemRequest
{
public class AddBasketItemRequest
{
public int CatalogItemId { get; set; }
public string BasketId { get; set; }
@ -13,6 +12,5 @@
{
Quantity = 1;
}
}
}

View File

@ -1,13 +1,10 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
public class BasketData
{
public class BasketData
{
public string BuyerId { get; set; }
public List<BasketDataItem> Items { get; set; } = new List<BasketDataItem>();
public List<BasketDataItem> Items { get; set; } = new();
public BasketData()
{
@ -17,6 +14,5 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
BuyerId = buyerId;
}
}
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class BasketDataItem
{
public class BasketDataItem
{
public string Id { get; set; }
public int ProductId { get; set; }
@ -16,6 +15,4 @@
public int Quantity { get; set; }
public string PictureUrl { get; set; }
}
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class CatalogItem
{
public class CatalogItem
{
public int Id { get; set; }
public string Name { get; set; }
@ -10,6 +9,6 @@
public decimal Price { get; set; }
public string PictureUri { get; set; }
}
}

View File

@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
public class OrderData
{
public class OrderData
{
public string OrderNumber { get; set; }
public DateTime Date { get; set; }
@ -42,7 +38,6 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
public string Buyer { get; set; }
public List<OrderItemData> OrderItems { get; } = new List<OrderItemData>();
}
public List<OrderItemData> OrderItems { get; } = new();
}

View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class OrderItemData
{
public class OrderItemData
{
public int ProductId { get; set; }
public string ProductName { get; set; }
@ -14,6 +13,4 @@
public int Units { get; set; }
public string PictureUrl { get; set; }
}
}

View File

@ -1,16 +1,9 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class UpdateBasketItemData
{
public class UpdateBasketItemData
{
public string BasketItemId { get; set; }
public int NewQty { get; set; }
public UpdateBasketItemData()
{
NewQty = 0;
}
}
}

View File

@ -1,10 +1,7 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
public class UpdateBasketItemsRequest
{
public class UpdateBasketItemsRequest
{
public string BasketId { get; set; }
public ICollection<UpdateBasketItemData> Updates { get; set; }
@ -13,6 +10,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
{
Updates = new List<UpdateBasketItemData>();
}
}
}

View File

@ -1,13 +1,8 @@
using System.Collections.Generic;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
public class UpdateBasketRequest
{
public class UpdateBasketRequest
{
public string BuyerId { get; set; }
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; }
}
}

View File

@ -1,11 +1,10 @@
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
public class UpdateBasketRequestItemData
{
public class UpdateBasketRequestItemData
{
public string Id { get; set; } // Basket id
public int ProductId { get; set; } // Catalog item id
public int Quantity { get; set; } // Quantity
}
}

View File

@ -1,9 +1,4 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator;
using Serilog;
BuildWebHost(args).Run();
await BuildWebHost(args).RunAsync();
IWebHost BuildWebHost(string[] args) =>
WebHost

View File

@ -1,13 +1,7 @@
using GrpcBasket;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public class BasketService : IBasketService
{
public class BasketService : IBasketService
{
private readonly Basket.BasketClient _basketClient;
private readonly ILogger<BasketService> _logger;
@ -17,8 +11,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
_logger = logger;
}
public async Task<BasketData> GetById(string id)
public async Task<BasketData> GetByIdAsync(string id)
{
_logger.LogDebug("grpc client created, request = {@id}", id);
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
@ -99,5 +92,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
return map;
}
}
}

View File

@ -1,14 +1,7 @@
using CatalogApi;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public class CatalogService : ICatalogService
{
public class CatalogService : ICatalogService
{
private readonly Catalog.CatalogClient _client;
private readonly ILogger<CatalogService> _logger;
@ -48,5 +41,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
Price = (decimal)catalogItemResponse.Price
};
}
}
}

View File

@ -1,12 +1,8 @@
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public interface IBasketService
{
public interface IBasketService
{
Task<BasketData> GetById(string id);
Task<BasketData> GetByIdAsync(string id);
Task UpdateAsync(BasketData currentBasket);
}
}

View File

@ -1,13 +1,8 @@
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public interface ICatalogService
{
public interface ICatalogService
{
Task<CatalogItem> GetCatalogItemAsync(int id);
Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
}
}

View File

@ -1,10 +1,6 @@
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public interface IOrderApiClient
{
public interface IOrderApiClient
{
Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
}
}

View File

@ -1,10 +1,6 @@
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public interface IOrderingService
{
public interface IOrderingService
{
Task<OrderData> GetOrderDraftAsync(BasketData basketData);
}
}

View File

@ -1,15 +1,7 @@
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public class OrderApiClient : IOrderApiClient
{
public class OrderApiClient : IOrderApiClient
{
private readonly HttpClient _apiClient;
private readonly ILogger<OrderApiClient> _logger;
private readonly UrlsConfig _urls;
@ -23,7 +15,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)
{
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
var url = $"{_urls.Orders}{UrlsConfig.OrdersOperations.GetOrderDraft()}";
var content = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json");
var response = await _apiClient.PostAsync(url, content);
@ -36,5 +28,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
PropertyNameCaseInsensitive = true
});
}
}
}

View File

@ -1,13 +1,7 @@
using GrpcOrdering;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
public class OrderingService : IOrderingService
{
public class OrderingService : IOrderingService
{
private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
private readonly ILogger<OrderingService> _logger;
@ -75,5 +69,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services
return command;
}
}
}

View File

@ -1,32 +1,7 @@
using CatalogApi;
using Devspaces.Support;
using GrpcBasket;
using GrpcOrdering;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure;
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator;
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
public class Startup
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
@ -99,10 +74,10 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
});
});
}
}
}
public static class ServiceCollectionExtensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
@ -221,5 +196,4 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator
return services;
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>Web.Shopping.HttpAggregator</AssemblyName>
<RootNamespace>Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator</RootNamespace>
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
@ -29,7 +29,6 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0-dev-00834" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<!--<PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.6.0-rc1.19456.4" />-->
</ItemGroup>
<ItemGroup>

View File

@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@ -1,13 +1,7 @@
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Devspaces.Support;
namespace Devspaces.Support
public class DevspacesMessageHandler : DelegatingHandler
{
public class DevspacesMessageHandler : DelegatingHandler
{
private const string DevspacesHeaderName = "azds-route-as";
private readonly IHttpContextAccessor _httpContextAccessor;
public DevspacesMessageHandler(IHttpContextAccessor httpContextAccessor)
@ -25,5 +19,4 @@ namespace Devspaces.Support
}
return base.SendAsync(request, cancellationToken);
}
}
}

View File

@ -0,0 +1,6 @@
global using Microsoft.AspNetCore.Http;
global using Microsoft.Extensions.DependencyInjection;
global using System.Collections.Generic;
global using System.Net.Http;
global using System.Threading.Tasks;
global using System.Threading;

View File

@ -1,13 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
namespace Devspaces.Support;
namespace Devspaces.Support
public static class HttpClientBuilderDevspacesExtensions
{
public static class HttpClientBuilderDevspacesExtensions
{
public static IHttpClientBuilder AddDevspacesSupport(this IHttpClientBuilder builder)
{
builder.AddHttpMessageHandler<DevspacesMessageHandler>();
return builder;
}
}
}

View File

@ -1,13 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
namespace Devspaces.Support;
namespace Devspaces.Support
public static class ServiceCollectionDevspacesExtensions
{
public static class ServiceCollectionDevspacesExtensions
{
public static IServiceCollection AddDevspaces(this IServiceCollection services)
{
services.AddTransient<DevspacesMessageHandler>();
return services;
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -1,9 +1,6 @@
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
public interface IDynamicIntegrationEventHandler
{
public interface IDynamicIntegrationEventHandler
{
Task Handle(dynamic eventData);
}
}

View File

@ -1,9 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
public interface IEventBus
{
public interface IEventBus
{
void Publish(IntegrationEvent @event);
void Subscribe<T, TH>()
@ -19,5 +17,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
void Unsubscribe<T, TH>()
where TH : IIntegrationEventHandler<T>
where T : IntegrationEvent;
}
}

View File

@ -1,15 +1,11 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions
{
public interface IIntegrationEventHandler<in TIntegrationEvent> : IIntegrationEventHandler
public interface IIntegrationEventHandler<in TIntegrationEvent> : IIntegrationEventHandler
where TIntegrationEvent : IntegrationEvent
{
{
Task Handle(TIntegrationEvent @event);
}
public interface IIntegrationEventHandler
{
}
}
public interface IIntegrationEventHandler
{
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.EventBus</RootNamespace>
</PropertyGroup>

View File

@ -1,10 +1,7 @@
using System;
using System.Text.Json.Serialization;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events
public record IntegrationEvent
{
public record IntegrationEvent
{
public IntegrationEvent()
{
Id = Guid.NewGuid();
@ -23,5 +20,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events
[JsonInclude]
public DateTime CreationDate { get; private init; }
}
}

View File

@ -1,10 +1,7 @@
using System;
using System.Linq;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions
public static class GenericTypeExtensions
{
public static class GenericTypeExtensions
{
public static string GetGenericTypeName(this Type type)
{
var typeName = string.Empty;
@ -26,5 +23,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions
{
return @object.GetType().GetGenericTypeName();
}
}
}

View File

@ -0,0 +1,8 @@
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
global using static Microsoft.eShopOnContainers.BuildingBlocks.EventBus.InMemoryEventBusSubscriptionsManager;
global using System.Collections.Generic;
global using System.Linq;
global using System.Text.Json.Serialization;
global using System.Threading.Tasks;
global using System;

View File

@ -1,13 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using static Microsoft.eShopOnContainers.BuildingBlocks.EventBus.InMemoryEventBusSubscriptionsManager;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
public interface IEventBusSubscriptionsManager
{
public interface IEventBusSubscriptionsManager
{
bool IsEmpty { get; }
event EventHandler<string> OnEventRemoved;
void AddDynamicSubscription<TH>(string eventName)
@ -30,5 +24,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
IEnumerable<SubscriptionInfo> GetHandlersForEvent<T>() where T : IntegrationEvent;
IEnumerable<SubscriptionInfo> GetHandlersForEvent(string eventName);
string GetEventKey<T>();
}
}

View File

@ -1,13 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager
{
public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager
{
private readonly Dictionary<string, List<SubscriptionInfo>> _handlers;
@ -21,7 +15,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
_eventTypes = new List<Type>();
}
public bool IsEmpty => !_handlers.Keys.Any();
public bool IsEmpty => _handlers is { Count: 0 };
public void Clear() => _handlers.Clear();
public void AddDynamicSubscription<TH>(string eventName)
@ -158,5 +152,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
{
return typeof(T).Name;
}
}
}

View File

@ -1,9 +1,7 @@
using System;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager
{
public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager
{
public class SubscriptionInfo
{
public bool IsDynamic { get; }
@ -15,14 +13,10 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus
HandlerType = handlerType;
}
public static SubscriptionInfo Dynamic(Type handlerType)
{
return new SubscriptionInfo(true, handlerType);
}
public static SubscriptionInfo Typed(Type handlerType)
{
return new SubscriptionInfo(false, handlerType);
}
}
public static SubscriptionInfo Dynamic(Type handlerType) =>
new SubscriptionInfo(true, handlerType);
public static SubscriptionInfo Typed(Type handlerType) =>
new SubscriptionInfo(false, handlerType);
}
}

View File

@ -1,18 +1,8 @@
using Microsoft.Extensions.Logging;
using Polly;
using Polly.Retry;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using System;
using System.IO;
using System.Net.Sockets;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
{
public class DefaultRabbitMQPersistentConnection
public class DefaultRabbitMQPersistentConnection
: IRabbitMQPersistentConnection
{
{
private readonly IConnectionFactory _connectionFactory;
private readonly ILogger<DefaultRabbitMQPersistentConnection> _logger;
private readonly int _retryCount;
@ -54,6 +44,9 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
try
{
_connection.ConnectionShutdown -= OnConnectionShutdown;
_connection.CallbackException -= OnCallbackException;
_connection.ConnectionBlocked -= OnConnectionBlocked;
_connection.Dispose();
}
catch (IOException ex)
@ -127,5 +120,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
TryConnect();
}
}
}

View File

@ -1,24 +1,7 @@
using Autofac;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
using Microsoft.Extensions.Logging;
using Polly;
using Polly.Retry;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
public class EventBusRabbitMQ : IEventBus, IDisposable
{
public class EventBusRabbitMQ : IEventBus, IDisposable
{
const string BROKER_NAME = "eshop_event_bus";
const string AUTOFAC_SCOPE_NAME = "eshop_event_bus";
@ -293,5 +276,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
_logger.LogWarning("No subscription for RabbitMQ event: {EventName}", eventName);
}
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ</RootNamespace>
</PropertyGroup>

View File

@ -0,0 +1,17 @@
global using Microsoft.Extensions.Logging;
global using Polly;
global using Polly.Retry;
global using RabbitMQ.Client;
global using RabbitMQ.Client.Events;
global using RabbitMQ.Client.Exceptions;
global using System;
global using System.IO;
global using System.Net.Sockets;
global using Autofac;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
global using System.Text;
global using System.Threading.Tasks;
global using System.Text.Json;

View File

@ -1,15 +1,11 @@
using RabbitMQ.Client;
using System;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
{
public interface IRabbitMQPersistentConnection
public interface IRabbitMQPersistentConnection
: IDisposable
{
{
bool IsConnected { get; }
bool TryConnect();
IModel CreateModel();
}
}

View File

@ -1,11 +1,7 @@
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using System;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus
public class DefaultServiceBusPersisterConnection : IServiceBusPersisterConnection
{
public class DefaultServiceBusPersisterConnection : IServiceBusPersisterConnection
{
private readonly string _serviceBusConnectionString;
private ServiceBusClient _topicClient;
private ServiceBusAdministrationClient _subscriptionClient;
@ -56,5 +52,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus
_disposed = true;
_topicClient.DisposeAsync().GetAwaiter().GetResult();
}
}
}

View File

@ -1,19 +1,7 @@
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using Autofac;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.Extensions.Logging;
using System;
using System.Text.Json;
using System.Threading.Tasks;
using System.Text;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus
public class EventBusServiceBus : IEventBus, IDisposable
{
public class EventBusServiceBus : IEventBus, IDisposable
{
private readonly IServiceBusPersisterConnection _serviceBusPersisterConnection;
private readonly ILogger<EventBusServiceBus> _logger;
private readonly IEventBusSubscriptionsManager _subsManager;
@ -211,5 +199,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus
_logger.LogWarning("The messaging entity {DefaultRuleName} Could not be found.", RuleProperties.DefaultRuleName);
}
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus</RootNamespace>
</PropertyGroup>

View File

@ -0,0 +1,23 @@
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
global using static Microsoft.eShopOnContainers.BuildingBlocks.EventBus.InMemoryEventBusSubscriptionsManager;
global using System.Collections.Generic;
global using System.Linq;
global using System.Text.Json.Serialization;
global using System.Threading.Tasks;
global using System;
global using Autofac;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
global using Microsoft.Extensions.Logging;
global using System.Text;
global using System.Text.Json;
global using Azure.Messaging.ServiceBus;
global using Azure.Messaging.ServiceBus.Administration;
global using System;

View File

@ -1,12 +1,7 @@
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus
{
using System;
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus;
public interface IServiceBusPersisterConnection : IDisposable
{
public interface IServiceBusPersisterConnection : IDisposable
{
ServiceBusClient TopicClient { get; }
ServiceBusAdministrationClient AdministrationClient { get; }
}
}

View File

@ -1,10 +1,10 @@
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
public enum EventStateEnum
{
public enum EventStateEnum
{
NotPublished = 0,
InProgress = 1,
Published = 2,
PublishedFailed = 3
}
}

View File

@ -0,0 +1,12 @@
global using Microsoft.EntityFrameworkCore;
global using Microsoft.EntityFrameworkCore.Metadata.Builders;
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
global using System;
global using System.Text.Json;
global using System.ComponentModel.DataAnnotations.Schema;
global using System.Linq;
global using System.Threading.Tasks;
global using Microsoft.EntityFrameworkCore.Storage;
global using System.Collections.Generic;
global using System.Data.Common;
global using System.Reflection;

View File

@ -1,10 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
public class IntegrationEventLogContext : DbContext
{
public class IntegrationEventLogContext : DbContext
{
public IntegrationEventLogContext(DbContextOptions<IntegrationEventLogContext> options) : base(options)
{
}
@ -41,5 +38,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
.IsRequired();
}
}
}

View File

@ -1,18 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,13 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Text.Json;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
public class IntegrationEventLogEntry
{
public class IntegrationEventLogEntry
{
private IntegrationEventLogEntry() { }
public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId)
{
@ -39,5 +33,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
IntegrationEvent = JsonSerializer.Deserialize(Content, type, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }) as IntegrationEvent;
return this;
}
}
}

View File

@ -1,17 +1,10 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
public interface IIntegrationEventLogService
{
public interface IIntegrationEventLogService
{
Task<IEnumerable<IntegrationEventLogEntry>> RetrieveEventLogsPendingToPublishAsync(Guid transactionId);
Task SaveEventAsync(IntegrationEvent @event, IDbContextTransaction transaction);
Task MarkEventAsPublishedAsync(Guid eventId);
Task MarkEventAsInProgressAsync(Guid eventId);
Task MarkEventAsFailedAsync(Guid eventId);
}
}

View File

@ -1,21 +1,11 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
public class IntegrationEventLogService : IIntegrationEventLogService, IDisposable
{
public class IntegrationEventLogService : IIntegrationEventLogService, IDisposable
{
private readonly IntegrationEventLogContext _integrationEventLogContext;
private readonly DbConnection _dbConnection;
private readonly List<Type> _eventTypes;
private volatile bool disposedValue;
private volatile bool _disposedValue;
public IntegrationEventLogService(DbConnection dbConnection)
{
@ -89,7 +79,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
if (!_disposedValue)
{
if (disposing)
{
@ -97,7 +87,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
}
disposedValue = true;
_disposedValue = true;
}
}
@ -106,5 +96,4 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Servi
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

Some files were not shown because too many files have changed in this diff Show More