From 75aac77310b3a1621f19f18364b45f1b9b9350b7 Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sat, 4 Feb 2023 12:48:00 +0100 Subject: [PATCH 1/3] :sparkles: Add API Gateway (Ocelot) --- ApiGateway/ApiGateway.csproj | 14 ++++ ApiGateway/Program.cs | 32 ++++++++ ApiGateway/Properties/launchSettings.json | 31 ++++++++ ApiGateway/appsettings.Development.json | 8 ++ ApiGateway/appsettings.json | 9 +++ ApiGateway/ocelot.json | 93 +++++++++++++++++++++++ cat_cafe/cat_cafe.sln | 8 +- 7 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 ApiGateway/ApiGateway.csproj create mode 100644 ApiGateway/Program.cs create mode 100644 ApiGateway/Properties/launchSettings.json create mode 100644 ApiGateway/appsettings.Development.json create mode 100644 ApiGateway/appsettings.json create mode 100644 ApiGateway/ocelot.json diff --git a/ApiGateway/ApiGateway.csproj b/ApiGateway/ApiGateway.csproj new file mode 100644 index 0000000..5302daa --- /dev/null +++ b/ApiGateway/ApiGateway.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/ApiGateway/Program.cs b/ApiGateway/Program.cs new file mode 100644 index 0000000..546b5ae --- /dev/null +++ b/ApiGateway/Program.cs @@ -0,0 +1,32 @@ +using Ocelot.DependencyInjection; +using Ocelot.Middleware; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true); +builder.Services.AddOcelot(builder.Configuration); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +await app.UseOcelot(); + +app.Run(); diff --git a/ApiGateway/Properties/launchSettings.json b/ApiGateway/Properties/launchSettings.json new file mode 100644 index 0000000..936506d --- /dev/null +++ b/ApiGateway/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:17820", + "sslPort": 44370 + } + }, + "profiles": { + "ApiGateway": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:5003;http://localhost:5197", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ApiGateway/appsettings.Development.json b/ApiGateway/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/ApiGateway/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ApiGateway/appsettings.json b/ApiGateway/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/ApiGateway/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/ApiGateway/ocelot.json b/ApiGateway/ocelot.json new file mode 100644 index 0000000..ce3623b --- /dev/null +++ b/ApiGateway/ocelot.json @@ -0,0 +1,93 @@ +{ + "GlobalConfiguration": { + "BaseUrl": "https://localhost:5003" + }, + "Routes": [ + { + "UpstreamPathTemplate": "/gateway/cats", + "UpstreamHttpMethod": [ "Get" ], + "DownstreamPathTemplate": "/api/cats", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + { + "UpstreamPathTemplate": "/gateway/cats", + "UpstreamHttpMethod": [ "Post" ], + "DownstreamPathTemplate": "/api/cats", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + { + "UpstreamPathTemplate": "/gateway/cats/{id}", + "UpstreamHttpMethod": [ "Get", "Put", "Delete" ], + "DownstreamPathTemplate": "/api/cats/{id}", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + + { + "UpstreamPathTemplate": "/gateway/bars", + "UpstreamHttpMethod": [ "Get", "Post" ], + "DownstreamPathTemplate": "/api/bars", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + { + "UpstreamPathTemplate": "/gateway/bars/{id}", + "UpstreamHttpMethod": [ "Get", "Put", "Delete" ], + "DownstreamPathTemplate": "/api/bars/{id}", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + + { + "UpstreamPathTemplate": "/gateway/customers", + "UpstreamHttpMethod": [ "Get", "Post" ], + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + }, + { + "UpstreamPathTemplate": "/gateway/customers/{id}", + "UpstreamHttpMethod": [ "Get", "Put", "Delete" ], + "DownstreamPathTemplate": "/api/customers/{id}", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ] + } + ] +} \ No newline at end of file diff --git a/cat_cafe/cat_cafe.sln b/cat_cafe/cat_cafe.sln index 86b7799..332759b 100644 --- a/cat_cafe/cat_cafe.sln +++ b/cat_cafe/cat_cafe.sln @@ -5,7 +5,9 @@ VisualStudioVersion = 17.2.32616.157 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cat_cafe", "cat_cafe.csproj", "{CC02D05A-3817-4D0A-8766-3FEE0C90941B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "..\Tests\Tests.csproj", "{039A9A95-25ED-4632-9C4B-0AB4E5B5A7B4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "..\Tests\Tests.csproj", "{039A9A95-25ED-4632-9C4B-0AB4E5B5A7B4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiGateway", "..\ApiGateway\ApiGateway.csproj", "{18B6DE0C-D6D7-452F-94A2-83DB98194D6F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +23,10 @@ Global {039A9A95-25ED-4632-9C4B-0AB4E5B5A7B4}.Debug|Any CPU.Build.0 = Debug|Any CPU {039A9A95-25ED-4632-9C4B-0AB4E5B5A7B4}.Release|Any CPU.ActiveCfg = Release|Any CPU {039A9A95-25ED-4632-9C4B-0AB4E5B5A7B4}.Release|Any CPU.Build.0 = Release|Any CPU + {18B6DE0C-D6D7-452F-94A2-83DB98194D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18B6DE0C-D6D7-452F-94A2-83DB98194D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18B6DE0C-D6D7-452F-94A2-83DB98194D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18B6DE0C-D6D7-452F-94A2-83DB98194D6F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- 2.36.3 From 9798de45604bc4d6d76c030220dfa4b07673bddd Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sat, 4 Feb 2023 12:59:15 +0100 Subject: [PATCH 2/3] :lock: Add rate limiting for get-all calls --- ApiGateway/ocelot.json | 48 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/ApiGateway/ocelot.json b/ApiGateway/ocelot.json index ce3623b..e75f74d 100644 --- a/ApiGateway/ocelot.json +++ b/ApiGateway/ocelot.json @@ -13,7 +13,13 @@ "Host": "localhost", "Port": 7229 } - ] + ], + "RateLimitOptions": { + "EnableRateLimiting": true, + "Period": "1 second", + "PeriodTimespan": 1, + "Limit": 1 + } }, { "UpstreamPathTemplate": "/gateway/cats", @@ -42,7 +48,25 @@ { "UpstreamPathTemplate": "/gateway/bars", - "UpstreamHttpMethod": [ "Get", "Post" ], + "UpstreamHttpMethod": [ "Get" ], + "DownstreamPathTemplate": "/api/bars", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ], + "RateLimitOptions": { + "EnableRateLimiting": true, + "Period": "1 second", + "PeriodTimespan": 1, + "Limit": 1 + } + }, + { + "UpstreamPathTemplate": "/gateway/bars", + "UpstreamHttpMethod": [ "Post" ], "DownstreamPathTemplate": "/api/bars", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ @@ -67,7 +91,25 @@ { "UpstreamPathTemplate": "/gateway/customers", - "UpstreamHttpMethod": [ "Get", "Post" ], + "UpstreamHttpMethod": [ "Get" ], + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 7229 + } + ], + "RateLimitOptions": { + "EnableRateLimiting": true, + "Period": "1 second", + "PeriodTimespan": 1, + "Limit": 1 + } + }, + { + "UpstreamPathTemplate": "/gateway/customers", + "UpstreamHttpMethod": [ "Post" ], "DownstreamPathTemplate": "/api/customers", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ -- 2.36.3 From c9e3ca22b935e61060a7d183664a5a459c477161 Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sat, 4 Feb 2023 13:09:38 +0100 Subject: [PATCH 3/3] :ambulance: Fix rate limiting, add cache for customers --- ApiGateway/ApiGateway.csproj | 1 + ApiGateway/Program.cs | 7 ++++++- ApiGateway/ocelot.json | 11 ++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ApiGateway/ApiGateway.csproj b/ApiGateway/ApiGateway.csproj index 5302daa..1f9898b 100644 --- a/ApiGateway/ApiGateway.csproj +++ b/ApiGateway/ApiGateway.csproj @@ -8,6 +8,7 @@ + diff --git a/ApiGateway/Program.cs b/ApiGateway/Program.cs index 546b5ae..2801331 100644 --- a/ApiGateway/Program.cs +++ b/ApiGateway/Program.cs @@ -1,3 +1,4 @@ +using Ocelot.Cache.CacheManager; using Ocelot.DependencyInjection; using Ocelot.Middleware; @@ -10,7 +11,11 @@ builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true); -builder.Services.AddOcelot(builder.Configuration); +builder.Services.AddOcelot(builder.Configuration) + .AddCacheManager(x => +{ + x.WithDictionaryHandle(); +}); var app = builder.Build(); diff --git a/ApiGateway/ocelot.json b/ApiGateway/ocelot.json index e75f74d..8451b05 100644 --- a/ApiGateway/ocelot.json +++ b/ApiGateway/ocelot.json @@ -16,7 +16,7 @@ ], "RateLimitOptions": { "EnableRateLimiting": true, - "Period": "1 second", + "Period": "1s", "PeriodTimespan": 1, "Limit": 1 } @@ -59,7 +59,7 @@ ], "RateLimitOptions": { "EnableRateLimiting": true, - "Period": "1 second", + "Period": "1s", "PeriodTimespan": 1, "Limit": 1 } @@ -100,11 +100,8 @@ "Port": 7229 } ], - "RateLimitOptions": { - "EnableRateLimiting": true, - "Period": "1 second", - "PeriodTimespan": 1, - "Limit": 1 + "FileCacheOptions": { + "TtlSeconds": 10 } }, { -- 2.36.3