From e74e829cf467bea15e61f0045f5bd6d1ea78e06e Mon Sep 17 00:00:00 2001 From: cpshahan Date: Thu, 28 Mar 2024 18:57:11 -0400 Subject: [PATCH 01/12] Renamed GameMicroService to APIGateway and the word micro to gateway in a lot of places and renamed the project folder and project path in the solution folder. --- GameMicroServer.sln => APIGateway.sln | 2 +- .../APIGateway.csproj | 0 .../Controllers/GatewayController.cs | 8 ++++---- {GameMicroServer => APIGateway}/Dockerfile | 0 {GameMicroServer => APIGateway}/GameInfo.cs | 2 +- {GameMicroServer => APIGateway}/Program.cs | 0 .../Properties/launchSettings.json | 2 +- .../appsettings.Development.json | 0 {GameMicroServer => APIGateway}/appsettings.json | 0 9 files changed, 7 insertions(+), 7 deletions(-) rename GameMicroServer.sln => APIGateway.sln (86%) rename GameMicroServer/GameMicroServer.csproj => APIGateway/APIGateway.csproj (100%) rename GameMicroServer/Controllers/microController.cs => APIGateway/Controllers/GatewayController.cs (93%) rename {GameMicroServer => APIGateway}/Dockerfile (100%) rename {GameMicroServer => APIGateway}/GameInfo.cs (94%) rename {GameMicroServer => APIGateway}/Program.cs (100%) rename {GameMicroServer => APIGateway}/Properties/launchSettings.json (97%) rename {GameMicroServer => APIGateway}/appsettings.Development.json (100%) rename {GameMicroServer => APIGateway}/appsettings.json (100%) diff --git a/GameMicroServer.sln b/APIGateway.sln similarity index 86% rename from GameMicroServer.sln rename to APIGateway.sln index 01da97b..c10c64a 100644 --- a/GameMicroServer.sln +++ b/APIGateway.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.34221.43 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameMicroServer", "GameMicroServer\GameMicroServer.csproj", "{C8787DE3-73A1-4FA9-BC23-865FCF0560AF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APIGateway", "APIGateway\APIGateway.csproj", "{C8787DE3-73A1-4FA9-BC23-865FCF0560AF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/GameMicroServer/GameMicroServer.csproj b/APIGateway/APIGateway.csproj similarity index 100% rename from GameMicroServer/GameMicroServer.csproj rename to APIGateway/APIGateway.csproj diff --git a/GameMicroServer/Controllers/microController.cs b/APIGateway/Controllers/GatewayController.cs similarity index 93% rename from GameMicroServer/Controllers/microController.cs rename to APIGateway/Controllers/GatewayController.cs index 931e493..0a13ef3 100644 --- a/GameMicroServer/Controllers/microController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -8,11 +8,11 @@ using Microsoft.Extensions.Caching.Distributed; using System.Text.Json; -namespace Micro +namespace Gateway { [ApiController] [Route("[controller]")] - public class MicroController : ControllerBase + public class GatewayController : ControllerBase { private static readonly List TheInfo = new List { @@ -54,9 +54,9 @@ public class MicroController : ControllerBase }; - private readonly ILogger _logger; + private readonly ILogger _logger; - public MicroController(ILogger logger) + public GatewayController(ILogger logger) { _logger = logger; } diff --git a/GameMicroServer/Dockerfile b/APIGateway/Dockerfile similarity index 100% rename from GameMicroServer/Dockerfile rename to APIGateway/Dockerfile diff --git a/GameMicroServer/GameInfo.cs b/APIGateway/GameInfo.cs similarity index 94% rename from GameMicroServer/GameInfo.cs rename to APIGateway/GameInfo.cs index 8732214..c3110d3 100644 --- a/GameMicroServer/GameInfo.cs +++ b/APIGateway/GameInfo.cs @@ -1,4 +1,4 @@ -namespace Micro +namespace Gateway { public class GameInfo { diff --git a/GameMicroServer/Program.cs b/APIGateway/Program.cs similarity index 100% rename from GameMicroServer/Program.cs rename to APIGateway/Program.cs diff --git a/GameMicroServer/Properties/launchSettings.json b/APIGateway/Properties/launchSettings.json similarity index 97% rename from GameMicroServer/Properties/launchSettings.json rename to APIGateway/Properties/launchSettings.json index fdaca06..e7be61f 100644 --- a/GameMicroServer/Properties/launchSettings.json +++ b/APIGateway/Properties/launchSettings.json @@ -1,6 +1,6 @@ { "profiles": { - "GameMicroServer": { + "APIGateway": { "commandName": "Project", "launchBrowser": true, "launchUrl": "swagger", diff --git a/GameMicroServer/appsettings.Development.json b/APIGateway/appsettings.Development.json similarity index 100% rename from GameMicroServer/appsettings.Development.json rename to APIGateway/appsettings.Development.json diff --git a/GameMicroServer/appsettings.json b/APIGateway/appsettings.json similarity index 100% rename from GameMicroServer/appsettings.json rename to APIGateway/appsettings.json From 79f880bf1004e729d350eaa4c6ef63c3d732405c Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 12:46:58 -0400 Subject: [PATCH 02/12] Added GetGamesAsync Call from MicroCleint in Bucstop to the GatewayController --- APIGateway/Controllers/GatewayController.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 0a13ef3..99ec046 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Caching.Distributed; using System.Text.Json; +using Microsoft.Extensions.Options; namespace Gateway { @@ -54,6 +55,25 @@ public class GatewayController : ControllerBase }; + public async Task GetGamesAsync() + { + try + { + var responseMessage = await this.client.GetAsync("/Micro"); + + if (responseMessage != null) + { + var stream = await responseMessage.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream, options); + } + } + catch (HttpRequestException ex) + { + _logger.LogError(ex.Message); + } + return new GameInfo[] { }; + } + private readonly ILogger _logger; public GatewayController(ILogger logger) From 1c3d759ebc3eae2421456f95279881beb4f9bbd6 Mon Sep 17 00:00:00 2001 From: evasiveace Date: Tue, 2 Apr 2024 12:55:41 -0400 Subject: [PATCH 03/12] Changed the GatewayController GameInfos to have error messages, to display that connection to the Microservice has failed. --- APIGateway/Controllers/GatewayController.cs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 99ec046..ef64b65 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -19,11 +19,11 @@ public class GatewayController : ControllerBase { new GameInfo { //Id = 1, - Title = "Snake", + Title = "Failed to retrieve from Microservice", //Content = "~/js/snake.js", - Author = "Fall 2023 Semester", + Author = "Failed to retrieve from Microservice", DateAdded = "", - Description = "Snake is a classic arcade game that challenges the player to control a snake-like creature that grows longer as it eats apples. The player must avoid hitting the walls or the snake's own body, which can end the game.\r\n", + Description = "Failed to retrieve from Microservice", HowTo = "Control with arrow keys.", //Thumbnail = "/images/snake.jpg" //640x360 resolution LeaderBoardStack = new Stack>(), @@ -31,24 +31,23 @@ public class GatewayController : ControllerBase }, new GameInfo { //Id = 2, - Title = "Tetris", + Title = "Failed to retrieve from Microservice", //Content = "~/js/tetris.js", - Author = "Fall 2023 Semester", + Author = "Failed to retrieve from Microservice", DateAdded = "", - Description = "Tetris is a classic arcade puzzle game where the player has to arrange falling blocks, also known as Tetronimos, of different shapes and colors to form complete rows on the bottom of the screen. The game gets faster and harder as the player progresses, and ends when the Tetronimos reach the top of the screen.", - HowTo = "Control with arrow keys: Up arrow to spin, down to speed up fall, space to insta-drop.", + Description = "Failed to retrieve from Microservice", //Thumbnail = "/images/tetris.jpg" LeaderBoardStack = new Stack>(), }, new GameInfo { //Id = 3, - Title = "Pong", + Title = "Failed to retrieve from Microservice", //Content = "~/js/pong.js", - Author = "Fall 2023 Semester", + Author = "Failed to retrieve from Microservice", DateAdded = "", - Description = "Pong is a classic arcade game where the player uses a paddle to hit a ball against a computer's paddle. Either party scores when the ball makes it past the opponent's paddle.", - HowTo = "Control with arrow keys.", + Description = "Failed to retrieve from Microservice", + HowTo = "Failed to retrieve from Microservice", //Thumbnail = "/images/pong.jpg" LeaderBoardStack = new Stack>(), }, From 2ec9c758ae0f25a9baef1ed693dc678b7ac64fa9 Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 12:57:59 -0400 Subject: [PATCH 04/12] Added JSON Serialization Options and HttpClient for reading gameInfo from Microservice --- APIGateway/Controllers/GatewayController.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 99ec046..88399c2 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -19,7 +19,7 @@ public class GatewayController : ControllerBase { new GameInfo { //Id = 1, - Title = "Snake", + Title = "Failed to retrive title from microservice", //Content = "~/js/snake.js", Author = "Fall 2023 Semester", DateAdded = "", @@ -74,6 +74,13 @@ public async Task GetGamesAsync() return new GameInfo[] { }; } + private readonly JsonSerializerOptions options = new JsonSerializerOptions() + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + private readonly HttpClient client; private readonly ILogger _logger; public GatewayController(ILogger logger) From ac6e5b7ae31651e26bc7984a7b7c9f7049d62356 Mon Sep 17 00:00:00 2001 From: evasiveace Date: Tue, 2 Apr 2024 13:15:45 -0400 Subject: [PATCH 05/12] Consistentency fixes --- APIGateway/Controllers/GatewayController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 2130eb6..3fc19cc 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -24,7 +24,7 @@ public class GatewayController : ControllerBase Author = "Failed to retrieve from Microservice", DateAdded = "", Description = "Failed to retrieve from Microservice", - HowTo = "Control with arrow keys.", + HowTo = "Failed to retrieve from Microservice", //Thumbnail = "/images/snake.jpg" //640x360 resolution LeaderBoardStack = new Stack>(), @@ -36,6 +36,7 @@ public class GatewayController : ControllerBase Author = "Failed to retrieve from Microservice", DateAdded = "", Description = "Failed to retrieve from Microservice", + HowTo = "Failed to retrieve from Microservice", //Thumbnail = "/images/tetris.jpg" LeaderBoardStack = new Stack>(), From 3535227127f21c2f77f26ea6ed6f52408aa0c9c6 Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 13:17:26 -0400 Subject: [PATCH 06/12] Added async Task GetGamesWithInfo() --- APIGateway/Controllers/GatewayController.cs | 36 +++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 2130eb6..69a2a70 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Caching.Distributed; using System.Text.Json; using Microsoft.Extensions.Options; +using System.Net.Http; namespace Gateway { @@ -54,6 +55,15 @@ public class GatewayController : ControllerBase }; + private readonly JsonSerializerOptions options = new JsonSerializerOptions() + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + private readonly HttpClient client; + private readonly ILogger _logger; + public async Task GetGamesAsync() { try @@ -73,14 +83,28 @@ public async Task GetGamesAsync() return new GameInfo[] { }; } - private readonly JsonSerializerOptions options = new JsonSerializerOptions() + /* + public async Task GetGamesWithInfo() { - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - }; + GameInfo[] gameInfos = await GetGamesAsync(); - private readonly HttpClient client; - private readonly ILogger _logger; + TheInfo + foreach (Game game in games) + { + GameInfo info = gameInfos.FirstOrDefault(x => x.Title == game.Title); + if (info != null) + { + game.Author = info.Author; + game.HowTo = info.HowTo; + game.DateAdded = info.DateAdded; + game.Description = $"{info.Description} \n {info.DateAdded}"; + game.LeaderBoard = info.LeaderBoard; + } + } + + return games; + } + */ public GatewayController(ILogger logger) { From 413c7e05e5307d547a4d6de44cd04136fe6de91d Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 19:30:56 -0400 Subject: [PATCH 07/12] Added HttpClient to web application so it can make Http requests without errors --- APIGateway/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/APIGateway/Program.cs b/APIGateway/Program.cs index 632a615..06a3690 100644 --- a/APIGateway/Program.cs +++ b/APIGateway/Program.cs @@ -7,6 +7,9 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +// Register HttpClient +builder.Services.AddHttpClient(); + var app = builder.Build(); // Configure the HTTP request pipeline. From 51eda57e7030fd1731cd8e4ff575b972f51d57f7 Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 19:32:49 -0400 Subject: [PATCH 08/12] Had ChatGPT instruct me how to read the list of Game Info from the Microservice. I needed the exact endpoint and you can find it on Swagger --- APIGateway/Controllers/GatewayController.cs | 125 ++++++-------------- 1 file changed, 37 insertions(+), 88 deletions(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 3f71200..8a94d55 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; - -using Microsoft.Extensions.Caching.Distributed; -using System.Text.Json; -using Microsoft.Extensions.Options; -using System.Net.Http; +using System.Net.Http.Json; namespace Gateway { @@ -16,106 +12,59 @@ namespace Gateway [Route("[controller]")] public class GatewayController : ControllerBase { - private static readonly List TheInfo = new List - { - new GameInfo { - //Id = 1, - Title = "Failed to retrieve from Microservice", - //Content = "~/js/snake.js", - Author = "Failed to retrieve from Microservice", - DateAdded = "", - Description = "Failed to retrieve from Microservice", - HowTo = "Failed to retrieve from Microservice", - //Thumbnail = "/images/snake.jpg" //640x360 resolution - LeaderBoardStack = new Stack>(), - - }, - new GameInfo { - //Id = 2, - Title = "Failed to retrieve from Microservice", - //Content = "~/js/tetris.js", - Author = "Failed to retrieve from Microservice", - DateAdded = "", - Description = "Failed to retrieve from Microservice", - HowTo = "Failed to retrieve from Microservice", - //Thumbnail = "/images/tetris.jpg" - LeaderBoardStack = new Stack>(), - - }, - new GameInfo { - //Id = 3, - Title = "Failed to retrieve from Microservice", - //Content = "~/js/pong.js", - Author = "Failed to retrieve from Microservice", - DateAdded = "", - Description = "Failed to retrieve from Microservice", - HowTo = "Failed to retrieve from Microservice", - //Thumbnail = "/images/pong.jpg" - LeaderBoardStack = new Stack>(), - }, - - }; + private readonly HttpClient _httpClient; + private readonly ILogger _logger; - private readonly JsonSerializerOptions options = new JsonSerializerOptions() + public GatewayController(HttpClient httpClient, ILogger logger) { - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - }; - - private readonly HttpClient client; - private readonly ILogger _logger; + _httpClient = httpClient; + _logger = logger; + } - public async Task GetGamesAsync() + [HttpGet] + public async Task> Get() { try { - var responseMessage = await this.client.GetAsync("/Micro"); + // Make a GET request to the microservice's endpoint + HttpResponseMessage response = await _httpClient.GetAsync("https://localhost:7223/Micro"); - if (responseMessage != null) + // Check if the request was successful + if (response.IsSuccessStatusCode) { - var stream = await responseMessage.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream, options); + // Deserialize the response content to a list of GameInfo objects + var gameInfoList = await response.Content.ReadAsAsync>(); + return gameInfoList; + } + else + { + _logger.LogError($"Failed to retrieve data from microservice. Status code: {response.StatusCode}"); + // Return a placeholder list of GameInfo objects indicating failure + return GenerateFailureResponse(); } } - catch (HttpRequestException ex) + catch (Exception ex) { - _logger.LogError(ex.Message); + _logger.LogError($"An error occurred while fetching data from microservice: {ex.Message}"); + // Return a placeholder list of GameInfo objects indicating failure + return GenerateFailureResponse(); } - return new GameInfo[] { }; } - /* - public async Task GetGamesWithInfo() + private IEnumerable GenerateFailureResponse() { - GameInfo[] gameInfos = await GetGamesAsync(); - - TheInfo - foreach (Game game in games) + // Generate a placeholder list of GameInfo objects indicating failure to retrieve data + return new List { - GameInfo info = gameInfos.FirstOrDefault(x => x.Title == game.Title); - if (info != null) + new GameInfo { - game.Author = info.Author; - game.HowTo = info.HowTo; - game.DateAdded = info.DateAdded; - game.Description = $"{info.Description} \n {info.DateAdded}"; - game.LeaderBoard = info.LeaderBoard; + Title = "Failed to retrieve from Microservice", + Author = "Failed to retrieve from Microservice", + Description = "Failed to retrieve from Microservice", + HowTo = "Failed to retrieve from Microservice", + LeaderBoardStack = new Stack>() } - } - - return games; - } - */ - - public GatewayController(ILogger logger) - { - _logger = logger; - } - - [HttpGet] - public IEnumerable Get() - { - return TheInfo; + }; } } } \ No newline at end of file From df47f8387b7b8e32890864717f2471d2407ebcd0 Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 19:33:27 -0400 Subject: [PATCH 09/12] Change APIGateway URL so not conflicts with Microservice --- APIGateway/Properties/launchSettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/APIGateway/Properties/launchSettings.json b/APIGateway/Properties/launchSettings.json index e7be61f..19f5ed8 100644 --- a/APIGateway/Properties/launchSettings.json +++ b/APIGateway/Properties/launchSettings.json @@ -8,7 +8,7 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "dotnetRunMessages": true, - "applicationUrl": "https://localhost:7223;http://localhost:5130" + "applicationUrl": "https://localhost:4141" }, "IIS Express": { "commandName": "IISExpress", From 392dc70dac3e5dbfb8c3970ea9c47ae0583873e2 Mon Sep 17 00:00:00 2001 From: cpshahan Date: Tue, 2 Apr 2024 19:34:09 -0400 Subject: [PATCH 10/12] Added ASPNet WebApi Client packege for ReadGamesAsync call --- APIGateway/APIGateway.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/APIGateway/APIGateway.csproj b/APIGateway/APIGateway.csproj index 1f43d86..f16dbbf 100644 --- a/APIGateway/APIGateway.csproj +++ b/APIGateway/APIGateway.csproj @@ -9,6 +9,7 @@ + From 8ed561af8c7358516f7e232576e2861b9a3d780b Mon Sep 17 00:00:00 2001 From: cpshahan Date: Thu, 4 Apr 2024 22:22:36 -0400 Subject: [PATCH 11/12] Added more comments about everything --- APIGateway/Controllers/GatewayController.cs | 25 ++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/APIGateway/Controllers/GatewayController.cs b/APIGateway/Controllers/GatewayController.cs index 8a94d55..194bcb2 100644 --- a/APIGateway/Controllers/GatewayController.cs +++ b/APIGateway/Controllers/GatewayController.cs @@ -8,12 +8,15 @@ namespace Gateway { + /// + /// Controller responsible for handling requests and responses at the gateway. + /// [ApiController] [Route("[controller]")] public class GatewayController : ControllerBase { - private readonly HttpClient _httpClient; - private readonly ILogger _logger; + private readonly HttpClient _httpClient; // Making readonly ensures thread safety + private readonly ILogger _logger; // Making readonly ensures thread safety public GatewayController(HttpClient httpClient, ILogger logger) { @@ -21,13 +24,17 @@ public GatewayController(HttpClient httpClient, ILogger logge _logger = logger; } + /// + /// Handles GET requests to retrieve game information from the microservice. + /// + /// A collection of GameInfo objects. [HttpGet] public async Task> Get() { try { // Make a GET request to the microservice's endpoint - HttpResponseMessage response = await _httpClient.GetAsync("https://localhost:7223/Micro"); + HttpResponseMessage response = await _httpClient.GetAsync("https://localhost:7223/Micro"); // URL might need to change for deployment // Check if the request was successful if (response.IsSuccessStatusCode) @@ -51,8 +58,16 @@ public async Task> Get() } } + /// + /// Generates a placeholder list of GameInfo objects indicating failure to retrieve data. + /// + /// A collection of GameInfo objects indicating failure. private IEnumerable GenerateFailureResponse() { + // Using IEnumerable allows flexibility in returning a placeholder response. + // It allows the method to return different types of collections (e.g., List, Array) if needed in the future. + // In this case, IEnumerable provides a simple way to return a list of failed responses. + // Generate a placeholder list of GameInfo objects indicating failure to retrieve data return new List { @@ -62,9 +77,9 @@ private IEnumerable GenerateFailureResponse() Author = "Failed to retrieve from Microservice", Description = "Failed to retrieve from Microservice", HowTo = "Failed to retrieve from Microservice", - LeaderBoardStack = new Stack>() + LeaderBoardStack = new Stack>() // Initializing an empty stack } }; } } -} \ No newline at end of file +} From 1a65061e33c2a94ed8314176f0e1e49b548ddb94 Mon Sep 17 00:00:00 2001 From: Patrick Vergason Date: Mon, 8 Apr 2024 21:28:16 -0400 Subject: [PATCH 12/12] Added timestamps classes and updated Program.cs --- APIGateway/Logging/TimestampLogger.cs | 41 +++++++++++++++++++ .../Logging/TimestampLoggerExtensions.cs | 27 ++++++++++++ APIGateway/Logging/TimestampLoggerProvider.cs | 28 +++++++++++++ APIGateway/Program.cs | 10 +++++ 4 files changed, 106 insertions(+) create mode 100644 APIGateway/Logging/TimestampLogger.cs create mode 100644 APIGateway/Logging/TimestampLoggerExtensions.cs create mode 100644 APIGateway/Logging/TimestampLoggerProvider.cs diff --git a/APIGateway/Logging/TimestampLogger.cs b/APIGateway/Logging/TimestampLogger.cs new file mode 100644 index 0000000..8f9a3fc --- /dev/null +++ b/APIGateway/Logging/TimestampLogger.cs @@ -0,0 +1,41 @@ +namespace APIGateway +{ + using Microsoft.Extensions.Logging; + using System; + + // This class details the beginning steps of the logger with timestamps. It implements ILogger, + // which comes with a few methods to be fulfilled. + + // This was written via ChatGPT 3.5. + public class TimestampLogger : ILogger + { + // This method is called when a new scope is requested for logging. + // Scopes are used to provide additional contextual information for log messages. + // In this implementation, it simply returns null because no specific scope is being managed. + public IDisposable BeginScope(TState state) + { + return null; + } + + // This method is called to check if logging at the specified log level is enabled. + // It can be used to implement filtering based on log levels. + // In this implementation, it always returns true, indicating that logging at any level is enabled. + // You may modify this method to implement filtering based on log levels if needed. + public bool IsEnabled(LogLevel logLevel) + { + return true; // You may implement filtering based on log level + } + + // This method is called to perform the actual logging of a message. + // It formats the log message with a timestamp in the format "yyyy-MM-dd HH:mm:ss", + // combines it with the formatted state and exception provided by the formatter function, + // and writes the resulting message to the console. + // You can replace Console.WriteLine(message) with your preferred logging mechanism. + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + string message = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - {formatter(state, exception)}"; + + Console.WriteLine(message); // Change this to your preferred logging mechanism + } + } +} diff --git a/APIGateway/Logging/TimestampLoggerExtensions.cs b/APIGateway/Logging/TimestampLoggerExtensions.cs new file mode 100644 index 0000000..48a0a87 --- /dev/null +++ b/APIGateway/Logging/TimestampLoggerExtensions.cs @@ -0,0 +1,27 @@ +namespace APIGateway +{ + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + using static IServiceCollection; + + // This was written via ChatGPT 3.5. + + public static class TimestampLoggerExtensions + { + // This extension method is used to extend the functionality of the ILoggingBuilder interface. + // It adds the capability to configure the logging system to include a timestamp in log messages. + // The method adds a timestamp logger to the logging builder. + + public static ILoggingBuilder AddTimestampLogger(this ILoggingBuilder builder) + { + // Inside the method, it accesses the IServiceCollection provided by the logging builder (builder.Services). + // It registers the TimestampLoggerProvider as a singleton service for ILoggerProvider. + // This ensures that the TimestampLoggerProvider will be used to create logger instances. + builder.Services.AddSingleton(); + + // Finally, it returns the logging builder instance to support method chaining. + // This allows further configuration to be chained after adding the timestamp logger. + return builder; + } + } +} diff --git a/APIGateway/Logging/TimestampLoggerProvider.cs b/APIGateway/Logging/TimestampLoggerProvider.cs new file mode 100644 index 0000000..84abef5 --- /dev/null +++ b/APIGateway/Logging/TimestampLoggerProvider.cs @@ -0,0 +1,28 @@ +namespace APIGateway +{ + using Microsoft.Extensions.Logging; + using System; + + // This was written via ChatGPT 3.5. + + // This class creates the baseline for the LoggerProvider. It implements ILoggerProvider, + // which simply just needs to create a logger and return it, whilst disposing of any extras. + public class TimestampLoggerProvider : ILoggerProvider + { + // This method is called when a logger is requested for a specific category. + // It creates and returns a new instance of the TimestampLogger class. + // Each logger provider can be associated with one or more logger instances. + // In this case, it always returns a new instance of TimestampLogger for any requested category. + + public ILogger CreateLogger(string categoryName) + { + // Creates and returns a new instance of TimestampLogger. + return new TimestampLogger(); + } + + // This method is called to release any resources used by the logger provider. + // Since this implementation does not hold any resources that need to be released explicitly, + // this method doesn't perform any action. + public void Dispose() { } + } +} diff --git a/APIGateway/Program.cs b/APIGateway/Program.cs index 06a3690..8d142e1 100644 --- a/APIGateway/Program.cs +++ b/APIGateway/Program.cs @@ -1,3 +1,5 @@ +using APIGateway; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -10,6 +12,14 @@ // Register HttpClient builder.Services.AddHttpClient(); +// This creates the services for the Logging files. +builder.Services.AddLogging(builder => +{ + builder.AddConsole(); + builder.AddDebug(); + builder.AddTimestampLogger(); // Add timestamp logger +}); + var app = builder.Build(); // Configure the HTTP request pipeline.