From 762c0880f0ba351cadaff820a1173ffc2732b258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Mon, 18 May 2020 23:48:40 +0200 Subject: [PATCH 01/18] * Fix in the paths when swagger servers are overwriten, it is optional to use --- demo/ApiGateway/Startup.cs | 1 + .../SwaggerForOcelotUIOptions.cs | 5 ++++ .../Middleware/SwaggerForOcelotMiddleware.cs | 2 +- .../Transformation/ISwaggerJsonTransformer.cs | 2 +- .../Transformation/SwaggerJsonTransformer.cs | 26 ++++++++++++------- .../SwaggerForOcelotMiddlewareShould.cs | 7 +++-- .../SwaggerForOcelotShould.cs | 5 ++-- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/demo/ApiGateway/Startup.cs b/demo/ApiGateway/Startup.cs index 79705f9..d025a14 100644 --- a/demo/ApiGateway/Startup.cs +++ b/demo/ApiGateway/Startup.cs @@ -59,6 +59,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) new KeyValuePair("Key", "Value"), new KeyValuePair("Key2", "Value2"), }; + opt.UseServerSwagger = false; }) .UseOcelot() .Wait(); diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs index 90da4f3..70fd3d1 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs @@ -36,5 +36,10 @@ public class SwaggerForOcelotUIOptions : SwaggerUIOptions /// Alter swagger/openApi json after it has been transformed /// public Func> ReConfigureUpstreamSwaggerJsonAsync { get; set; } + + /// + /// Configure if use Server of swagger or not + /// + public bool UseServerSwagger { get; set; } = true; } } diff --git a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs index 23501fa..132b26a 100644 --- a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs +++ b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs @@ -74,7 +74,7 @@ public async Task Invoke(HttpContext context, ISwaggerServiceDiscoveryProvider d if (EndPoint.TransformByOcelotConfig) { - content = _transformer.Transform(content, reRouteOptions, hostName); + content = _transformer.Transform(content, reRouteOptions, _options.UseServerSwagger, hostName); } content = await ReconfigureUpstreamSwagger(context, content); diff --git a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs index 9375ce9..8652ba3 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs @@ -17,6 +17,6 @@ public interface ISwaggerJsonTransformer /// /// Transformed swagger json. /// - string Transform(string swaggerJson, IEnumerable reRoutes, string hostOverride); + string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride); } } diff --git a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs index c93e6cd..10ccd41 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs @@ -1,4 +1,4 @@ -using Kros.IO; +using Kros.IO; using MMLib.SwaggerForOcelot.Configuration; using Newtonsoft.Json.Linq; using System; @@ -15,7 +15,7 @@ namespace MMLib.SwaggerForOcelot.Transformation public class SwaggerJsonTransformer : ISwaggerJsonTransformer { /// - public string Transform(string swaggerJson, IEnumerable reRoutes, string hostOverride) + public string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride) { var swagger = JObject.Parse(swaggerJson); @@ -26,7 +26,7 @@ public string Transform(string swaggerJson, IEnumerable reRoutes if (swagger.ContainsKey("openapi")) { - return TransformOpenApi(swagger, reRoutes, hostOverride); + return TransformOpenApi(swagger, reRoutes, useServer, hostOverride); } throw new InvalidOperationException("Unknown swagger/openapi version"); @@ -73,7 +73,7 @@ private string TransformSwagger(JObject swagger, IEnumerable reR return swagger.ToString(Formatting.Indented); } - private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, string hostOverride = "/") + private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, bool useServer, string hostOverride = "/") { // NOTE: Only supporting one server for now. string downstreamBasePath = ""; @@ -110,7 +110,7 @@ private string TransformOpenApi(JObject openApi, IEnumerable reR } } - TransformServerPaths(openApi, hostOverride); + TransformServerPaths(openApi, useServer, hostOverride); return openApi.ToString(Formatting.Indented); } @@ -252,18 +252,24 @@ private static void RenameToken(JProperty property, string newName) property.Replace(newProperty); } - private static void TransformServerPaths(JObject openApi, string hostOverride) + private static void TransformServerPaths(JObject openApi, bool userServer, string hostOverride) { if (!openApi.ContainsKey(OpenApiProperties.Servers)) { return; } - - foreach (JToken server in openApi.GetValue(OpenApiProperties.Servers)) + else if (!userServer) + { + openApi.Remove(OpenApiProperties.Servers); + } + else { - if (server[OpenApiProperties.Url] != null) + foreach (JToken server in openApi.GetValue(OpenApiProperties.Servers)) { - server[OpenApiProperties.Url] = hostOverride.RemoveSlashFromEnd(); + if (server[OpenApiProperties.Url] != null) + { + server[OpenApiProperties.Url] = hostOverride.RemoveSlashFromEnd(); + } } } } diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs index 7b6cb0a..df6a44b 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs @@ -73,12 +73,14 @@ public async Task AllowVersionPlaceholder() .Setup(x => x.Transform( It.IsAny(), It.IsAny>(), + It.IsAny(), It.IsAny())) .Returns(( string swaggerJson, IEnumerable reRouteOptions, + bool userServer, string hostOverride) => new SwaggerJsonTransformer() - .Transform(swaggerJson,reRouteOptions,hostOverride)); + .Transform(swaggerJson,reRouteOptions, userServer, hostOverride)); var swaggerForOcelotMiddleware = new SwaggerForOcelotMiddleware( next.Invoke, swaggerForOcelotOptions, @@ -100,6 +102,7 @@ public async Task AllowVersionPlaceholder() swaggerJsonTransformerMock.Verify(x => x.Transform( It.IsAny(), It.IsAny>(), + It.IsAny(), It.IsAny()), Times.Once); } @@ -320,7 +323,7 @@ public TestSwaggerJsonTransformer(string transformedJson) _transformedJson = transformedJson; } - public string Transform(string swaggerJson, IEnumerable reRoutes, string hostOverride) + public string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride) { return _transformedJson; } diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs index 97b3207..4885d37 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs @@ -1,4 +1,4 @@ -using System; +using System; using JsonDiffPatchDotNet; using MMLib.SwaggerForOcelot.Transformation; using Newtonsoft.Json.Linq; @@ -22,6 +22,7 @@ public void TransferDownstreamSwaggerToUpstreamFormat(TestCase testData) string transformed = transformer.Transform( testData.DownstreamSwagger.ToString(), testData.ReRoutes, + true, testData.HostOverride); AreEqual(transformed, testData.ExpectedTransformedSwagger); @@ -41,4 +42,4 @@ private static void AreEqual(string transformed, JObject expected) } } } -} \ No newline at end of file +} From a624c20ad369f3f7f9c4ce9f4a268bb6926c6952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 19 May 2020 10:56:52 +0200 Subject: [PATCH 02/18] * added Server of swagger for configuration --- demo/ApiGateway/Startup.cs | 3 +- demo/ApiGateway/ocelot.json | 115 +++--------------- .../SwaggerForOcelotUIOptions.cs | 2 +- .../Middleware/SwaggerForOcelotMiddleware.cs | 9 +- .../Transformation/ISwaggerJsonTransformer.cs | 4 +- .../Transformation/SwaggerJsonTransformer.cs | 26 ++-- .../SwaggerForOcelotMiddlewareShould.cs | 9 +- .../SwaggerForOcelotShould.cs | 1 - 8 files changed, 39 insertions(+), 130 deletions(-) diff --git a/demo/ApiGateway/Startup.cs b/demo/ApiGateway/Startup.cs index d025a14..31958eb 100644 --- a/demo/ApiGateway/Startup.cs +++ b/demo/ApiGateway/Startup.cs @@ -59,7 +59,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) new KeyValuePair("Key", "Value"), new KeyValuePair("Key2", "Value2"), }; - opt.UseServerSwagger = false; + + opt.ServerOcelot = "/siteName/apigateway" ; }) .UseOcelot() .Wait(); diff --git a/demo/ApiGateway/ocelot.json b/demo/ApiGateway/ocelot.json index 32e42a2..9cb4030 100644 --- a/demo/ApiGateway/ocelot.json +++ b/demo/ApiGateway/ocelot.json @@ -1,116 +1,29 @@ { "ReRoutes": [ { - "DownstreamPathTemplate": "/api/{everything}", - "ServiceName": "contacts", - "UpstreamPathTemplate": "/api/contacts/{everything}", - "UpstreamHttpMethod": [ "Get" ], - "SwaggerKey": "contacts" - }, - { - "DownstreamPathTemplate": "/api/{everything}", - "ServiceName": "projects", - "UpstreamPathTemplate": "/api/projects/{everything}", - "SwaggerKey": "projects" - }, - { - "DownstreamPathTemplate": "/{everything}", - "ServiceName": "pets", - "UpstreamHttpMethod": [ "Get", "Post" ], - "UpstreamPathTemplate": "/api/pets/{everything}", - "SwaggerKey": "pets" - }, - { - "DownstreamPathTemplate": "/api/{everything}", + "DownstreamPathTemplate": "/satcen/apitsr/{everything}", "DownstreamScheme": "http", - "ServiceName": "orders", - "UpstreamPathTemplate": "/api/orders/{everything}", - "UpstreamHttpMethod": [], - "SwaggerKey": "orders" + "DownstreamHostAndPorts": [ + { + "Host": "172.30.9.200", + "Port": 8080 + } + ], + "UpstreamPathTemplate": "/api/request/{everything}", + "DangerousAcceptAnyServerCertificateValidator": true, + "SwaggerKey": "request" } ], "SwaggerEndPoints": [ { - "Key": "contacts", - "Config": [ - { - "Name": "Contacts API", - "Version": "v1", - "Service": { - "Name": "contacts", - "Path": "/swagger/v1/swagger.json" - } - } - ] - }, - { - "Key": "gateway", - "TransformByOcelotConfig": false, - "Config": [ - { - "Name": "Gateway", - "Version": "v1", - "Url": "http://localhost:5000/swagger/v1/swagger.json" - } - ] - }, - { - "Key": "projects", + "Key": "request", "Config": [ { - "Name": "Projects API", + "Name": "ApiIngestTSR API", "Version": "v1", - "Service": { - "Name": "projects", - "Path": "/swagger/v1/swagger.json" - } + "Url": "http://172.30.9.200:8080/swagger/v1/swagger.json" } ] - }, - { - "Key": "pets", - "Config": [ - { - "Name": "Pets API", - "Version": "v1", - "Service": { - "Name": "projects", - "Path": "/swagger/v1/swagger.json" - } - } - ] - }, - { - "Key": "orders", - "Config": [ - { - "Name": "Orders API", - "Version": "v0.9", - "Url": "http://localhost:5400/swagger/v0.9/swagger.json" - }, - { - "Name": "Orders API", - "Version": "v1", - "Url": "http://localhost:5400/swagger/v1/swagger.json" - }, - { - "Name": "Orders API", - "Version": "v2", - "Url": "http://localhost:5400/swagger/v2/swagger.json" - }, - { - "Name": "Orders API", - "Version": "v3", - "Url": "http://localhost:5400/swagger/v3/swagger.json" - } - ] - } - ], - "GlobalConfiguration": { - "BaseUrl": "http://localhost", - "ServiceDiscoveryProvider": { - "Type": "AppConfiguration", - "PollingIntervalSeconds": 10000 } - } + ] } \ No newline at end of file diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs index 70fd3d1..49dacfa 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs @@ -40,6 +40,6 @@ public class SwaggerForOcelotUIOptions : SwaggerUIOptions /// /// Configure if use Server of swagger or not /// - public bool UseServerSwagger { get; set; } = true; + public string ServerOcelot { get; set; } } } diff --git a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs index 132b26a..707b788 100644 --- a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs +++ b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs @@ -67,14 +67,19 @@ public async Task Invoke(HttpContext context, ISwaggerServiceDiscoveryProvider d HttpClient httpClient = _httpClientFactory.CreateClient(); AddHeaders(httpClient); string content = await httpClient.GetStringAsync(Url); - string hostName = EndPoint.HostOverride ?? context.Request.Host.Value.RemoveSlashFromEnd(); + string serverName; + if (string.IsNullOrWhiteSpace(_options.ServerOcelot)) + serverName = EndPoint.HostOverride ?? context.Request.Host.Value.RemoveSlashFromEnd(); + else + serverName = _options.ServerOcelot; + IEnumerable reRouteOptions = _reRoutes.Value .ExpandConfig(EndPoint) .GroupByPaths(); if (EndPoint.TransformByOcelotConfig) { - content = _transformer.Transform(content, reRouteOptions, _options.UseServerSwagger, hostName); + content = _transformer.Transform(content, reRouteOptions, serverName); } content = await ReconfigureUpstreamSwagger(context, content); diff --git a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs index 8652ba3..35152dc 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs @@ -13,10 +13,10 @@ public interface ISwaggerJsonTransformer /// /// The swagger json. /// The re routes. - /// The host override to add to swagger json. + /// The host override to add to swagger json. /// /// Transformed swagger json. /// - string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride); + string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride); } } diff --git a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs index 10ccd41..b42a9b5 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs @@ -15,18 +15,18 @@ namespace MMLib.SwaggerForOcelot.Transformation public class SwaggerJsonTransformer : ISwaggerJsonTransformer { /// - public string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride) + public string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride) { var swagger = JObject.Parse(swaggerJson); if (swagger.ContainsKey("swagger")) { - return TransformSwagger(swagger, reRoutes, hostOverride); + return TransformSwagger(swagger, reRoutes, serverOverride); } if (swagger.ContainsKey("openapi")) { - return TransformOpenApi(swagger, reRoutes, useServer, hostOverride); + return TransformOpenApi(swagger, reRoutes, serverOverride); } throw new InvalidOperationException("Unknown swagger/openapi version"); @@ -73,7 +73,7 @@ private string TransformSwagger(JObject swagger, IEnumerable reR return swagger.ToString(Formatting.Indented); } - private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, bool useServer, string hostOverride = "/") + private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, string serverOverride = null) { // NOTE: Only supporting one server for now. string downstreamBasePath = ""; @@ -110,7 +110,7 @@ private string TransformOpenApi(JObject openApi, IEnumerable reR } } - TransformServerPaths(openApi, useServer, hostOverride); + TransformServerPaths(openApi, serverOverride); return openApi.ToString(Formatting.Indented); } @@ -252,24 +252,18 @@ private static void RenameToken(JProperty property, string newName) property.Replace(newProperty); } - private static void TransformServerPaths(JObject openApi, bool userServer, string hostOverride) + private static void TransformServerPaths(JObject openApi, string serverOverride) { if (!openApi.ContainsKey(OpenApiProperties.Servers)) { return; } - else if (!userServer) - { - openApi.Remove(OpenApiProperties.Servers); - } - else + + foreach (JToken server in openApi.GetValue(OpenApiProperties.Servers)) { - foreach (JToken server in openApi.GetValue(OpenApiProperties.Servers)) + if (server[OpenApiProperties.Url] != null) { - if (server[OpenApiProperties.Url] != null) - { - server[OpenApiProperties.Url] = hostOverride.RemoveSlashFromEnd(); - } + server[OpenApiProperties.Url] = serverOverride; } } } diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs index df6a44b..de68832 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs @@ -73,14 +73,12 @@ public async Task AllowVersionPlaceholder() .Setup(x => x.Transform( It.IsAny(), It.IsAny>(), - It.IsAny(), It.IsAny())) .Returns(( string swaggerJson, IEnumerable reRouteOptions, - bool userServer, - string hostOverride) => new SwaggerJsonTransformer() - .Transform(swaggerJson,reRouteOptions, userServer, hostOverride)); + string serverOverride) => new SwaggerJsonTransformer() + .Transform(swaggerJson,reRouteOptions, serverOverride)); var swaggerForOcelotMiddleware = new SwaggerForOcelotMiddleware( next.Invoke, swaggerForOcelotOptions, @@ -102,7 +100,6 @@ public async Task AllowVersionPlaceholder() swaggerJsonTransformerMock.Verify(x => x.Transform( It.IsAny(), It.IsAny>(), - It.IsAny(), It.IsAny()), Times.Once); } @@ -323,7 +320,7 @@ public TestSwaggerJsonTransformer(string transformedJson) _transformedJson = transformedJson; } - public string Transform(string swaggerJson, IEnumerable reRoutes, bool useServer, string hostOverride) + public string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride) { return _transformedJson; } diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs index 4885d37..9d1cc1f 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs @@ -22,7 +22,6 @@ public void TransferDownstreamSwaggerToUpstreamFormat(TestCase testData) string transformed = transformer.Transform( testData.DownstreamSwagger.ToString(), testData.ReRoutes, - true, testData.HostOverride); AreEqual(transformed, testData.ExpectedTransformedSwagger); From c498d83061c39f86c37f0e3a32b2fc6595865ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 19 May 2020 10:59:55 +0200 Subject: [PATCH 03/18] * Revert this file --- demo/ApiGateway/ocelot.json | 115 +++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/demo/ApiGateway/ocelot.json b/demo/ApiGateway/ocelot.json index 9cb4030..32e42a2 100644 --- a/demo/ApiGateway/ocelot.json +++ b/demo/ApiGateway/ocelot.json @@ -1,29 +1,116 @@ { "ReRoutes": [ { - "DownstreamPathTemplate": "/satcen/apitsr/{everything}", + "DownstreamPathTemplate": "/api/{everything}", + "ServiceName": "contacts", + "UpstreamPathTemplate": "/api/contacts/{everything}", + "UpstreamHttpMethod": [ "Get" ], + "SwaggerKey": "contacts" + }, + { + "DownstreamPathTemplate": "/api/{everything}", + "ServiceName": "projects", + "UpstreamPathTemplate": "/api/projects/{everything}", + "SwaggerKey": "projects" + }, + { + "DownstreamPathTemplate": "/{everything}", + "ServiceName": "pets", + "UpstreamHttpMethod": [ "Get", "Post" ], + "UpstreamPathTemplate": "/api/pets/{everything}", + "SwaggerKey": "pets" + }, + { + "DownstreamPathTemplate": "/api/{everything}", "DownstreamScheme": "http", - "DownstreamHostAndPorts": [ - { - "Host": "172.30.9.200", - "Port": 8080 - } - ], - "UpstreamPathTemplate": "/api/request/{everything}", - "DangerousAcceptAnyServerCertificateValidator": true, - "SwaggerKey": "request" + "ServiceName": "orders", + "UpstreamPathTemplate": "/api/orders/{everything}", + "UpstreamHttpMethod": [], + "SwaggerKey": "orders" } ], "SwaggerEndPoints": [ { - "Key": "request", + "Key": "contacts", + "Config": [ + { + "Name": "Contacts API", + "Version": "v1", + "Service": { + "Name": "contacts", + "Path": "/swagger/v1/swagger.json" + } + } + ] + }, + { + "Key": "gateway", + "TransformByOcelotConfig": false, + "Config": [ + { + "Name": "Gateway", + "Version": "v1", + "Url": "http://localhost:5000/swagger/v1/swagger.json" + } + ] + }, + { + "Key": "projects", "Config": [ { - "Name": "ApiIngestTSR API", + "Name": "Projects API", "Version": "v1", - "Url": "http://172.30.9.200:8080/swagger/v1/swagger.json" + "Service": { + "Name": "projects", + "Path": "/swagger/v1/swagger.json" + } } ] + }, + { + "Key": "pets", + "Config": [ + { + "Name": "Pets API", + "Version": "v1", + "Service": { + "Name": "projects", + "Path": "/swagger/v1/swagger.json" + } + } + ] + }, + { + "Key": "orders", + "Config": [ + { + "Name": "Orders API", + "Version": "v0.9", + "Url": "http://localhost:5400/swagger/v0.9/swagger.json" + }, + { + "Name": "Orders API", + "Version": "v1", + "Url": "http://localhost:5400/swagger/v1/swagger.json" + }, + { + "Name": "Orders API", + "Version": "v2", + "Url": "http://localhost:5400/swagger/v2/swagger.json" + }, + { + "Name": "Orders API", + "Version": "v3", + "Url": "http://localhost:5400/swagger/v3/swagger.json" + } + ] + } + ], + "GlobalConfiguration": { + "BaseUrl": "http://localhost", + "ServiceDiscoveryProvider": { + "Type": "AppConfiguration", + "PollingIntervalSeconds": 10000 } - ] + } } \ No newline at end of file From aa5d5643a1d8d71ee458f11dfe95948a16b2d413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 19 May 2020 11:51:14 +0200 Subject: [PATCH 04/18] * Modify comment --- .../Configuration/SwaggerForOcelotUIOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs index 49dacfa..7a0bd25 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs @@ -38,7 +38,7 @@ public class SwaggerForOcelotUIOptions : SwaggerUIOptions public Func> ReConfigureUpstreamSwaggerJsonAsync { get; set; } /// - /// Configure if use Server of swagger or not + /// Configure route of server of swagger in ocelot /// public string ServerOcelot { get; set; } } From 6d6fa3e35ab2e21ca71826397aff3f1a65f2a41f Mon Sep 17 00:00:00 2001 From: Burgyn Date: Tue, 19 May 2020 13:12:53 +0200 Subject: [PATCH 05/18] Typo changes --- .../Configuration/SwaggerForOcelotUIOptions.cs | 6 +++--- .../Middleware/SwaggerForOcelotMiddleware.cs | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs index 7a0bd25..2749da8 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotUIOptions.cs @@ -28,17 +28,17 @@ public class SwaggerForOcelotUIOptions : SwaggerUIOptions public IEnumerable> DownstreamSwaggerHeaders { get; set; } /// - /// Alter swagger/openApi json after it has been transformed + /// Alter swagger/openApi json after it has been transformed. /// public Func ReConfigureUpstreamSwaggerJson { get; set; } /// - /// Alter swagger/openApi json after it has been transformed + /// Alter swagger/openApi json after it has been transformed. /// public Func> ReConfigureUpstreamSwaggerJsonAsync { get; set; } /// - /// Configure route of server of swagger in ocelot + /// Configure route of server of swagger in ocelot. /// public string ServerOcelot { get; set; } } diff --git a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs index 707b788..2fb303c 100644 --- a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs +++ b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs @@ -69,9 +69,13 @@ public async Task Invoke(HttpContext context, ISwaggerServiceDiscoveryProvider d string content = await httpClient.GetStringAsync(Url); string serverName; if (string.IsNullOrWhiteSpace(_options.ServerOcelot)) + { serverName = EndPoint.HostOverride ?? context.Request.Host.Value.RemoveSlashFromEnd(); + } else + { serverName = _options.ServerOcelot; + } IEnumerable reRouteOptions = _reRoutes.Value .ExpandConfig(EndPoint) From 578c12520891f708fc8a68b13a0cf7b47744fb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Tue, 19 May 2020 14:16:56 +0200 Subject: [PATCH 06/18] * Added documentation of change * Revert default value of serverOverride * Added .RemoveSlashFromEnd(); in serverOverride --- README.md | 7 +++++++ .../Transformation/SwaggerJsonTransformer.cs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3715105..900cba4 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,13 @@ app.UseSwaggerForOcelotUI(Configuration, opt => { opts.ReConfigureUpstreamSwaggerJson = AlterUpstreamSwaggerJson; }) ``` +You can optionally customize the swagger server prior to calling the endpoints of the microservices as follows: +```CSharp +app.UseSwaggerForOcelotUI(Configuration, opt => { + opts.ReConfigureUpstreamSwaggerJson = AlterUpstreamSwaggerJson; + opts.ServerOcelot = "/siteName/apigateway" ; +}) + ``` 7. Show your microservices interactive documentation. diff --git a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs index b42a9b5..fb701bb 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs @@ -73,7 +73,7 @@ private string TransformSwagger(JObject swagger, IEnumerable reR return swagger.ToString(Formatting.Indented); } - private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, string serverOverride = null) + private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, string serverOverride = "/") { // NOTE: Only supporting one server for now. string downstreamBasePath = ""; @@ -263,7 +263,7 @@ private static void TransformServerPaths(JObject openApi, string serverOverride) { if (server[OpenApiProperties.Url] != null) { - server[OpenApiProperties.Url] = serverOverride; + server[OpenApiProperties.Url] = serverOverride.RemoveSlashFromEnd(); } } } From 359e1c550eb9e9fdc7b620398346408e743d9d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Wed, 10 Jun 2020 18:47:41 +0200 Subject: [PATCH 07/18] * Added Multifile configuration ocelot and swagger --- demo/ApiGateway/ApiGateway.csproj | 7 +- demo/ApiGateway/Program.cs | 3 +- demo/ApiGateway/Startup.cs | 2 +- .../ApiGatewayWithPath.csproj | 2 +- demo/ApiGatewayWithPath/ocelot.json | 2 +- .../{ReRouteOptions.cs => RouteOptions.cs} | 12 +- .../Configuration/SwaggerEndPointOptions.cs | 2 +- .../Configuration/SwaggerFileConfiguration.cs | 22 ++++ .../Configuration/SwaggerFileRoute.cs | 12 ++ .../SwaggerForOcelotFileOptions.cs | 24 ++++ .../ConfigurationBuilderExtensions.cs | 121 ++++++++++++++++++ .../ServiceCollectionExtensions.cs | 2 +- .../MMLib.SwaggerForOcelot.csproj | 2 +- .../Middleware/SwaggerForOcelotMiddleware.cs | 14 +- .../ReRouteOptionsExtensions.cs | 69 ---------- .../RouteOptionsExtensions.cs | 69 ++++++++++ .../ISwaggerServiceDiscoveryProvider.cs | 4 +- .../SwaggerServiceDiscoveryProvider.cs | 24 ++-- .../Transformation/ISwaggerJsonTransformer.cs | 4 +- .../Transformation/SwaggerJsonTransformer.cs | 30 ++--- .../DummySwaggerServiceDiscoveryProvider.cs | 2 +- ...uld.cs => RouteOptionsExtensionsShould.cs} | 18 +-- .../SwaggerServiceDiscoveryProviderShould.cs | 14 +- .../SwaggerForOcelotMiddlewareShould.cs | 34 ++--- .../SwaggerForOcelotShould.cs | 2 +- .../MMLib.SwaggerForOcelot.Tests/TestCase.cs | 8 +- .../Tests/BasicConfiguration.json | 2 +- ...asicConfigurationWithVirtualDirectory.json | 2 +- .../ConfigurationContainsOnlyPostMethods.json | 2 +- .../ConfigurationIsSplitByControllers.json | 4 +- .../ConfigurationIsSplitToSomeParts.json | 4 +- .../Tests/Issue_65.json | 2 +- .../Tests/NestedClasses.json | 2 +- .../Tests/OcelotRouteOnlyOneController.json | 2 +- .../Tests/OpenApiWithBasicConfiguration.json | 2 +- .../Tests/OpenApiWithHostOverridden.json | 2 +- ...pstreamAndDownstreamPathsAreDifferent.json | 2 +- .../Tests/OpenApiWithServers.json | 2 +- .../Tests/OpenApiWithVirtualDirectory.json | 2 +- ...aggerContainsInnerReferenceDefinition.json | 2 +- .../Tests/SwaggerWithBasePath.json | 2 +- 41 files changed, 361 insertions(+), 178 deletions(-) rename src/MMLib.SwaggerForOcelot/Configuration/{ReRouteOptions.cs => RouteOptions.cs} (96%) create mode 100644 src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs create mode 100644 src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileRoute.cs create mode 100644 src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs create mode 100644 src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs delete mode 100644 src/MMLib.SwaggerForOcelot/ReRouteOptionsExtensions.cs create mode 100644 src/MMLib.SwaggerForOcelot/RouteOptionsExtensions.cs rename tests/MMLib.SwaggerForOcelot.Tests/{ReRouteOptionsExtensionsShould.cs => RouteOptionsExtensionsShould.cs} (79%) diff --git a/demo/ApiGateway/ApiGateway.csproj b/demo/ApiGateway/ApiGateway.csproj index a9e6488..95ff48c 100644 --- a/demo/ApiGateway/ApiGateway.csproj +++ b/demo/ApiGateway/ApiGateway.csproj @@ -5,11 +5,14 @@ - + + + + - + diff --git a/demo/ApiGateway/Program.cs b/demo/ApiGateway/Program.cs index 1816f68..2157126 100644 --- a/demo/ApiGateway/Program.cs +++ b/demo/ApiGateway/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using MMLib.SwaggerForOcelot.DependencyInjection; namespace ApiGateway { @@ -21,7 +22,7 @@ public static IWebHostBuilder CreateWebHostBuilder(string[] args) => .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.local.json", optional: true, reloadOnChange: true) - .AddJsonFile("ocelot.json") + .AddOcelotWithSwaggerSupport(folder: "Configuration") .AddEnvironmentVariables(); }) .UseStartup(); diff --git a/demo/ApiGateway/Startup.cs b/demo/ApiGateway/Startup.cs index 31958eb..8d79353 100644 --- a/demo/ApiGateway/Startup.cs +++ b/demo/ApiGateway/Startup.cs @@ -60,7 +60,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) new KeyValuePair("Key2", "Value2"), }; - opt.ServerOcelot = "/siteName/apigateway" ; + //opt.ServerOcelot = "/siteName/apigateway" ; }) .UseOcelot() .Wait(); diff --git a/demo/ApiGatewayWithPath/ApiGatewayWithPath.csproj b/demo/ApiGatewayWithPath/ApiGatewayWithPath.csproj index 40d0c10..e642e1f 100644 --- a/demo/ApiGatewayWithPath/ApiGatewayWithPath.csproj +++ b/demo/ApiGatewayWithPath/ApiGatewayWithPath.csproj @@ -7,7 +7,7 @@ - + diff --git a/demo/ApiGatewayWithPath/ocelot.json b/demo/ApiGatewayWithPath/ocelot.json index a11bad8..eb24741 100644 --- a/demo/ApiGatewayWithPath/ocelot.json +++ b/demo/ApiGatewayWithPath/ocelot.json @@ -1,5 +1,5 @@ { - "ReRoutes": [ + "Routes": [ { "DownstreamPathTemplate": "/api/{everything}", "DownstreamScheme": "http", diff --git a/src/MMLib.SwaggerForOcelot/Configuration/ReRouteOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/RouteOptions.cs similarity index 96% rename from src/MMLib.SwaggerForOcelot/Configuration/ReRouteOptions.cs rename to src/MMLib.SwaggerForOcelot/Configuration/RouteOptions.cs index 31dce90..4860ace 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/ReRouteOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/RouteOptions.cs @@ -6,9 +6,9 @@ namespace MMLib.SwaggerForOcelot.Configuration { /// - /// Ocelot ReRoute configuration. + /// Ocelot Route configuration. /// - public class ReRouteOptions + public class RouteOptions { private const string CatchAllPlaceHolder = "{everything}"; private readonly string[] _defaultMethodsTypes = @@ -19,7 +19,7 @@ public class ReRouteOptions /// /// Ctor. /// - public ReRouteOptions() + public RouteOptions() { _httpMethods = new Lazy>(() => new HashSet( UpstreamHttpMethod?.Count() > 0 ? UpstreamHttpMethod : _defaultMethodsTypes, @@ -27,14 +27,14 @@ public ReRouteOptions() } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The swagger key. /// The upstream path template. /// The downstream path template. /// The virtual directory. /// The upstream methods. - public ReRouteOptions( + public RouteOptions( string swaggerKey, string upstreamPathTemplate, string downstreamPathTemplate, @@ -149,4 +149,4 @@ public bool CanCatchAll /// public override string ToString() => $"{UpstreamPathTemplate} => {DownstreamPathTemplate} | ({UpstreamPath} => {DownstreamPath})"; } -} \ No newline at end of file +} diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerEndPointOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerEndPointOptions.cs index d6a1f6b..b35be30 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerEndPointOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerEndPointOptions.cs @@ -14,7 +14,7 @@ public class SwaggerEndPointOptions public const string ConfigurationSectionName = "SwaggerEndPoints"; /// - /// Swagger endpoint key, which have to corresponding with . + /// Swagger endpoint key, which have to corresponding with . /// public string Key { get; set; } diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs new file mode 100644 index 0000000..449b48a --- /dev/null +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs @@ -0,0 +1,22 @@ +using Ocelot.Configuration.File; +using System.Collections.Generic; + +namespace MMLib.SwaggerForOcelot.Configuration +{ + /// + /// Mapping of the files configuration of ocelot + /// + public class SwaggerFileConfiguration + { + public List Routes { get; set; } = new List(); + + public List DynamicRoutes { get; set; } = new List(); + + // Seperate field for aggregates because this let's you re-use Routes in multiple Aggregates + public List Aggregates { get; set; } = new List(); + + public FileGlobalConfiguration GlobalConfiguration { get; set; } = new FileGlobalConfiguration(); + + public List SwaggerEndPoints { get; set; } = new List(); + } +} diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileRoute.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileRoute.cs new file mode 100644 index 0000000..063feab --- /dev/null +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileRoute.cs @@ -0,0 +1,12 @@ +using Ocelot.Configuration.File; + +namespace MMLib.SwaggerForOcelot.Configuration +{ + /// + /// Added Swagger configuration to routing of ocelot + /// + public class SwaggerFileRoute : FileRoute + { + public string SwaggerKey { get; set; } + } +} diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs new file mode 100644 index 0000000..48bf391 --- /dev/null +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs @@ -0,0 +1,24 @@ + +namespace MMLib.SwaggerForOcelot.Configuration +{ + /// + /// Class of constans of configuration of ocelot + /// + public static class SwaggerForOcelotFileOptions + { + /// + /// Name of file of principal file of configuration ocelot + /// + public const string PrimaryOcelotConfigFile = "ocelot.json"; + + /// + /// Name of file of global configuration of ocelot + /// + public const string GlobalOcelotConfigFile = "ocelot.global"; + + /// + /// Name for default of file of configuration of endpoints of swagger in ocelot + /// + public const string SwaggerEndPointsConfigFile = "ocelot.SwaggerEndPoints"; + } +} diff --git a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs new file mode 100644 index 0000000..46e04fb --- /dev/null +++ b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -0,0 +1,121 @@ +using Kros.Extensions; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using MMLib.SwaggerForOcelot.Configuration; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace MMLib.SwaggerForOcelot.DependencyInjection +{ + public static class ConfigurationBuilderExtensions + { + /// + /// Extension for compatibility of functionality multifile of ocelot + /// + /// + /// + /// + /// + /// a Object IConfigurationBuilder + public static IConfigurationBuilder AddOcelotWithSwaggerSupport( + this IConfigurationBuilder builder, + IWebHostEnvironment environment = null, + string folder = "/", + string fileOfSwaggerEndPoints = SwaggerForOcelotFileOptions.SwaggerEndPointsConfigFile) + { + List files = GetListOfOcelotFiles(folder, environment?.EnvironmentName); + + SwaggerFileConfiguration fileConfigurationMerged = MergeFilesOfOcelotConfiguration(files, fileOfSwaggerEndPoints, environment?.EnvironmentName); + + string jsonFileConfiguration = JsonConvert.SerializeObject(fileConfigurationMerged); + + File.WriteAllText(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, jsonFileConfiguration); + + builder.AddJsonFile(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, optional: false, reloadOnChange: false); + + return builder; + } + + #region Private Methods + + /// + /// Get files of ocelot Configuration with a filter of envirotment + /// + /// + /// a var of type List with the list of files of configuration of ocelot + private static List GetListOfOcelotFiles(string folder, string nameEnvirotment) + { + string subConfigPattern = @"^ocelot\.(.*?)\.json$"; + + var reg = new Regex(subConfigPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline); + + IEnumerable ocelotFiles = new DirectoryInfo(folder).EnumerateFiles() + .Where(fi => reg.IsMatch(fi.Name)); + if (!nameEnvirotment.IsNullOrWhiteSpace()) + ocelotFiles = ocelotFiles.Where(fi => fi.Name.Contains(nameEnvirotment)); + + return ocelotFiles.ToList(); + } + + /// + /// Check if name of file is the file of configuration by environment + /// + /// + /// + /// + /// a bool with a result of checked + private static bool IsGlobalConfigurationFile(string environmentName, string fileName, string fileConfigurationName) + { + if (environmentName.IsNullOrWhiteSpace()) + { + return fileName.Equals($"{fileConfigurationName}.json", StringComparison.OrdinalIgnoreCase); + } + else + { + return fileName.Equals($"{fileConfigurationName}.{environmentName}.json", StringComparison.OrdinalIgnoreCase); + } + } + + /// + /// Merge a list of files of configuration of Ocelot with options SwaggerEnpoints + /// + /// + /// + /// + /// a object SwaggerFileConfiguration with the configuration of file + private static SwaggerFileConfiguration MergeFilesOfOcelotConfiguration(List files, string fileOfSwaggerEndPoints, string environmentName) + { + SwaggerFileConfiguration fileConfigurationMerged = new SwaggerFileConfiguration(); + + foreach (FileInfo itemFile in files) + { + string linesOfFile = File.ReadAllText(itemFile.FullName); + SwaggerFileConfiguration config = JsonConvert.DeserializeObject(linesOfFile); + + if (files.Count > 1 && itemFile.Name.Equals(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + else if (IsGlobalConfigurationFile(environmentName, itemFile.Name, SwaggerForOcelotFileOptions.GlobalOcelotConfigFile)) + { + fileConfigurationMerged.GlobalConfiguration = config.GlobalConfiguration; + } + else if (IsGlobalConfigurationFile(environmentName, itemFile.Name, fileOfSwaggerEndPoints)) + { + fileConfigurationMerged.SwaggerEndPoints = config.SwaggerEndPoints; + } + + fileConfigurationMerged.Aggregates.AddRange(config.Aggregates); + fileConfigurationMerged.Routes.AddRange(config.Routes); + } + + return fileConfigurationMerged; + } + + #endregion + } +} diff --git a/src/MMLib.SwaggerForOcelot/DependencyInjection/ServiceCollectionExtensions.cs b/src/MMLib.SwaggerForOcelot/DependencyInjection/ServiceCollectionExtensions.cs index 43be2a1..b7d8430 100644 --- a/src/MMLib.SwaggerForOcelot/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/MMLib.SwaggerForOcelot/DependencyInjection/ServiceCollectionExtensions.cs @@ -22,7 +22,7 @@ public static IServiceCollection AddSwaggerForOcelot(this IServiceCollection ser => services .AddTransient() .AddTransient() - .Configure>(options => configuration.GetSection("ReRoutes").Bind(options)) + .Configure>(options => configuration.GetSection("Routes").Bind(options)) .Configure>(options => configuration.GetSection(SwaggerEndPointOptions.ConfigurationSectionName).Bind(options)) .AddHttpClient(); diff --git a/src/MMLib.SwaggerForOcelot/MMLib.SwaggerForOcelot.csproj b/src/MMLib.SwaggerForOcelot/MMLib.SwaggerForOcelot.csproj index 8265d6d..893063d 100644 --- a/src/MMLib.SwaggerForOcelot/MMLib.SwaggerForOcelot.csproj +++ b/src/MMLib.SwaggerForOcelot/MMLib.SwaggerForOcelot.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs index 2fb303c..1971c9c 100644 --- a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs +++ b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs @@ -22,7 +22,7 @@ public class SwaggerForOcelotMiddleware private readonly RequestDelegate _next; #pragma warning restore IDE0052 - private readonly IOptions> _reRoutes; + private readonly IOptions> _routes; private readonly Lazy> _swaggerEndPoints; private readonly IHttpClientFactory _httpClientFactory; private readonly ISwaggerJsonTransformer _transformer; @@ -33,21 +33,21 @@ public class SwaggerForOcelotMiddleware /// /// The next delegate. /// The options. - /// The Ocelot ReRoutes configuration. + /// The Ocelot Routes configuration. /// The swagger end points. /// The HTTP client factory. /// The SwaggerJsonTransformer public SwaggerForOcelotMiddleware( RequestDelegate next, SwaggerForOcelotUIOptions options, - IOptions> reRoutes, + IOptions> routes, IOptions> swaggerEndPoints, IHttpClientFactory httpClientFactory, ISwaggerJsonTransformer transformer) { _transformer = Check.NotNull(transformer, nameof(transformer)); _next = Check.NotNull(next, nameof(next)); - _reRoutes = Check.NotNull(reRoutes, nameof(reRoutes)); + _routes = Check.NotNull(routes, nameof(routes)); Check.NotNull(swaggerEndPoints, nameof(swaggerEndPoints)); _httpClientFactory = Check.NotNull(httpClientFactory, nameof(httpClientFactory)); _options = options; @@ -77,13 +77,13 @@ public async Task Invoke(HttpContext context, ISwaggerServiceDiscoveryProvider d serverName = _options.ServerOcelot; } - IEnumerable reRouteOptions = _reRoutes.Value + IEnumerable routeOptions = _routes.Value .ExpandConfig(EndPoint) .GroupByPaths(); if (EndPoint.TransformByOcelotConfig) { - content = _transformer.Transform(content, reRouteOptions, serverName); + content = _transformer.Transform(content, routeOptions, serverName); } content = await ReconfigureUpstreamSwagger(context, content); @@ -140,7 +140,7 @@ private void AddHeaders(HttpClient httpClient) SwaggerEndPointConfig config = endPoint.Config.FirstOrDefault(x => x.Version == endPointInfo.Version); string url = (await discoveryProvider - .GetSwaggerUriAsync(config, _reRoutes.Value.FirstOrDefault(p => p.SwaggerKey == endPoint.Key))) + .GetSwaggerUriAsync(config, _routes.Value.FirstOrDefault(p => p.SwaggerKey == endPoint.Key))) .AbsoluteUri; return (url, endPoint); diff --git a/src/MMLib.SwaggerForOcelot/ReRouteOptionsExtensions.cs b/src/MMLib.SwaggerForOcelot/ReRouteOptionsExtensions.cs deleted file mode 100644 index 6b606b1..0000000 --- a/src/MMLib.SwaggerForOcelot/ReRouteOptionsExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -using MMLib.SwaggerForOcelot.Configuration; -using System.Collections.Generic; -using System.Linq; - -namespace MMLib.SwaggerForOcelot -{ - /// - /// Extensions for . - /// - internal static class ReRouteOptionsExtensions - { - /// - /// Goups the re routes by paths. - /// - /// The re route options. - public static IEnumerable GroupByPaths(this IEnumerable reRouteOptions) - => reRouteOptions - .GroupBy(p => new { p.SwaggerKey, p.UpstreamPathTemplate, p.DownstreamPathTemplate, p.VirtualDirectory}) - .Select(p => { - ReRouteOptions route = p.First(); - return new ReRouteOptions( - p.Key.SwaggerKey, - route.UpstreamPathTemplate, - route.DownstreamPathTemplate, - p.Key.VirtualDirectory, - p.Where(r => r.UpstreamHttpMethod != null).SelectMany(r => r.UpstreamHttpMethod)); - }); - - /// - /// Expands versions from one endpoint to more ReRoute options. - /// - /// The re routes. - /// The end point. - public static IEnumerable ExpandConfig( - this IEnumerable reRoutes, - SwaggerEndPointOptions endPoint) - { - var reRouteOptions = reRoutes.Where(p => p.SwaggerKey == endPoint.Key).ToList(); - - if (string.IsNullOrWhiteSpace(endPoint.VersionPlaceholder)) - { - return reRouteOptions; - } - - var versionReRouteOptions = reRouteOptions.Where(x => - x.DownstreamPathTemplate.Contains(endPoint.VersionPlaceholder) - || x.UpstreamPathTemplate.Contains(endPoint.VersionPlaceholder)).ToList(); - versionReRouteOptions.ForEach(o => reRouteOptions.Remove(o)); - foreach (ReRouteOptions reRouteOption in versionReRouteOptions) - { - IEnumerable versionMappedReRouteOptions = endPoint.Config.Select(c => new ReRouteOptions() - { - SwaggerKey = reRouteOption.SwaggerKey, - DownstreamPathTemplate = - reRouteOption.DownstreamPathTemplate.Replace(endPoint.VersionPlaceholder, - c.Version), - UpstreamHttpMethod = reRouteOption.UpstreamHttpMethod, - UpstreamPathTemplate = - reRouteOption.UpstreamPathTemplate.Replace(endPoint.VersionPlaceholder, - c.Version), - VirtualDirectory = reRouteOption.VirtualDirectory - }); - reRouteOptions.AddRange(versionMappedReRouteOptions); - } - - return reRouteOptions; - } - } -} diff --git a/src/MMLib.SwaggerForOcelot/RouteOptionsExtensions.cs b/src/MMLib.SwaggerForOcelot/RouteOptionsExtensions.cs new file mode 100644 index 0000000..309d948 --- /dev/null +++ b/src/MMLib.SwaggerForOcelot/RouteOptionsExtensions.cs @@ -0,0 +1,69 @@ +using MMLib.SwaggerForOcelot.Configuration; +using System.Collections.Generic; +using System.Linq; + +namespace MMLib.SwaggerForOcelot +{ + /// + /// Extensions for . + /// + internal static class RouteOptionsExtensions + { + /// + /// Goups the re routes by paths. + /// + /// The re route options. + public static IEnumerable GroupByPaths(this IEnumerable routeOptions) + => routeOptions + .GroupBy(p => new { p.SwaggerKey, p.UpstreamPathTemplate, p.DownstreamPathTemplate, p.VirtualDirectory}) + .Select(p => { + RouteOptions route = p.First(); + return new RouteOptions( + p.Key.SwaggerKey, + route.UpstreamPathTemplate, + route.DownstreamPathTemplate, + p.Key.VirtualDirectory, + p.Where(r => r.UpstreamHttpMethod != null).SelectMany(r => r.UpstreamHttpMethod)); + }); + + /// + /// Expands versions from one endpoint to more Route options. + /// + /// The re routes. + /// The end point. + public static IEnumerable ExpandConfig( + this IEnumerable routes, + SwaggerEndPointOptions endPoint) + { + var routeOptions = routes.Where(p => p.SwaggerKey == endPoint.Key).ToList(); + + if (string.IsNullOrWhiteSpace(endPoint.VersionPlaceholder)) + { + return routeOptions; + } + + var versionRouteOptions = routeOptions.Where(x => + x.DownstreamPathTemplate.Contains(endPoint.VersionPlaceholder) + || x.UpstreamPathTemplate.Contains(endPoint.VersionPlaceholder)).ToList(); + versionRouteOptions.ForEach(o => routeOptions.Remove(o)); + foreach (RouteOptions routeOption in versionRouteOptions) + { + IEnumerable versionMappedRouteOptions = endPoint.Config.Select(c => new RouteOptions() + { + SwaggerKey = routeOption.SwaggerKey, + DownstreamPathTemplate = + routeOption.DownstreamPathTemplate.Replace(endPoint.VersionPlaceholder, + c.Version), + UpstreamHttpMethod = routeOption.UpstreamHttpMethod, + UpstreamPathTemplate = + routeOption.UpstreamPathTemplate.Replace(endPoint.VersionPlaceholder, + c.Version), + VirtualDirectory = routeOption.VirtualDirectory + }); + routeOptions.AddRange(versionMappedRouteOptions); + } + + return routeOptions; + } + } +} diff --git a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/ISwaggerServiceDiscoveryProvider.cs b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/ISwaggerServiceDiscoveryProvider.cs index bb79711..4b54c7c 100644 --- a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/ISwaggerServiceDiscoveryProvider.cs +++ b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/ISwaggerServiceDiscoveryProvider.cs @@ -13,7 +13,7 @@ public interface ISwaggerServiceDiscoveryProvider /// Gets the swagger URI asynchronous. /// /// The endPoint. - /// The reRoute. - Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute); + /// The route. + Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, RouteOptions route); } } diff --git a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs index fdd61f9..27d8f58 100644 --- a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs +++ b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Threading.Tasks; using Kros.Extensions; @@ -33,7 +33,7 @@ public SwaggerServiceDiscoveryProvider( } /// - public async Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) + public async Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, RouteOptions route) { if (!endPoint.Url.IsNullOrEmpty()) { @@ -41,21 +41,21 @@ public async Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRout } else { - return await GetSwaggerUri(endPoint, reRoute); + return await GetSwaggerUri(endPoint, route); } } - private async Task GetSwaggerUri(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) + private async Task GetSwaggerUri(SwaggerEndPointConfig endPoint, RouteOptions route) { var conf = _configurationCreator.Create(_options.CurrentValue.GlobalConfiguration); - var downstreamReroute = new DownstreamReRouteBuilder() + var downstreamRoute = new DownstreamRouteBuilder() .WithUseServiceDiscovery(true) .WithServiceName(endPoint.Service.Name) - .WithServiceNamespace(reRoute.ServiceNamespace) + .WithServiceNamespace(route.ServiceNamespace) .Build(); - var serviceProvider = _serviceDiscovery.Get(conf, downstreamReroute); + var serviceProvider = _serviceDiscovery.Get(conf, downstreamRoute); if (serviceProvider.IsError) { @@ -69,15 +69,15 @@ private async Task GetSwaggerUri(SwaggerEndPointConfig endPoint, ReRouteOpt throw new InvalidOperationException(GetErrorMessage(endPoint)); } - var builder = new UriBuilder(GetScheme(service, reRoute), service.DownstreamHost, service.DownstreamPort); + var builder = new UriBuilder(GetScheme(service, route), service.DownstreamHost, service.DownstreamPort); builder.Path = endPoint.Service.Path; return builder.Uri; } - private string GetScheme(ServiceHostAndPort service, ReRouteOptions reRoute) - => !reRoute.DownstreamScheme.IsNullOrEmpty() - ? reRoute.DownstreamScheme + private string GetScheme(ServiceHostAndPort service, RouteOptions route) + => !route.DownstreamScheme.IsNullOrEmpty() + ? route.DownstreamScheme : !service.Scheme.IsNullOrEmpty() ? service.Scheme : service.DownstreamPort @@ -90,4 +90,4 @@ private string GetScheme(ServiceHostAndPort service, ReRouteOptions reRoute) private static string GetErrorMessage(SwaggerEndPointConfig endPoint) => $"Service with swagger documentation '{endPoint.Service.Name}' cann't be discovered"; } -} \ No newline at end of file +} diff --git a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs index 35152dc..bb8c849 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/ISwaggerJsonTransformer.cs @@ -12,11 +12,11 @@ public interface ISwaggerJsonTransformer /// Transforms downstream swagger json into upstream format. /// /// The swagger json. - /// The re routes. + /// The re routes. /// The host override to add to swagger json. /// /// Transformed swagger json. /// - string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride); + string Transform(string swaggerJson, IEnumerable routes, string serverOverride); } } diff --git a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs index fb701bb..3a4f40f 100644 --- a/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs +++ b/src/MMLib.SwaggerForOcelot/Transformation/SwaggerJsonTransformer.cs @@ -15,24 +15,24 @@ namespace MMLib.SwaggerForOcelot.Transformation public class SwaggerJsonTransformer : ISwaggerJsonTransformer { /// - public string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride) + public string Transform(string swaggerJson, IEnumerable routes, string serverOverride) { var swagger = JObject.Parse(swaggerJson); if (swagger.ContainsKey("swagger")) { - return TransformSwagger(swagger, reRoutes, serverOverride); + return TransformSwagger(swagger, routes, serverOverride); } if (swagger.ContainsKey("openapi")) { - return TransformOpenApi(swagger, reRoutes, serverOverride); + return TransformOpenApi(swagger, routes, serverOverride); } throw new InvalidOperationException("Unknown swagger/openapi version"); } - private string TransformSwagger(JObject swagger, IEnumerable reRoutes, string hostOverride) + private string TransformSwagger(JObject swagger, IEnumerable routes, string hostOverride) { JToken paths = swagger[SwaggerProperties.Paths]; string basePath = swagger.ContainsKey(SwaggerProperties.BasePath) @@ -48,7 +48,7 @@ private string TransformSwagger(JObject swagger, IEnumerable reR if (paths != null) { - RenameAndRemovePaths(reRoutes, paths, basePath); + RenameAndRemovePaths(routes, paths, basePath); RemoveItems( swagger[SwaggerProperties.Definitions], @@ -73,7 +73,7 @@ private string TransformSwagger(JObject swagger, IEnumerable reR return swagger.ToString(Formatting.Indented); } - private string TransformOpenApi(JObject openApi, IEnumerable reRoutes, string serverOverride = "/") + private string TransformOpenApi(JObject openApi, IEnumerable routes, string serverOverride = "/") { // NOTE: Only supporting one server for now. string downstreamBasePath = ""; @@ -89,7 +89,7 @@ private string TransformOpenApi(JObject openApi, IEnumerable reR JToken paths = openApi[OpenApiProperties.Paths]; if (paths != null) { - RenameAndRemovePaths(reRoutes, paths, downstreamBasePath); + RenameAndRemovePaths(routes, paths, downstreamBasePath); JToken schemaToken = openApi[OpenApiProperties.Components][OpenApiProperties.Schemas]; if (schemaToken != null) @@ -115,7 +115,7 @@ private string TransformOpenApi(JObject openApi, IEnumerable reR return openApi.ToString(Formatting.Indented); } - private void RenameAndRemovePaths(IEnumerable reRoutes, JToken paths, string basePath) + private void RenameAndRemovePaths(IEnumerable routes, JToken paths, string basePath) { var forRemove = new List(); @@ -123,11 +123,11 @@ private void RenameAndRemovePaths(IEnumerable reRoutes, JToken p { var path = paths.ElementAt(i) as JProperty; string downstreamPath = path.Name.RemoveSlashFromEnd(); - ReRouteOptions reRoute = FindReRoute(reRoutes, path.Name.WithShashEnding(), basePath); + RouteOptions route = FindRoute(routes, path.Name.WithShashEnding(), basePath); - if (reRoute != null && RemoveMethods(path, reRoute)) + if (route != null && RemoveMethods(path, route)) { - RenameToken(path, ConvertDownstreamPathToUpstreamPath(downstreamPath, reRoute.DownstreamPath, reRoute.UpstreamPath, basePath)); + RenameToken(path, ConvertDownstreamPathToUpstreamPath(downstreamPath, route.DownstreamPath, route.UpstreamPath, basePath)); } else { @@ -141,14 +141,14 @@ private void RenameAndRemovePaths(IEnumerable reRoutes, JToken p } } - private bool RemoveMethods(JProperty path, ReRouteOptions reRoute) + private bool RemoveMethods(JProperty path, RouteOptions route) { var forRemove = new List(); var method = path.First.First as JProperty; while (method != null) { - if (!reRoute.ContainsHttpMethod(method.Name)) + if (!route.ContainsHttpMethod(method.Name)) { forRemove.Add(method); } @@ -211,10 +211,10 @@ private static void CheckSubreferences(IEnumerable token, Func reRoutes, string downstreamPath, string basePath) + private static RouteOptions FindRoute(IEnumerable routes, string downstreamPath, string basePath) { string downstreamPathWithBasePath = PathHelper.BuildPath(basePath, downstreamPath); - return reRoutes.FirstOrDefault(p + return routes.FirstOrDefault(p => p.CanCatchAll ? downstreamPathWithBasePath.StartsWith(p.DownstreamPathWithShash, StringComparison.CurrentCultureIgnoreCase) : p.DownstreamPathWithShash.Equals(downstreamPathWithBasePath, StringComparison.CurrentCultureIgnoreCase)); diff --git a/tests/MMLib.SwaggerForOcelot.Tests/DummySwaggerServiceDiscoveryProvider.cs b/tests/MMLib.SwaggerForOcelot.Tests/DummySwaggerServiceDiscoveryProvider.cs index 02e2efd..64472c2 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/DummySwaggerServiceDiscoveryProvider.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/DummySwaggerServiceDiscoveryProvider.cs @@ -7,7 +7,7 @@ namespace MMLib.SwaggerForOcelot.Tests { internal class DummySwaggerServiceDiscoveryProvider : ISwaggerServiceDiscoveryProvider { - public Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) => + public Task GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, RouteOptions route) => Task.FromResult(new Uri(endPoint.Url)); public static ISwaggerServiceDiscoveryProvider Default => new DummySwaggerServiceDiscoveryProvider(); diff --git a/tests/MMLib.SwaggerForOcelot.Tests/ReRouteOptionsExtensionsShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/RouteOptionsExtensionsShould.cs similarity index 79% rename from tests/MMLib.SwaggerForOcelot.Tests/ReRouteOptionsExtensionsShould.cs rename to tests/MMLib.SwaggerForOcelot.Tests/RouteOptionsExtensionsShould.cs index df8c66f..54a9f81 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/ReRouteOptionsExtensionsShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/RouteOptionsExtensionsShould.cs @@ -6,42 +6,42 @@ namespace MMLib.SwaggerForOcelot.Tests { - public class ReRouteOptionsExtensionsShould + public class RouteOptionsExtensionsShould { [Fact] - public void GroupReRoutesByPaths() + public void GroupRoutesByPaths() { - IEnumerable reRouteOptions = new List() + IEnumerable routeOptions = new List() { - new ReRouteOptions(){ + new RouteOptions(){ DownstreamPathTemplate= "/api/masterdatatype", UpstreamPathTemplate = "/masterdatatype", UpstreamHttpMethod = new HashSet(){ "Get"} }, - new ReRouteOptions(){ + new RouteOptions(){ DownstreamPathTemplate= "/api/masterdatatype", UpstreamPathTemplate = "/masterdatatype", UpstreamHttpMethod = new HashSet(){ "Post"} }, - new ReRouteOptions(){ + new RouteOptions(){ DownstreamPathTemplate= "/api/masterdatatype/{everything}", UpstreamPathTemplate = "/masterdatatype/{everything}", UpstreamHttpMethod = new HashSet(){ "Delete"} }, - new ReRouteOptions(){ + new RouteOptions(){ DownstreamPathTemplate= "/api/masterdatatype/{everything}", UpstreamPathTemplate = "/masterdatatype/{everything}", UpstreamHttpMethod = new HashSet(){ "Delete"}, VirtualDirectory = "something" }, - new ReRouteOptions(){ + new RouteOptions(){ DownstreamPathTemplate= "/api/masterdata", UpstreamPathTemplate = "/masterdata", UpstreamHttpMethod = new HashSet(){ "Delete"} }, }; - IEnumerable actual = reRouteOptions.GroupByPaths(); + IEnumerable actual = routeOptions.GroupByPaths(); actual .Should() diff --git a/tests/MMLib.SwaggerForOcelot.Tests/ServiceDiscovery/SwaggerServiceDiscoveryProviderShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/ServiceDiscovery/SwaggerServiceDiscoveryProviderShould.cs index 87ff470..520674c 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/ServiceDiscovery/SwaggerServiceDiscoveryProviderShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/ServiceDiscovery/SwaggerServiceDiscoveryProviderShould.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -27,7 +27,7 @@ public async Task ReturnUriFromUrlDefinition() Uri uri = await provider.GetSwaggerUriAsync( new SwaggerEndPointConfig() { Url = "http://localhost:5000/swagger" }, - new Configuration.ReRouteOptions()); + new Configuration.RouteOptions()); uri.AbsoluteUri.Should().Be("http://localhost:5000/swagger"); } @@ -42,7 +42,7 @@ public async Task ReturnUriFromServiceDiscovery() { Service = new SwaggerService() { Name = "Projects", Path = "/swagger/v1/json" } }, - new Configuration.ReRouteOptions()); + new Configuration.RouteOptions()); uri.AbsoluteUri.Should().Be("http://localhost:5000/swagger/v1/json"); } @@ -59,7 +59,7 @@ public async Task UseCorrectSchemeByPort(int port, string expectedScheme) { Service = new SwaggerService() { Name = "Projects", Path = "/swagger/v1/json" } }, - new Configuration.ReRouteOptions()); + new Configuration.RouteOptions()); uri.Scheme.Should().Be(expectedScheme); } @@ -76,7 +76,7 @@ public async Task UseCorrectSchemeByDownstreamScheme(string expectedScheme) { Service = new SwaggerService() { Name = "Projects", Path = "/swagger/v1/json" } }, - new Configuration.ReRouteOptions() { DownstreamScheme = expectedScheme }); + new Configuration.RouteOptions() { DownstreamScheme = expectedScheme }); uri.Scheme.Should().Be(expectedScheme); } @@ -93,7 +93,7 @@ private static SwaggerServiceDiscoveryProvider CreateProvider(Service service = serviceProvider.Get().Returns(new List() { service }); var response = new OkResponse(serviceProvider); - serviceDiscovery.Get(Arg.Any(), Arg.Any()).Returns(response); + serviceDiscovery.Get(Arg.Any(), Arg.Any()).Returns(response); var provider = new SwaggerServiceDiscoveryProvider(serviceDiscovery, configurationCreator, options); return provider; @@ -105,4 +105,4 @@ private static SwaggerServiceDiscoveryProvider CreateProvider(Service service = string.Empty, Enumerable.Empty()); } -} \ No newline at end of file +} diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs index de68832..73f7a52 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotMiddlewareShould.cs @@ -38,21 +38,21 @@ public async Task AllowVersionPlaceholder() // What is being tested var swaggerForOcelotOptions = new SwaggerForOcelotUIOptions(); TestSwaggerEndpointOptions swaggerEndpointOptions = CreateSwaggerEndpointOptions(key,version); - var rerouteOptions = new TestReRouteOptions(new List + var routeOptions = new TestRouteOptions(new List { - new ReRouteOptions + new RouteOptions { SwaggerKey = "projects", UpstreamPathTemplate ="/api/{version}/projects/Values/{everything}", DownstreamPathTemplate ="/api/{version}/Values/{everything}", }, - new ReRouteOptions + new RouteOptions { SwaggerKey = "projects", UpstreamPathTemplate = "/api/projects/Projects", DownstreamPathTemplate = "/api/Projects", }, - new ReRouteOptions + new RouteOptions { SwaggerKey = "projects", UpstreamPathTemplate = "/api/projects/Projects/{everything}", @@ -72,17 +72,17 @@ public async Task AllowVersionPlaceholder() swaggerJsonTransformerMock .Setup(x => x.Transform( It.IsAny(), - It.IsAny>(), + It.IsAny>(), It.IsAny())) .Returns(( string swaggerJson, - IEnumerable reRouteOptions, + IEnumerable routeOptions, string serverOverride) => new SwaggerJsonTransformer() - .Transform(swaggerJson,reRouteOptions, serverOverride)); + .Transform(swaggerJson,routeOptions, serverOverride)); var swaggerForOcelotMiddleware = new SwaggerForOcelotMiddleware( next.Invoke, swaggerForOcelotOptions, - rerouteOptions, + routeOptions, swaggerEndpointOptions, httpClientFactory, swaggerJsonTransformerMock.Object); @@ -99,7 +99,7 @@ public async Task AllowVersionPlaceholder() } swaggerJsonTransformerMock.Verify(x => x.Transform( It.IsAny(), - It.IsAny>(), + It.IsAny>(), It.IsAny()), Times.Once); } @@ -119,7 +119,7 @@ public async Task AllowUserDefinedUpstreamTransformer() ReConfigureUpstreamSwaggerJson = ExampleUserDefinedUpstreamTransformer }; TestSwaggerEndpointOptions testSwaggerEndpointOptions = CreateSwaggerEndpointOptions(key,version); - var rerouteOptions = new TestReRouteOptions(); + var routeOptions = new TestRouteOptions(); // downstreamSwagger is returned when client.GetStringAsync is called by the middleware. string downstreamSwagger = await GetBaseOpenApi("OpenApiBase"); @@ -133,7 +133,7 @@ public async Task AllowUserDefinedUpstreamTransformer() var swaggerForOcelotMiddleware = new SwaggerForOcelotMiddleware( next.Invoke, swaggerForOcelotOptions, - rerouteOptions, + routeOptions, testSwaggerEndpointOptions, httpClientFactory, swaggerJsonTransformer); @@ -287,19 +287,19 @@ public HttpClient CreateClient(string name) } } - private class TestReRouteOptions : IOptions> + private class TestRouteOptions : IOptions> { - public TestReRouteOptions() + public TestRouteOptions() { - Value = new List(); + Value = new List(); } - public TestReRouteOptions(List value) + public TestRouteOptions(List value) { Value = value; } - public List Value { get; } + public List Value { get; } } private class TestSwaggerEndpointOptions : IOptions> @@ -320,7 +320,7 @@ public TestSwaggerJsonTransformer(string transformedJson) _transformedJson = transformedJson; } - public string Transform(string swaggerJson, IEnumerable reRoutes, string serverOverride) + public string Transform(string swaggerJson, IEnumerable routes, string serverOverride) { return _transformedJson; } diff --git a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs index 9d1cc1f..e00f582 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/SwaggerForOcelotShould.cs @@ -21,7 +21,7 @@ public void TransferDownstreamSwaggerToUpstreamFormat(TestCase testData) string transformed = transformer.Transform( testData.DownstreamSwagger.ToString(), - testData.ReRoutes, + testData.Routes, testData.HostOverride); AreEqual(transformed, testData.ExpectedTransformedSwagger); diff --git a/tests/MMLib.SwaggerForOcelot.Tests/TestCase.cs b/tests/MMLib.SwaggerForOcelot.Tests/TestCase.cs index d068368..050db1b 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/TestCase.cs +++ b/tests/MMLib.SwaggerForOcelot.Tests/TestCase.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using MMLib.SwaggerForOcelot.Configuration; using Newtonsoft.Json.Linq; @@ -25,9 +25,9 @@ public class TestCase public string HostOverride { get; set; } /// - /// Ocelot ReRoutes configuration. + /// Ocelot Routes configuration. /// - public IEnumerable ReRoutes { get; set; } + public IEnumerable Routes { get; set; } /// /// Source downstream swagger to transformation. @@ -44,4 +44,4 @@ public class TestCase /// public override string ToString() => $"{Name} ({FileName})"; } -} \ No newline at end of file +} diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfiguration.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfiguration.json index d35c735..3929752 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfiguration.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfiguration.json @@ -1,7 +1,7 @@ { "name": "Basic configuration", "hostOverride": "localhost:8000", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfigurationWithVirtualDirectory.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfigurationWithVirtualDirectory.json index 7dcaad4..ef6f597 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfigurationWithVirtualDirectory.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/BasicConfigurationWithVirtualDirectory.json @@ -1,7 +1,7 @@ { "name": "Basic configuration with virtual directory.", "hostOverride": "localhost:8000", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationContainsOnlyPostMethods.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationContainsOnlyPostMethods.json index e1852f1..3ab0934 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationContainsOnlyPostMethods.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationContainsOnlyPostMethods.json @@ -2,7 +2,7 @@ "name": "Ocelot configuration contains only POST methods.", "description": "Ocelot filter only POST methods.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/v2/{everything}", "UpstreamPathTemplate": "/v2/api/pets/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitByControllers.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitByControllers.json index a21d556..79411f8 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitByControllers.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitByControllers.json @@ -1,8 +1,8 @@ { "name": "Ocelot configuration is split by controllers.", - "description": "One service is split to more Ocelot's reroutes configurations by controllers.", + "description": "One service is split to more Ocelot's routes configurations by controllers.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/v2/pet/findByStatus", "UpstreamPathTemplate": "/v2/api/pets/pet/findByStatus", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitToSomeParts.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitToSomeParts.json index b59886b..2915613 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitToSomeParts.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/ConfigurationIsSplitToSomeParts.json @@ -1,8 +1,8 @@ { "name": "Ocelot configuration is split to some parts.", - "description": "One service is split to more Ocelot's reroutes configurations. Contains only same actions.", + "description": "One service is split to more Ocelot's routes configurations. Contains only same actions.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/v2/pet/{everything}", "UpstreamPathTemplate": "/v2/api/pets/pet/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/Issue_65.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/Issue_65.json index 7ca1790..ce9c175 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/Issue_65.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/Issue_65.json @@ -2,7 +2,7 @@ "name": "GitHub issue #65", "description": "Confusion in the interpretation of the routes. https://github.com/Burgyn/MMLib.SwaggerForOcelot/issues/65", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/companies", "DownstreamScheme": "https", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/NestedClasses.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/NestedClasses.json index 09d07bf..e287e09 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/NestedClasses.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/NestedClasses.json @@ -1,7 +1,7 @@ { "name": "Nested classes", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/r/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OcelotRouteOnlyOneController.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OcelotRouteOnlyOneController.json index 9667c7d..a779795 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OcelotRouteOnlyOneController.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OcelotRouteOnlyOneController.json @@ -2,7 +2,7 @@ "name": "Ocelot route only one controller.", "description": "Ocelot configuration contains routing for only one controller.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/v2/store/{everything}", "UpstreamPathTemplate": "/v2/api/store/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithBasicConfiguration.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithBasicConfiguration.json index c134b38..dd1448f 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithBasicConfiguration.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithBasicConfiguration.json @@ -2,7 +2,7 @@ "name": "Open api version with basic configuration.", "description": "Test open api format with basic configuration.", "hostOverride": "localhost:8000", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverridden.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverridden.json index 39ac155..35a8943 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverridden.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverridden.json @@ -2,7 +2,7 @@ "name": "Open Api version with host overriden.", "description": "Configuration has overridden host.", "hostOverride": "http://override.host.it", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverriddenWhenUpstreamAndDownstreamPathsAreDifferent.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverriddenWhenUpstreamAndDownstreamPathsAreDifferent.json index c0e2177..29926f4 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverriddenWhenUpstreamAndDownstreamPathsAreDifferent.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithHostOverriddenWhenUpstreamAndDownstreamPathsAreDifferent.json @@ -1,7 +1,7 @@ { "name": "Open Api with host overridden when upstream and downstream paths are different.", "hostOverride": "http://service.api.io", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/prefix/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithServers.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithServers.json index 939bca6..81dcf3d 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithServers.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithServers.json @@ -2,7 +2,7 @@ "name": "Open Api format with servers.", "description": "Open Api contains servers.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithVirtualDirectory.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithVirtualDirectory.json index 3da9a88..bec350e 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithVirtualDirectory.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/OpenApiWithVirtualDirectory.json @@ -2,7 +2,7 @@ "name": "Open api version with basic configuration and virtual directory.", "description": "Test open api format with basic configuration and virtual directory.", "hostOverride": "localhost:8000", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerContainsInnerReferenceDefinition.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerContainsInnerReferenceDefinition.json index 97f5999..18ead80 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerContainsInnerReferenceDefinition.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerContainsInnerReferenceDefinition.json @@ -2,7 +2,7 @@ "name": "Swagger contains inner reference definition.", "description": "Same definition has inner references.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/admin/{everything}", diff --git a/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerWithBasePath.json b/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerWithBasePath.json index 1300750..14067c5 100644 --- a/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerWithBasePath.json +++ b/tests/MMLib.SwaggerForOcelot.Tests/Tests/SwaggerWithBasePath.json @@ -2,7 +2,7 @@ "name": "Swagger with base path.", "description": "Testing swagger with setting base path.", "hostOverride": "", - "reRoutes": [ + "routes": [ { "DownstreamPathTemplate": "/api/{everything}", "UpstreamPathTemplate": "/api/projects/{everything}", From bb877898b5248e3df14bf609494bd156ed1c6c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Thu, 11 Jun 2020 09:20:35 +0200 Subject: [PATCH 08/18] * blank line removed --- .../Configuration/SwaggerForOcelotFileOptions.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs index 48bf391..2a72bd5 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerForOcelotFileOptions.cs @@ -1,5 +1,4 @@ - -namespace MMLib.SwaggerForOcelot.Configuration +namespace MMLib.SwaggerForOcelot.Configuration { /// /// Class of constans of configuration of ocelot From 04564cc0e73607a93541a9b6a8262b4b61339397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Thu, 11 Jun 2020 09:50:16 +0200 Subject: [PATCH 09/18] * Remove line of file not used --- demo/ApiGateway/ApiGateway.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/demo/ApiGateway/ApiGateway.csproj b/demo/ApiGateway/ApiGateway.csproj index 95ff48c..b254574 100644 --- a/demo/ApiGateway/ApiGateway.csproj +++ b/demo/ApiGateway/ApiGateway.csproj @@ -4,10 +4,6 @@ netcoreapp3.1 - - - - From e4d2b5d647434f4f4f7c67eb9371e26a7c59e94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Mon, 15 Jun 2020 17:41:38 +0200 Subject: [PATCH 10/18] * Added comments --- demo/ApiGateway/Startup.cs | 2 -- .../Configuration/SwaggerFileConfiguration.cs | 16 +++++++++++++++- .../ConfigurationBuilderExtensions.cs | 15 ++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/demo/ApiGateway/Startup.cs b/demo/ApiGateway/Startup.cs index e25a677..53cf825 100644 --- a/demo/ApiGateway/Startup.cs +++ b/demo/ApiGateway/Startup.cs @@ -59,8 +59,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) new KeyValuePair("Key", "Value"), new KeyValuePair("Key2", "Value2"), }; - - opt.ServerOcelot = "/siteName/apigateway" ; }) .UseOcelot() .Wait(); diff --git a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs index 449b48a..c03d13b 100644 --- a/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs +++ b/src/MMLib.SwaggerForOcelot/Configuration/SwaggerFileConfiguration.cs @@ -8,15 +8,29 @@ namespace MMLib.SwaggerForOcelot.Configuration /// public class SwaggerFileConfiguration { + /// + /// Routes of ocelot + /// public List Routes { get; set; } = new List(); + /// + /// Dynamic Routes for ocelot + /// public List DynamicRoutes { get; set; } = new List(); - // Seperate field for aggregates because this let's you re-use Routes in multiple Aggregates + /// + /// Seperate field for aggregates because this let's you re-use Routes in multiple Aggregates + /// public List Aggregates { get; set; } = new List(); + /// + /// Global configuration of ocelot + /// public FileGlobalConfiguration GlobalConfiguration { get; set; } = new FileGlobalConfiguration(); + /// + /// Configuration of swagger for ocelot + /// public List SwaggerEndPoints { get; set; } = new List(); } } diff --git a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 46e04fb..01a19a2 100644 --- a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -11,15 +11,18 @@ namespace MMLib.SwaggerForOcelot.DependencyInjection { + /// + /// Extension for compatibility of multiple ocelot configuration files with SwaggerForOcelot + /// public static class ConfigurationBuilderExtensions { /// /// Extension for compatibility of functionality multifile of ocelot /// - /// - /// - /// - /// + /// builder of net core for call this extension + /// environment of net core app + /// folder of files of configuration of ocelot + /// name of file of configuration SwaggerForOcelot without .json extension /// a Object IConfigurationBuilder public static IConfigurationBuilder AddOcelotWithSwaggerSupport( this IConfigurationBuilder builder, @@ -27,7 +30,7 @@ public static IConfigurationBuilder AddOcelotWithSwaggerSupport( string folder = "/", string fileOfSwaggerEndPoints = SwaggerForOcelotFileOptions.SwaggerEndPointsConfigFile) { - List files = GetListOfOcelotFiles(folder, environment?.EnvironmentName); + List files = GetListOfOcelotFiles(folder, environment?.EnvironmentName); SwaggerFileConfiguration fileConfigurationMerged = MergeFilesOfOcelotConfiguration(files, fileOfSwaggerEndPoints, environment?.EnvironmentName); @@ -56,7 +59,9 @@ private static List GetListOfOcelotFiles(string folder, string nameEnv IEnumerable ocelotFiles = new DirectoryInfo(folder).EnumerateFiles() .Where(fi => reg.IsMatch(fi.Name)); if (!nameEnvirotment.IsNullOrWhiteSpace()) + { ocelotFiles = ocelotFiles.Where(fi => fi.Name.Contains(nameEnvirotment)); + } return ocelotFiles.ToList(); } From ee1d247b1dd7ad4ae6c04f449b151582532f1ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Mon, 15 Jun 2020 17:49:35 +0200 Subject: [PATCH 11/18] Remove line not used --- demo/ApiGateway/ApiGateway.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/demo/ApiGateway/ApiGateway.csproj b/demo/ApiGateway/ApiGateway.csproj index 8048cbd..b254574 100644 --- a/demo/ApiGateway/ApiGateway.csproj +++ b/demo/ApiGateway/ApiGateway.csproj @@ -16,8 +16,4 @@ - - - - From 4b0bc092335517c22288ec9d52cbe79e1f02d641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Wed, 17 Jun 2020 19:33:06 +0200 Subject: [PATCH 12/18] *fixed test and new documentation on the new extension --- README.md | 37 +++++++++++++++++++ .../SwaggerServiceDiscoveryProvider.cs | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d807174..b838af8 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,43 @@ Direct via `http://ocelotprojecturl:port/swagger` provides documentation for dow > `SwaggerEndPoint` is configuration for downstream service swagger generator endpoint. Property `Key` is used to pair with the Route configuration. `Name` is displayed in the combobox. `Url` is downstream service swagger generator endpoint. +Optionally you can use the ocelot utility to load the apigateway configuration into multiple configuration files named as follows: ocelot.exampleName.json, but to activate this feature you need to use the following extension: +```CSharp + WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(); + }) + .UseStartup(); +``` +using this extension the swagger path settings must be in a file called: "ocelot.SwaggerEndPoints.json", if instead you want to use another name for this file you could set the name as follows (without the .json extension): +```CSharp + WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + .AddOcelotWithSwaggerSupport(fileOfSwaggerEndPoints: "ocelot.swagger") + }) + .UseStartup(folder: "Configuration"); +``` +Optionally you can put the configuration files in a folder, and for that you have to set the extension as follows: +```CSharp + WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(); + }) + .UseStartup(folder: "Configuration"); +``` +Optionally you can also add configuration files with the format ocelot.exampleName.json per environment, to use this functionality you must configure the extension as follows: +```CSharp + WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + .AddOcelotWithSwaggerSupport(environment: hostingContext.HostingEnvironment); + }) + .UseStartup(folder: "Configuration"); +``` + 4. In the `ConfigureServices` method of `Startup.cs`, register the SwaggerForOcelot generator. ```CSharp diff --git a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs index de2b56b..0745e9e 100644 --- a/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs +++ b/src/MMLib.SwaggerForOcelot/ServiceDiscovery/SwaggerServiceDiscoveryProvider.cs @@ -52,7 +52,7 @@ private async Task GetSwaggerUri(SwaggerEndPointConfig endPoint, RouteOptio var downstreamRoute = new DownstreamRouteBuilder() .WithUseServiceDiscovery(true) .WithServiceName(endPoint.Service.Name) - .WithServiceNamespace(route.ServiceNamespace) + .WithServiceNamespace(route?.ServiceNamespace) .Build(); var serviceProvider = _serviceDiscovery.Get(conf, downstreamRoute); From 612f0b33b152f4e57dccad3c278257637adaea37 Mon Sep 17 00:00:00 2001 From: Burgyn Date: Thu, 18 Jun 2020 07:10:55 +0200 Subject: [PATCH 13/18] Remove ocelot.json from demo --- demo/ApiGateway/ocelot.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 demo/ApiGateway/ocelot.json diff --git a/demo/ApiGateway/ocelot.json b/demo/ApiGateway/ocelot.json deleted file mode 100644 index 6f71d7d..0000000 --- a/demo/ApiGateway/ocelot.json +++ /dev/null @@ -1 +0,0 @@ -{"Routes":[{"SwaggerKey":"contacts","DownstreamPathTemplate":"/api/{everything}","UpstreamPathTemplate":"/api/contacts/{everything}","UpstreamHttpMethod":["Get"],"DownstreamHttpMethod":null,"AddHeadersToRequest":{},"UpstreamHeaderTransform":{},"DownstreamHeaderTransform":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"ChangeDownstreamPathTemplate":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0,"Region":null},"RouteIsCaseSensitive":false,"ServiceName":"contacts","ServiceNamespace":null,"DownstreamScheme":null,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancerOptions":{"Type":null,"Key":null,"Expiry":0},"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0},"AuthenticationOptions":{"AuthenticationProviderKey":null,"AllowedScopes":[]},"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true,"MaxConnectionsPerServer":2147483647},"DownstreamHostAndPorts":[],"UpstreamHost":null,"Key":null,"DelegatingHandlers":[],"Priority":1,"Timeout":0,"DangerousAcceptAnyServerCertificateValidator":false,"SecurityOptions":{"IPAllowedList":[],"IPBlockedList":[]},"DownstreamHttpVersion":null},{"SwaggerKey":"orders","DownstreamPathTemplate":"/api/{everything}","UpstreamPathTemplate":"/api/orders/{everything}","UpstreamHttpMethod":[],"DownstreamHttpMethod":null,"AddHeadersToRequest":{},"UpstreamHeaderTransform":{},"DownstreamHeaderTransform":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"ChangeDownstreamPathTemplate":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0,"Region":null},"RouteIsCaseSensitive":false,"ServiceName":"orders","ServiceNamespace":null,"DownstreamScheme":"http","QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancerOptions":{"Type":null,"Key":null,"Expiry":0},"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0},"AuthenticationOptions":{"AuthenticationProviderKey":null,"AllowedScopes":[]},"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true,"MaxConnectionsPerServer":2147483647},"DownstreamHostAndPorts":[],"UpstreamHost":null,"Key":null,"DelegatingHandlers":[],"Priority":1,"Timeout":0,"DangerousAcceptAnyServerCertificateValidator":false,"SecurityOptions":{"IPAllowedList":[],"IPBlockedList":[]},"DownstreamHttpVersion":null},{"SwaggerKey":"projects","DownstreamPathTemplate":"/api/{everything}","UpstreamPathTemplate":"/api/projects/{everything}","UpstreamHttpMethod":[],"DownstreamHttpMethod":null,"AddHeadersToRequest":{},"UpstreamHeaderTransform":{},"DownstreamHeaderTransform":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"ChangeDownstreamPathTemplate":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0,"Region":null},"RouteIsCaseSensitive":false,"ServiceName":"projects","ServiceNamespace":null,"DownstreamScheme":null,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancerOptions":{"Type":null,"Key":null,"Expiry":0},"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0},"AuthenticationOptions":{"AuthenticationProviderKey":null,"AllowedScopes":[]},"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true,"MaxConnectionsPerServer":2147483647},"DownstreamHostAndPorts":[],"UpstreamHost":null,"Key":null,"DelegatingHandlers":[],"Priority":1,"Timeout":0,"DangerousAcceptAnyServerCertificateValidator":false,"SecurityOptions":{"IPAllowedList":[],"IPBlockedList":[]},"DownstreamHttpVersion":null}],"DynamicRoutes":[],"Aggregates":[],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Scheme":null,"Host":null,"Port":0,"Type":null,"Token":null,"ConfigurationKey":null,"PollingInterval":0,"Namespace":null},"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":null,"RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429},"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"BaseUrl":null,"LoadBalancerOptions":{"Type":null,"Key":null,"Expiry":0},"DownstreamScheme":null,"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true,"MaxConnectionsPerServer":2147483647},"DownstreamHttpVersion":null},"SwaggerEndPoints":[{"Key":"contacts","VersionPlaceholder":"{version}","KeyToPath":"contacts","Config":[{"Name":"Contacts API","Version":"v1","Url":"https://localhost:44359/swagger/v1/swagger.json","Service":null}],"HostOverride":null,"TransformByOcelotConfig":true},{"Key":"projects","VersionPlaceholder":"{version}","KeyToPath":"projects","Config":[{"Name":"Projects API","Version":"v1","Url":"https://localhost:44304/swagger/v1/swagger.json","Service":null}],"HostOverride":null,"TransformByOcelotConfig":true},{"Key":"orders","VersionPlaceholder":"{version}","KeyToPath":"orders","Config":[{"Name":"Orders API","Version":"v0.9","Url":"https://localhost:44343/swagger/v0.9/swagger.json","Service":null},{"Name":"Orders API","Version":"v1","Url":"https://localhost:44343/swagger/v1/swagger.json","Service":null},{"Name":"Orders API","Version":"v2","Url":"https://localhost:44343/swagger/v2/swagger.json","Service":null},{"Name":"Orders API","Version":"v3","Url":"https://localhost:44343/swagger/v3/swagger.json","Service":null}],"HostOverride":null,"TransformByOcelotConfig":true}]} \ No newline at end of file From 215c2d9f4108fdc5cf581df34a76a27cb00d0eff Mon Sep 17 00:00:00 2001 From: Burgyn Date: Thu, 18 Jun 2020 07:11:05 +0200 Subject: [PATCH 14/18] Fix demo --- .gitignore | 1 + demo/ApiGateway/ApiGateway.csproj | 2 +- .../ocelot.SwaggerEndPoints.json | 30 +++++++++++++++---- .../Configuration/ocelot.global.json | 9 ++++++ 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 demo/ApiGateway/Configuration/ocelot.global.json diff --git a/.gitignore b/.gitignore index 3e759b7..f995c92 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +demo/ApiGateway/ocelot.json diff --git a/demo/ApiGateway/ApiGateway.csproj b/demo/ApiGateway/ApiGateway.csproj index b254574..512afae 100644 --- a/demo/ApiGateway/ApiGateway.csproj +++ b/demo/ApiGateway/ApiGateway.csproj @@ -7,7 +7,7 @@ - + diff --git a/demo/ApiGateway/Configuration/ocelot.SwaggerEndPoints.json b/demo/ApiGateway/Configuration/ocelot.SwaggerEndPoints.json index f015452..d7029f8 100644 --- a/demo/ApiGateway/Configuration/ocelot.SwaggerEndPoints.json +++ b/demo/ApiGateway/Configuration/ocelot.SwaggerEndPoints.json @@ -6,7 +6,10 @@ { "Name": "Contacts API", "Version": "v1", - "Url": "https://localhost:44359/swagger/v1/swagger.json" + "Service": { + "Name": "contacts", + "Path": "/swagger/v1/swagger.json" + } } ] }, @@ -16,7 +19,10 @@ { "Name": "Projects API", "Version": "v1", - "Url": "https://localhost:44304/swagger/v1/swagger.json" + "Service": { + "Name": "projects", + "Path": "/swagger/v1/swagger.json" + } } ] }, @@ -26,22 +32,34 @@ { "Name": "Orders API", "Version": "v0.9", - "Url": "https://localhost:44343/swagger/v0.9/swagger.json" + "Service": { + "Name": "orders", + "Path": "/swagger/v0.9/swagger.json" + } }, { "Name": "Orders API", "Version": "v1", - "Url": "https://localhost:44343/swagger/v1/swagger.json" + "Service": { + "Name": "orders", + "Path": "/swagger/v1/swagger.json" + } }, { "Name": "Orders API", "Version": "v2", - "Url": "https://localhost:44343/swagger/v2/swagger.json" + "Service": { + "Name": "orders", + "Path": "/swagger/v2/swagger.json" + } }, { "Name": "Orders API", "Version": "v3", - "Url": "https://localhost:44343/swagger/v3/swagger.json" + "Service": { + "Name": "orders", + "Path": "/swagger/v3/swagger.json" + } } ] } diff --git a/demo/ApiGateway/Configuration/ocelot.global.json b/demo/ApiGateway/Configuration/ocelot.global.json new file mode 100644 index 0000000..c3fab8d --- /dev/null +++ b/demo/ApiGateway/Configuration/ocelot.global.json @@ -0,0 +1,9 @@ +{ + "GlobalConfiguration": { + "BaseUrl": "http://localhost", + "ServiceDiscoveryProvider": { + "Type": "AppConfiguration", + "PollingIntervalSeconds": 10000 + } + } +} From fbb01d64beea8def2bdd043f6ba50d7f61275ae6 Mon Sep 17 00:00:00 2001 From: Burgyn Date: Thu, 18 Jun 2020 07:21:16 +0200 Subject: [PATCH 15/18] Documentation --- README.md | 87 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index b838af8..c63492a 100644 --- a/README.md +++ b/README.md @@ -91,50 +91,13 @@ Direct via `http://ocelotprojecturl:port/swagger` provides documentation for dow > `SwaggerEndPoint` is configuration for downstream service swagger generator endpoint. Property `Key` is used to pair with the Route configuration. `Name` is displayed in the combobox. `Url` is downstream service swagger generator endpoint. -Optionally you can use the ocelot utility to load the apigateway configuration into multiple configuration files named as follows: ocelot.exampleName.json, but to activate this feature you need to use the following extension: -```CSharp - WebHost.CreateDefaultBuilder(args) - .ConfigureAppConfiguration((hostingContext, config) => - { - config.AddOcelotWithSwaggerSupport(); - }) - .UseStartup(); -``` -using this extension the swagger path settings must be in a file called: "ocelot.SwaggerEndPoints.json", if instead you want to use another name for this file you could set the name as follows (without the .json extension): -```CSharp - WebHost.CreateDefaultBuilder(args) - .ConfigureAppConfiguration((hostingContext, config) => - { - .AddOcelotWithSwaggerSupport(fileOfSwaggerEndPoints: "ocelot.swagger") - }) - .UseStartup(folder: "Configuration"); -``` -Optionally you can put the configuration files in a folder, and for that you have to set the extension as follows: -```CSharp - WebHost.CreateDefaultBuilder(args) - .ConfigureAppConfiguration((hostingContext, config) => - { - config.AddOcelotWithSwaggerSupport(); - }) - .UseStartup(folder: "Configuration"); -``` -Optionally you can also add configuration files with the format ocelot.exampleName.json per environment, to use this functionality you must configure the extension as follows: -```CSharp - WebHost.CreateDefaultBuilder(args) - .ConfigureAppConfiguration((hostingContext, config) => - { - .AddOcelotWithSwaggerSupport(environment: hostingContext.HostingEnvironment); - }) - .UseStartup(folder: "Configuration"); -``` - 4. In the `ConfigureServices` method of `Startup.cs`, register the SwaggerForOcelot generator. ```CSharp services.AddSwaggerForOcelot(Configuration); ``` -6. In `Configure` method, insert the `SwaggerForOcelot` middleware to expose interactive documentation. +5. In `Configure` method, insert the `SwaggerForOcelot` middleware to expose interactive documentation. ```CSharp app.UseSwaggerForOcelotUI(opt => { @@ -175,7 +138,7 @@ app.UseSwaggerForOcelotUI(opt => { }) ``` -7. Show your microservices interactive documentation. +6. Show your microservices interactive documentation. > `http://ocelotserviceurl/swagger` @@ -282,6 +245,52 @@ The key is to set it up property `TransformByOcelotConfig` to `false`, because i ![ocelot docs](./demo/ocelotdocs.png) +## Merging configuration files + +Optionally you can use the Ocelot feature [Merging configuration files](https://ocelot.readthedocs.io/en/latest/features/configuration.html#merging-configuration-files) to load the apigateway configuration from multiple configuration files named as follows: `ocelot.exampleName.json`. To activate this feature you need to use the following extension: + +```CSharp +WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(); + }) + .UseStartup(); +``` + +Using this extension the swagger path settings must be in a file called: `ocelot.SwaggerEndPoints.json`. If instead you want to use another name for this file you could set the name as follows _(without the .json extension)_: + +```CSharp +WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(fileOfSwaggerEndPoints: "ocelot.swagger") + }) + .UseStartup(); +``` + +Optionally you can put the configuration files in a folder, and for that you have to set the extension as follows: + +```CSharp +WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(); + }) + .UseStartup(folder: "Configuration"); +``` + +Optionally you can also add configuration files with the format `ocelot.exampleName.json` per environment, to use this functionality you must configure the extension as follows: + +```CSharp +WebHost.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddOcelotWithSwaggerSupport(environment: hostingContext.HostingEnvironment); + }) + .UseStartup(folder: "Configuration"); +``` + ## Limitation - Now, this library support only `{everything}` as a wildcard in routing definition. #68 From d45cca77a464eb40fe33690220a3405a41d85b34 Mon Sep 17 00:00:00 2001 From: Burgyn Date: Thu, 18 Jun 2020 07:30:45 +0200 Subject: [PATCH 16/18] typo --- .../ConfigurationBuilderExtensions.cs | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 01a19a2..2cb99fd 100644 --- a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -16,6 +16,8 @@ namespace MMLib.SwaggerForOcelot.DependencyInjection /// public static class ConfigurationBuilderExtensions { + private const string OcelotFilePattern = @"^ocelot\.(.*?)\.json$"; + /// /// Extension for compatibility of functionality multifile of ocelot /// @@ -31,9 +33,8 @@ public static IConfigurationBuilder AddOcelotWithSwaggerSupport( string fileOfSwaggerEndPoints = SwaggerForOcelotFileOptions.SwaggerEndPointsConfigFile) { List files = GetListOfOcelotFiles(folder, environment?.EnvironmentName); - - SwaggerFileConfiguration fileConfigurationMerged = MergeFilesOfOcelotConfiguration(files, fileOfSwaggerEndPoints, environment?.EnvironmentName); - + SwaggerFileConfiguration fileConfigurationMerged = + MergeFilesOfOcelotConfiguration(files, fileOfSwaggerEndPoints, environment?.EnvironmentName); string jsonFileConfiguration = JsonConvert.SerializeObject(fileConfigurationMerged); File.WriteAllText(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, jsonFileConfiguration); @@ -52,12 +53,12 @@ public static IConfigurationBuilder AddOcelotWithSwaggerSupport( /// a var of type List with the list of files of configuration of ocelot private static List GetListOfOcelotFiles(string folder, string nameEnvirotment) { - string subConfigPattern = @"^ocelot\.(.*?)\.json$"; - - var reg = new Regex(subConfigPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline); + var reg = new Regex(OcelotFilePattern, RegexOptions.IgnoreCase | RegexOptions.Singleline); + IEnumerable ocelotFiles = + new DirectoryInfo(folder) + .EnumerateFiles() + .Where(fi => reg.IsMatch(fi.Name)); - IEnumerable ocelotFiles = new DirectoryInfo(folder).EnumerateFiles() - .Where(fi => reg.IsMatch(fi.Name)); if (!nameEnvirotment.IsNullOrWhiteSpace()) { ocelotFiles = ocelotFiles.Where(fi => fi.Name.Contains(nameEnvirotment)); @@ -66,25 +67,6 @@ private static List GetListOfOcelotFiles(string folder, string nameEnv return ocelotFiles.ToList(); } - /// - /// Check if name of file is the file of configuration by environment - /// - /// - /// - /// - /// a bool with a result of checked - private static bool IsGlobalConfigurationFile(string environmentName, string fileName, string fileConfigurationName) - { - if (environmentName.IsNullOrWhiteSpace()) - { - return fileName.Equals($"{fileConfigurationName}.json", StringComparison.OrdinalIgnoreCase); - } - else - { - return fileName.Equals($"{fileConfigurationName}.{environmentName}.json", StringComparison.OrdinalIgnoreCase); - } - } - /// /// Merge a list of files of configuration of Ocelot with options SwaggerEnpoints /// @@ -92,7 +74,10 @@ private static bool IsGlobalConfigurationFile(string environmentName, string fil /// /// /// a object SwaggerFileConfiguration with the configuration of file - private static SwaggerFileConfiguration MergeFilesOfOcelotConfiguration(List files, string fileOfSwaggerEndPoints, string environmentName) + private static SwaggerFileConfiguration MergeFilesOfOcelotConfiguration( + List files, + string fileOfSwaggerEndPoints, + string environmentName) { SwaggerFileConfiguration fileConfigurationMerged = new SwaggerFileConfiguration(); @@ -101,7 +86,7 @@ private static SwaggerFileConfiguration MergeFilesOfOcelotConfiguration(List(linesOfFile); - if (files.Count > 1 && itemFile.Name.Equals(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, StringComparison.OrdinalIgnoreCase)) + if (CanContinue(files, itemFile)) { continue; } @@ -121,6 +106,22 @@ private static SwaggerFileConfiguration MergeFilesOfOcelotConfiguration(List files, FileInfo itemFile) + => files.Count > 1 + && itemFile.Name.Equals(SwaggerForOcelotFileOptions.PrimaryOcelotConfigFile, StringComparison.OrdinalIgnoreCase); + + /// + /// Check if name of file is the file of configuration by environment + /// + /// + /// + /// + /// a bool with a result of checked + private static bool IsGlobalConfigurationFile(string environmentName, string fileName, string fileConfigurationName) + => environmentName.IsNullOrWhiteSpace() + ? fileName.Equals($"{fileConfigurationName}.json", StringComparison.OrdinalIgnoreCase) + : fileName.Equals($"{fileConfigurationName}.{environmentName}.json", StringComparison.OrdinalIgnoreCase); + #endregion } } From b4ed0782f5438286e003fc77eef765f710100ad6 Mon Sep 17 00:00:00 2001 From: Burgyn Date: Thu, 18 Jun 2020 07:47:37 +0200 Subject: [PATCH 17/18] IsNullOrEmpty --- .../Middleware/SwaggerForOcelotMiddleware.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs index 16b468b..9dea092 100644 --- a/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs +++ b/src/MMLib.SwaggerForOcelot/Middleware/SwaggerForOcelotMiddleware.cs @@ -131,7 +131,7 @@ private void AddHeaders(HttpClient httpClient) private void SetHttpVersion(HttpClient httpClient, IEnumerable routeOptions) { string downstreamHttpVersion = routeOptions.FirstOrDefault()?.DownstreamHttpVersion; - if (downstreamHttpVersion != null && downstreamHttpVersion != string.Empty) + if (!downstreamHttpVersion.IsNullOrEmpty()) { int[] version = downstreamHttpVersion.Split('.').Select(int.Parse).ToArray(); httpClient.DefaultRequestVersion = new Version(version[0], version[1]); From f1c50dbe724e472a8d0115a6ff80df908fd6c2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Jim=C3=A9nez?= Date: Thu, 18 Jun 2020 13:45:41 +0200 Subject: [PATCH 18/18] * Change object IWebHostEnvironment for a object IHostEnvironment new of net core --- demo/ApiGateway/Program.cs | 7 ++++--- .../DependencyInjection/ConfigurationBuilderExtensions.cs | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/ApiGateway/Program.cs b/demo/ApiGateway/Program.cs index 2157126..029fd7b 100644 --- a/demo/ApiGateway/Program.cs +++ b/demo/ApiGateway/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; using MMLib.SwaggerForOcelot.DependencyInjection; namespace ApiGateway @@ -12,8 +13,8 @@ public static void Main(string[] args) CreateWebHostBuilder(args).Build().Run(); } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) + public static IHostBuilder CreateWebHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config @@ -25,6 +26,6 @@ public static IWebHostBuilder CreateWebHostBuilder(string[] args) => .AddOcelotWithSwaggerSupport(folder: "Configuration") .AddEnvironmentVariables(); }) - .UseStartup(); + .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup()); } } diff --git a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 2cb99fd..2bf7673 100644 --- a/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/MMLib.SwaggerForOcelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -1,6 +1,7 @@ using Kros.Extensions; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; using MMLib.SwaggerForOcelot.Configuration; using Newtonsoft.Json; using System; @@ -28,7 +29,7 @@ public static class ConfigurationBuilderExtensions /// a Object IConfigurationBuilder public static IConfigurationBuilder AddOcelotWithSwaggerSupport( this IConfigurationBuilder builder, - IWebHostEnvironment environment = null, + IHostEnvironment environment = null, string folder = "/", string fileOfSwaggerEndPoints = SwaggerForOcelotFileOptions.SwaggerEndPointsConfigFile) {