From e55ce11c4ee72256f8c7732221b502bc08959079 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 22 Mar 2022 01:40:36 +0300 Subject: [PATCH 1/6] Added yarp to shared gateway hosting --- .../EShopOnAbp.Shared.Hosting.Gateways.csproj | 1 + .../EShopOnAbpSharedHostingGatewaysModule.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj index 33dfe14e..6f653505 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj @@ -7,6 +7,7 @@ + diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs index 895cfabf..a28d8444 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs @@ -17,8 +17,8 @@ namespace EShopOnAbp.Shared.Hosting.Gateways { var configuration = context.Services.GetConfiguration(); - context.Services.AddOcelot(configuration) - .AddPolly(); + // context.Services.AddOcelot(configuration) + // .AddPolly(); } } } \ No newline at end of file From 0e73b9f16a3d2ecb8073d9e07eea58be298c4099 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Tue, 22 Mar 2022 01:40:59 +0300 Subject: [PATCH 2/6] added yarp to public-web gateway --- .../EShopOnAbpWebPublicGatewayModule.cs | 105 +++++++++++------- .../appsettings.json | 85 +++++++++++++- 2 files changed, 146 insertions(+), 44 deletions(-) diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs index a77e5660..00f4da4f 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs @@ -7,6 +7,7 @@ using Ocelot.Middleware; using System.Collections.Generic; using System.Linq; using EShopOnAbp.Shared.Hosting.AspNetCore; +using Microsoft.AspNetCore.Http; using Volo.Abp; using Volo.Abp.Modularity; using Microsoft.AspNetCore.Rewrite; @@ -23,21 +24,24 @@ public class EShopOnAbpWebPublicGatewayModule : AbpModule var configuration = context.Services.GetConfiguration(); var hostingEnvironment = context.Services.GetHostingEnvironment(); - SwaggerConfigurationHelper.ConfigureWithAuth( - context: context, - authority: configuration["AuthServer:Authority"], - scopes: new Dictionary /* Requested scopes for authorization code request and descriptions for swagger UI only */ - { - { "AccountService", "Account Service API" }, - { "IdentityService", "Identity Service API" }, - { "AdministrationService", "Administration Service API" }, - { "CatalogService", "Catalog Service API" }, - { "BasketService", "Basket Service API" }, - { "PaymentService", "Payment Service API" }, - { "OrderingService", "Ordering Service API" }, - }, - apiTitle: "WebPublic Gateway" - ); + // SwaggerConfigurationHelper.ConfigureWithAuth( + // context: context, + // authority: configuration["AuthServer:Authority"], + // scopes: new Dictionary /* Requested scopes for authorization code request and descriptions for swagger UI only */ + // { + // { "AccountService", "Account Service API" }, + // { "IdentityService", "Identity Service API" }, + // { "AdministrationService", "Administration Service API" }, + // { "CatalogService", "Catalog Service API" }, + // { "BasketService", "Basket Service API" }, + // { "PaymentService", "Payment Service API" }, + // { "OrderingService", "Ordering Service API" }, + // }, + // apiTitle: "WebPublic Gateway" + // ); + + context.Services.AddReverseProxy() + .LoadFromConfig(configuration.GetSection("ReverseProxy")); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -52,35 +56,50 @@ public class EShopOnAbpWebPublicGatewayModule : AbpModule app.UseCorrelationId(); app.UseAbpSerilogEnrichers(); - app.UseSwagger(); - app.UseSwaggerUI(options => + // app.UseSwagger(); + // app.UseSwaggerUI(options => + // { + // var configuration = context.ServiceProvider.GetRequiredService(); + // var routes = configuration.GetSection("Routes").Get>(); + // var routedServices = routes + // .GroupBy(t => t.ServiceKey) + // .Select(r => r.First()) + // .Distinct(); + // + // foreach (var config in routedServices) + // { + // var url = + // $"{config.DownstreamScheme}://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}:{config.DownstreamHostAndPorts.FirstOrDefault()?.Port}"; + // if (!env.IsDevelopment()) + // { + // url = $"https://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}"; + // } + // + // options.SwaggerEndpoint($"{url}/swagger/v1/swagger.json", $"{config.ServiceKey} API"); + // options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + // options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); + // } + // }); + // + // app.UseRewriter(new RewriteOptions() + // // Regex for "", "/" and "" (whitespace) + // .AddRedirect("^(|\\|\\s+)$", "/swagger")); + // + // app.UseOcelot().Wait(); + // app.MapWhen( + // ctx => ctx.Request.Path.ToString().TrimEnd('/').Equals(""), + // app2 => + // { + // app2.UseRouting(); + // // app2.UseConfiguredEndpoints(); + // app2.UseEndpoints(endpoints => endpoints.MapReverseProxy()); + // } + // ); + app.UseRouting(); + app.UseEndpoints(endpoints => { - var configuration = context.ServiceProvider.GetRequiredService(); - var routes = configuration.GetSection("Routes").Get>(); - var routedServices = routes - .GroupBy(t => t.ServiceKey) - .Select(r => r.First()) - .Distinct(); - - foreach (var config in routedServices) - { - var url = - $"{config.DownstreamScheme}://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}:{config.DownstreamHostAndPorts.FirstOrDefault()?.Port}"; - if (!env.IsDevelopment()) - { - url = $"https://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}"; - } - - options.SwaggerEndpoint($"{url}/swagger/v1/swagger.json", $"{config.ServiceKey} API"); - options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); - options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); - } + endpoints.MapGet("", ctx => ctx.Response.WriteAsync("YAG")); + endpoints.MapReverseProxy(); }); - - app.UseRewriter(new RewriteOptions() - // Regex for "", "/" and "" (whitespace) - .AddRedirect("^(|\\|\\s+)$", "/swagger")); - - app.UseOcelot().Wait(); } } \ No newline at end of file diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json index dfe10330..924dbd44 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json @@ -17,11 +17,94 @@ } }, "AllowedHosts": "*", - "Redis": { "Configuration": "localhost:6379" }, "ElasticSearch": { "Url": "http://localhost:9200" + }, + "ReverseProxy": { + "Routes": { + "account-route": { + "ClusterId": "account-cluster", + "Match": { + "Path": "/api/account/{**everything}" + } + }, + "administration-route": { + "ClusterId": "administration-cluster", + "Match": { + "Path": "/api/abp/{**everything}" + } + }, + "catalog-route": { + "ClusterId": "catalog-cluster", + "Match": { + "Path": "/api/catalog/{**everything}" + } + }, + "basket-route": { + "ClusterId": "basket-cluster", + "Match": { + "Path": "/api/basket/{**everything}" + } + }, + "ordering-route": { + "ClusterId": "ordering-cluster", + "Match": { + "Path": "/api/ordering/{**everything}" + } + }, + "payment-route": { + "ClusterId": "payment-cluster", + "Match": { + "Path": "/api/payment/{**everything}" + } + } + }, + "Clusters": { + "account-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44330" + } + } + }, + "administration-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + }, + "catalog-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44354" + } + } + }, + "basket-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44355" + } + } + }, + "ordering-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44356" + } + } + }, + "payment-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44357" + } + } + } + } } } From 4bbc6e4a4384ffc239d74ae29d51ece51edfd4e4 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 23 Mar 2022 21:35:49 +0300 Subject: [PATCH 3/6] removed ocelot configurations and dependency --- .../EShopOnAbp.WebPublicGateway/ocelot.json | 113 ------------------ .../web/src/EShopOnAbp.WebGateway/ocelot.json | 90 -------------- .../EShopOnAbp.Shared.Hosting.Gateways.csproj | 6 - .../OcelotConfiguration.cs | 20 ---- 4 files changed, 229 deletions(-) delete mode 100644 gateways/web-public/src/EShopOnAbp.WebPublicGateway/ocelot.json delete mode 100644 gateways/web/src/EShopOnAbp.WebGateway/ocelot.json delete mode 100644 shared/EShopOnAbp.Shared.Hosting.Gateways/OcelotConfiguration.cs diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/ocelot.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/ocelot.json deleted file mode 100644 index a436b432..00000000 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/ocelot.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "GlobalConfiguration": { - "BaseUrl": "https://localhost:44373" - }, - "Routes": [ - { - "ServiceKey": "Account Service", - "DownstreamPathTemplate": "/api/account/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44330 - } - ], - "UpstreamPathTemplate": "/api/account/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Administration Service", - "DownstreamPathTemplate": "/api/abp/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44353 - } - ], - "UpstreamPathTemplate": "/api/abp/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ], - "QoSOptions": { - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 3000, - "TimeoutValue": 2500 - } - }, - { - "ServiceKey": "Catalog Service", - "DownstreamPathTemplate": "/api/catalog/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44354 - } - ], - "UpstreamPathTemplate": "/api/catalog/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ], - "QoSOptions": { - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 3000, - "TimeoutValue": 2500 - } - }, - { - "ServiceKey": "Catalog Service", - "DownstreamPathTemplate": "/product-images/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44354 - } - ], - "UpstreamPathTemplate": "/product-images/{everything}", - "UpstreamHttpMethod": [ "Get" ] - }, - { - "ServiceKey": "Basket Service", - "DownstreamPathTemplate": "/api/basket/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44355 - } - ], - "UpstreamPathTemplate": "/api/basket/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ], - "QoSOptions": { - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 3000, - "TimeoutValue": 2500 - } - }, - { - "ServiceKey": "Ordering Service", - "DownstreamPathTemplate": "/api/ordering/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44356 - } - ], - "UpstreamPathTemplate": "/api/ordering/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Payment Service", - "DownstreamPathTemplate": "/api/payment/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44357 - } - ], - "UpstreamPathTemplate": "/api/payment/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - } - ] -} \ No newline at end of file diff --git a/gateways/web/src/EShopOnAbp.WebGateway/ocelot.json b/gateways/web/src/EShopOnAbp.WebGateway/ocelot.json deleted file mode 100644 index affe35be..00000000 --- a/gateways/web/src/EShopOnAbp.WebGateway/ocelot.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "GlobalConfiguration": { - "BaseUrl": "https://localhost:44372" - }, - "Routes": [ - { - "ServiceKey": "Identity Service", - "DownstreamPathTemplate": "/api/identity/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44351 - } - ], - "UpstreamPathTemplate": "/api/identity/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Account Service", - "DownstreamPathTemplate": "/api/account/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44330 - } - ], - "UpstreamPathTemplate": "/api/account/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Administration Service", - "DownstreamPathTemplate": "/api/abp/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44353 - } - ], - "UpstreamPathTemplate": "/api/abp/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ], - "QoSOptions": { - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 5000, - "TimeoutValue": 2500 - } - }, - { - "ServiceKey": "Administration Service", - "DownstreamPathTemplate": "/api/feature-management/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44353 - } - ], - "UpstreamPathTemplate": "/api/feature-management/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Administration Service", - "DownstreamPathTemplate": "/api/permission-management/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44353 - } - ], - "UpstreamPathTemplate": "/api/permission-management/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - }, - { - "ServiceKey": "Administration Service", - "DownstreamPathTemplate": "/api/setting-management/{everything}", - "DownstreamScheme": "https", - "DownstreamHostAndPorts": [ - { - "Host": "localhost", - "Port": 44353 - } - ], - "UpstreamPathTemplate": "/api/setting-management/{everything}", - "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] - } - ] -} \ No newline at end of file diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj index 6f653505..c6e72cb3 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbp.Shared.Hosting.Gateways.csproj @@ -5,15 +5,9 @@ - - - - - - diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/OcelotConfiguration.cs b/shared/EShopOnAbp.Shared.Hosting.Gateways/OcelotConfiguration.cs deleted file mode 100644 index 288b697e..00000000 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/OcelotConfiguration.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; - -namespace EShopOnAbp.Shared.Hosting.Gateways -{ - public class OcelotConfiguration - { - public string ServiceKey { get; set; } - public string DownstreamPathTemplate { get; set; } - public string DownstreamScheme { get; set; } - public string UpstreamPathTemplate { get; set; } - public List UpstreamHttpMethod { get; set; } - public List DownstreamHostAndPorts { get; set; } - } - - public class HostAndPort - { - public string Host { get; set; } - public int Port { get; set; } - } -} \ No newline at end of file From 1d33884d0f95265a743525b742c0584af9bdd3ae Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 23 Mar 2022 21:37:43 +0300 Subject: [PATCH 4/6] moved yarp configuration to explicit yarp file for easier overriding at deployment --- .../appsettings.json | 84 --------------- .../src/EShopOnAbp.WebPublicGateway/yarp.json | 100 ++++++++++++++++++ .../web/src/EShopOnAbp.WebGateway/yarp.json | 86 +++++++++++++++ 3 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 gateways/web-public/src/EShopOnAbp.WebPublicGateway/yarp.json create mode 100644 gateways/web/src/EShopOnAbp.WebGateway/yarp.json diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json index 924dbd44..f1417cac 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json @@ -22,89 +22,5 @@ }, "ElasticSearch": { "Url": "http://localhost:9200" - }, - "ReverseProxy": { - "Routes": { - "account-route": { - "ClusterId": "account-cluster", - "Match": { - "Path": "/api/account/{**everything}" - } - }, - "administration-route": { - "ClusterId": "administration-cluster", - "Match": { - "Path": "/api/abp/{**everything}" - } - }, - "catalog-route": { - "ClusterId": "catalog-cluster", - "Match": { - "Path": "/api/catalog/{**everything}" - } - }, - "basket-route": { - "ClusterId": "basket-cluster", - "Match": { - "Path": "/api/basket/{**everything}" - } - }, - "ordering-route": { - "ClusterId": "ordering-cluster", - "Match": { - "Path": "/api/ordering/{**everything}" - } - }, - "payment-route": { - "ClusterId": "payment-cluster", - "Match": { - "Path": "/api/payment/{**everything}" - } - } - }, - "Clusters": { - "account-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44330" - } - } - }, - "administration-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44353" - } - } - }, - "catalog-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44354" - } - } - }, - "basket-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44355" - } - } - }, - "ordering-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44356" - } - } - }, - "payment-cluster": { - "Destinations": { - "destination1": { - "Address": "https://localhost:44357" - } - } - } - } } } diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/yarp.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/yarp.json new file mode 100644 index 00000000..7e3b617a --- /dev/null +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/yarp.json @@ -0,0 +1,100 @@ +{ + "ReverseProxy": { + "Routes": { + "Account Service": { + "ClusterId": "account-cluster", + "Match": { + "Path": "/api/account/{**everything}" + } + }, + "Administration Service": { + "ClusterId": "administration-cluster", + "Match": { + "Path": "/api/abp/{**everything}" + } + }, + "Catalog Service": { + "ClusterId": "catalog-cluster", + "Match": { + "Path": "/api/catalog/{**everything}" + } + }, + "Basket Service": { + "ClusterId": "basket-cluster", + "Match": { + "Path": "/api/basket/{**everything}" + } + }, + "Ordering Service": { + "ClusterId": "ordering-cluster", + "Match": { + "Path": "/api/ordering/{**everything}" + } + }, + "Payment Service": { + "ClusterId": "payment-cluster", + "Match": { + "Path": "/api/payment/{**everything}" + } + }, + "product-picture-route": { + "ClusterId": "product-picture-cluster", + "Match": { + "Path": "/product-images/{**everything}", + "Methods" : [ "GET" ] + } + } + }, + "Clusters": { + "account-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44330" + } + } + }, + "administration-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + }, + "catalog-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44354" + } + } + }, + "product-picture-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44354" + } + } + }, + "basket-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44355" + } + } + }, + "ordering-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44356" + } + } + }, + "payment-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44357" + } + } + } + } + } +} \ No newline at end of file diff --git a/gateways/web/src/EShopOnAbp.WebGateway/yarp.json b/gateways/web/src/EShopOnAbp.WebGateway/yarp.json new file mode 100644 index 00000000..424e598e --- /dev/null +++ b/gateways/web/src/EShopOnAbp.WebGateway/yarp.json @@ -0,0 +1,86 @@ +{ + "ReverseProxy": { + "Routes": { + "Account Service": { + "ClusterId": "account-cluster", + "Match": { + "Path": "/api/account/{**everything}" + } + }, + "Identity Service": { + "ClusterId": "identity-cluster", + "Match": { + "Path": "/api/identity/{**everything}" + } + }, + "Administration Service": { + "ClusterId": "administration-cluster", + "Match": { + "Path": "/api/abp/{**everything}" + } + }, + "feature-management-route": { + "ClusterId": "feature-management-cluster", + "Match": { + "Path": "/api/feature-management/{**everything}" + } + }, + "permission-management-route": { + "ClusterId": "permission-management-cluster", + "Match": { + "Path": "/api/permission-management/{**everything}" + } + }, + "setting-management-route": { + "ClusterId": "setting-management-cluster", + "Match": { + "Path": "/api/setting-management/{**everything}" + } + } + }, + "Clusters": { + "account-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44330" + } + } + }, + "identity-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44351" + } + } + }, + "administration-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + }, + "feature-management-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + }, + "permission-management-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + }, + "setting-management-cluster": { + "Destinations": { + "destination1": { + "Address": "https://localhost:44353" + } + } + } + } + } +} \ No newline at end of file From e4f144af09faf84be6669e1214921ed61f8533b9 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 23 Mar 2022 21:38:04 +0300 Subject: [PATCH 5/6] Added yarp configuration and builder extensions --- .../EShopOnAbpSharedHostingGatewaysModule.cs | 12 ++--- .../GatewayHostBuilderExtensions.cs | 6 +-- .../YarpSwaggerUIBuilderExtensions.cs | 52 +++++++++++++++++++ 3 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 shared/EShopOnAbp.Shared.Hosting.Gateways/YarpSwaggerUIBuilderExtensions.cs diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs index a28d8444..11c1d509 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/EShopOnAbpSharedHostingGatewaysModule.cs @@ -1,24 +1,20 @@ using EShopOnAbp.Shared.Hosting.AspNetCore; using Microsoft.Extensions.DependencyInjection; -using Ocelot.DependencyInjection; -using Ocelot.Provider.Polly; -using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; using Volo.Abp.Modularity; namespace EShopOnAbp.Shared.Hosting.Gateways { [DependsOn( - typeof(EShopOnAbpSharedHostingAspNetCoreModule), - typeof(AbpAspNetCoreMvcUiMultiTenancyModule) + typeof(EShopOnAbpSharedHostingAspNetCoreModule) )] public class EShopOnAbpSharedHostingGatewaysModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - - // context.Services.AddOcelot(configuration) - // .AddPolly(); + + context.Services.AddReverseProxy() + .LoadFromConfig(configuration.GetSection("ReverseProxy")); } } } \ No newline at end of file diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/GatewayHostBuilderExtensions.cs b/shared/EShopOnAbp.Shared.Hosting.Gateways/GatewayHostBuilderExtensions.cs index b53c608f..a2663f9a 100644 --- a/shared/EShopOnAbp.Shared.Hosting.Gateways/GatewayHostBuilderExtensions.cs +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/GatewayHostBuilderExtensions.cs @@ -4,18 +4,18 @@ namespace Microsoft.Extensions.Hosting; public static class AbpHostingHostBuilderExtensions { - public const string AppOcelotJsonPath = "ocelot.json"; + public const string AppYarpJsonPath = "yarp.json"; public static IHostBuilder AddOcelotJson( this IHostBuilder hostBuilder, bool optional = true, bool reloadOnChange = true, - string path = AppOcelotJsonPath) + string path = AppYarpJsonPath) { return hostBuilder.ConfigureAppConfiguration((_, builder) => { builder.AddJsonFile( - path: AppOcelotJsonPath, + path: AppYarpJsonPath, optional: optional, reloadOnChange: reloadOnChange ); diff --git a/shared/EShopOnAbp.Shared.Hosting.Gateways/YarpSwaggerUIBuilderExtensions.cs b/shared/EShopOnAbp.Shared.Hosting.Gateways/YarpSwaggerUIBuilderExtensions.cs new file mode 100644 index 00000000..7a8cb5e0 --- /dev/null +++ b/shared/EShopOnAbp.Shared.Hosting.Gateways/YarpSwaggerUIBuilderExtensions.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Volo.Abp; +using Yarp.ReverseProxy.Configuration; + +namespace EShopOnAbp.Shared.Hosting.Gateways; + +public static class YarpSwaggerUIBuilderExtensions +{ + public static IApplicationBuilder ConfigureSwaggerUIWithYarp(this IApplicationBuilder app, + ApplicationInitializationContext context) + { + app.UseSwagger(); + app.UseSwaggerUI(options => + { + var configuration = context.ServiceProvider.GetRequiredService(); + var logger = context.ServiceProvider.GetRequiredService>(); + var proxyConfigProvider = context.ServiceProvider.GetRequiredService(); + var yarpConfig = proxyConfigProvider.GetConfig(); + + var routedClusters = yarpConfig.Clusters + .SelectMany(t => t.Destinations, + (clusterId, destination) => new {clusterId.ClusterId, destination.Value}); + + var groupedClusters = routedClusters + .GroupBy(q => q.Value.Address) + .Select(t => t.First()) + .Distinct() + .ToList(); + + foreach (var clusterGroup in groupedClusters) + { + var routeConfig = yarpConfig.Routes.FirstOrDefault(q => + q.ClusterId == clusterGroup.ClusterId); + if (routeConfig == null) + { + logger.LogWarning($"Swagger UI: Couldn't find route configuration for {clusterGroup.ClusterId}..."); + continue; + } + + options.SwaggerEndpoint($"{clusterGroup.Value.Address}/swagger/v1/swagger.json", $"{routeConfig.RouteId} API"); + options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); + } + }); + + return app; + } +} \ No newline at end of file From 679d04d2636d7277d9766b9ed6990500b4941f7d Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Wed, 23 Mar 2022 21:38:13 +0300 Subject: [PATCH 6/6] updated gateways --- .../EShopOnAbpWebPublicGatewayModule.cs | 82 ++++++------------- .../EShopOnAbpWebGatewayModule.cs | 29 +------ 2 files changed, 25 insertions(+), 86 deletions(-) diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs index 00f4da4f..6609c638 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/EShopOnAbpWebPublicGatewayModule.cs @@ -1,11 +1,8 @@ using EShopOnAbp.Shared.Hosting.Gateways; using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Ocelot.Middleware; using System.Collections.Generic; -using System.Linq; using EShopOnAbp.Shared.Hosting.AspNetCore; using Microsoft.AspNetCore.Http; using Volo.Abp; @@ -24,24 +21,24 @@ public class EShopOnAbpWebPublicGatewayModule : AbpModule var configuration = context.Services.GetConfiguration(); var hostingEnvironment = context.Services.GetHostingEnvironment(); - // SwaggerConfigurationHelper.ConfigureWithAuth( - // context: context, - // authority: configuration["AuthServer:Authority"], - // scopes: new Dictionary /* Requested scopes for authorization code request and descriptions for swagger UI only */ - // { - // { "AccountService", "Account Service API" }, - // { "IdentityService", "Identity Service API" }, - // { "AdministrationService", "Administration Service API" }, - // { "CatalogService", "Catalog Service API" }, - // { "BasketService", "Basket Service API" }, - // { "PaymentService", "Payment Service API" }, - // { "OrderingService", "Ordering Service API" }, - // }, - // apiTitle: "WebPublic Gateway" - // ); + SwaggerConfigurationHelper.ConfigureWithAuth( + context: context, + authority: configuration["AuthServer:Authority"], + scopes: new Dictionary /* Requested scopes for authorization code request and descriptions for swagger UI only */ + { + { "AccountService", "Account Service API" }, + { "IdentityService", "Identity Service API" }, + { "AdministrationService", "Administration Service API" }, + { "CatalogService", "Catalog Service API" }, + { "BasketService", "Basket Service API" }, + { "PaymentService", "Payment Service API" }, + { "OrderingService", "Ordering Service API" }, + }, + apiTitle: "WebPublic Gateway" + ); - context.Services.AddReverseProxy() - .LoadFromConfig(configuration.GetSection("ReverseProxy")); + // context.Services.AddReverseProxy() + // .LoadFromConfig(configuration.GetSection("ReverseProxy")); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -56,45 +53,12 @@ public class EShopOnAbpWebPublicGatewayModule : AbpModule app.UseCorrelationId(); app.UseAbpSerilogEnrichers(); - // app.UseSwagger(); - // app.UseSwaggerUI(options => - // { - // var configuration = context.ServiceProvider.GetRequiredService(); - // var routes = configuration.GetSection("Routes").Get>(); - // var routedServices = routes - // .GroupBy(t => t.ServiceKey) - // .Select(r => r.First()) - // .Distinct(); - // - // foreach (var config in routedServices) - // { - // var url = - // $"{config.DownstreamScheme}://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}:{config.DownstreamHostAndPorts.FirstOrDefault()?.Port}"; - // if (!env.IsDevelopment()) - // { - // url = $"https://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}"; - // } - // - // options.SwaggerEndpoint($"{url}/swagger/v1/swagger.json", $"{config.ServiceKey} API"); - // options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); - // options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); - // } - // }); - // - // app.UseRewriter(new RewriteOptions() - // // Regex for "", "/" and "" (whitespace) - // .AddRedirect("^(|\\|\\s+)$", "/swagger")); - // - // app.UseOcelot().Wait(); - // app.MapWhen( - // ctx => ctx.Request.Path.ToString().TrimEnd('/').Equals(""), - // app2 => - // { - // app2.UseRouting(); - // // app2.UseConfiguredEndpoints(); - // app2.UseEndpoints(endpoints => endpoints.MapReverseProxy()); - // } - // ); + app.ConfigureSwaggerUIWithYarp(context); + + app.UseRewriter(new RewriteOptions() + // Regex for "", "/" and "" (whitespace) + .AddRedirect("^(|\\|\\s+)$", "/swagger")); + app.UseRouting(); app.UseEndpoints(endpoints => { diff --git a/gateways/web/src/EShopOnAbp.WebGateway/EShopOnAbpWebGatewayModule.cs b/gateways/web/src/EShopOnAbp.WebGateway/EShopOnAbpWebGatewayModule.cs index 232fafb2..ae4cb249 100644 --- a/gateways/web/src/EShopOnAbp.WebGateway/EShopOnAbpWebGatewayModule.cs +++ b/gateways/web/src/EShopOnAbp.WebGateway/EShopOnAbpWebGatewayModule.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Cors; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Ocelot.Middleware; using System; using System.Collections.Generic; using System.Linq; @@ -71,39 +70,15 @@ public class EShopOnAbpWebGatewayModule : AbpModule { app.UseDeveloperExceptionPage(); } - app.UseCorrelationId(); app.UseAbpSerilogEnrichers(); app.UseCors(); - app.UseSwagger(); - app.UseSwaggerUI(options => - { - var configuration = context.ServiceProvider.GetRequiredService(); - var routes = configuration.GetSection("Routes").Get>(); - var routedServices = routes - .GroupBy(t => t.ServiceKey) - .Select(r => r.First()) - .Distinct(); - - foreach (var config in routedServices) - { - var url = - $"{config.DownstreamScheme}://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}:{config.DownstreamHostAndPorts.FirstOrDefault()?.Port}"; - if (!env.IsDevelopment()) - { - url = $"https://{config.DownstreamHostAndPorts.FirstOrDefault()?.Host}"; - } - - options.SwaggerEndpoint($"{url}/swagger/v1/swagger.json", $"{config.ServiceKey} API"); - options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); - options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); - } - }); + app.ConfigureSwaggerUIWithYarp(context); app.UseRewriter(new RewriteOptions() // Regex for "", "/" and "" (whitespace) .AddRedirect("^(|\\|\\s+)$", "/swagger")); - app.UseOcelot().Wait(); + // app.UseOcelot().Wait(); } } \ No newline at end of file