Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprint 5 #12

Merged
merged 26 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
79f880b
Added GetGamesAsync Call from MicroCleint in Bucstop to the GatewayCo…
cpshahan Apr 2, 2024
1c3d759
Changed the GatewayController GameInfos to have error messages, to di…
EvasiveAce Apr 2, 2024
2ec9c75
Added JSON Serialization Options and HttpClient for reading gameInfo …
cpshahan Apr 2, 2024
767d14e
Added JsonSerializerOptions and HttpClient for reading information fr…
cpshahan Apr 2, 2024
ac6e5b7
Consistentency fixes
EvasiveAce Apr 2, 2024
3535227
Added async Task GetGamesWithInfo()
cpshahan Apr 2, 2024
3836385
Merge branch 'shahan-hensley-sprint-4' of https://github.com/Redacted…
cpshahan Apr 2, 2024
413c7e0
Added HttpClient to web application so it can make Http requests with…
cpshahan Apr 2, 2024
51eda57
Had ChatGPT instruct me how to read the list of Game Info from the Mi…
cpshahan Apr 2, 2024
df47f83
Change APIGateway URL so not conflicts with Microservice
cpshahan Apr 2, 2024
392dc70
Added ASPNet WebApi Client packege for ReadGamesAsync call
cpshahan Apr 2, 2024
8ed561a
Added more comments about everything
cpshahan Apr 5, 2024
af750f2
Merge pull request #5 from Redacted-Team/shahan-hensley-sprint-4
cpshahan Apr 8, 2024
1a65061
Added timestamps classes and updated Program.cs
PatrickVergason Apr 9, 2024
cfbed8a
Merge pull request #6 from Redacted-Team/vergason-sprint-4
cpshahan Apr 9, 2024
2c581e5
Added the base Uri for the gatway
cpshahan Apr 11, 2024
973b136
Dockerfile changes
Ethan-W1 Apr 11, 2024
427a753
Removed custom logger; added timestamps to existing
PatrickVergason Apr 11, 2024
7f67172
Added a method to read GameInfo objects and add it to a list and mofi…
cpshahan Apr 12, 2024
67616ed
Added Snake URL and endpoint
cpshahan Apr 16, 2024
fb850a4
Merge pull request #10 from Redacted-Team/vergason-sprint-5
EvasiveAce Apr 16, 2024
23c23fc
Added more endpoints
cpshahan Apr 16, 2024
ecee2e1
Modified GameInfo class
cpshahan Apr 18, 2024
1f14eb5
Merge pull request #9 from Redacted-Team/ethan-sprint-5
Ethan-W1 Apr 18, 2024
25ec2ca
Merge pull request #8 from Redacted-Team/shahan-sprint-5
cpshahan Apr 18, 2024
938e7c8
Update README.md
cpshahan Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions APIGateway/APIGateway.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
Expand Down
147 changes: 99 additions & 48 deletions APIGateway/Controllers/GatewayController.cs
Original file line number Diff line number Diff line change
@@ -1,70 +1,121 @@
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 System.Net.Http.Json;
using System.Text;

namespace Gateway
{
/// <summary>
/// Controller responsible for handling requests and responses at the gateway.
/// </summary>
[ApiController]
[Route("[controller]")]
public class GatewayController : ControllerBase
{
private static readonly List<GameInfo> TheInfo = new List<GameInfo>
private readonly HttpClient _httpClient; // Making readonly ensures thread safety
private readonly ILogger<GatewayController> _logger; // Making readonly ensures thread safety
private readonly List<GameInfo> TheInfo;

public GatewayController(HttpClient httpClient, ILogger<GatewayController> logger)
{
new GameInfo {
//Id = 1,
Title = "Snake",
//Content = "~/js/snake.js",
Author = "Fall 2023 Semester",
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",
HowTo = "Control with arrow keys.",
//Thumbnail = "/images/snake.jpg" //640x360 resolution
LeaderBoardStack = new Stack<KeyValuePair<string, int>>(),
_httpClient = httpClient;
_logger = logger;
TheInfo = new List<GameInfo>();
}

},
new GameInfo {
//Id = 2,
Title = "Tetris",
//Content = "~/js/tetris.js",
Author = "Fall 2023 Semester",
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.",
//Thumbnail = "/images/tetris.jpg"
LeaderBoardStack = new Stack<KeyValuePair<string, int>>(),

},
new GameInfo {
//Id = 3,
Title = "Pong",
//Content = "~/js/pong.js",
Author = "Fall 2023 Semester",
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.",
//Thumbnail = "/images/pong.jpg"
LeaderBoardStack = new Stack<KeyValuePair<string, int>>(),
},
/// <summary>
/// Handles GET requests to retrieve game information from microservices.
/// </summary>
/// <returns>A collection of GameInfo objects.</returns>
[HttpGet]
public async Task<IEnumerable<GameInfo>> Get()
{
try
{
var SnakeTask = AddGameInfo("https://localhost:1948", "/Snake" ); //Snake
var Tetristask = AddGameInfo("https://localhost:2626", "/Tetris"); //Tetris
var PongTask = AddGameInfo("https://localhost:1941", "Pong"); //Pong
await Task.WhenAll(SnakeTask, Tetristask, PongTask);
return TheInfo;
}
catch (Exception ex)
{
_logger.LogError($"An error occurred while fetching data from microservice: {ex.Message}");
// Return a placeholder list of GameInfo objects indicating failure
return GenerateFailureResponse();
}
}

};
/// <summary>
/// Attempts to retrieve gameinfo object from a microservice that holds a game info object (snake, tetris, pong)
/// and adds the game info into a list of game info objects
/// </summary>
/// <param name="gameinfolist"></param>
/// <param name="baseUrl"></param>
/// <param name="endpoint"></param>
/// <returns></returns>
[ApiExplorerSettings(IgnoreApi = true)]
public async Task AddGameInfo(string baseUrl, string endpoint)
{
try
{
using var client = new HttpClient();
//Set the base address of the microservice
client.BaseAddress = new Uri(baseUrl);

private readonly ILogger<GatewayController> _logger;
//Read the data from the endpoint
HttpResponseMessage response = await client.GetAsync(endpoint);

public GatewayController(ILogger<GatewayController> logger)
{
_logger = logger;
// Check if the request was successful
if (response.IsSuccessStatusCode)
{
// Deserialize the response content to a GameInfo object
var gameinfo = await response.Content.ReadAsAsync<List<GameInfo>>();
//Add object to list
lock (TheInfo)
{
TheInfo.AddRange(gameinfo);
}
}
else
{
_logger.LogError($"Failed to retrieve data from microservice at endpoint {endpoint}. Status code: {response.StatusCode}");
}

}
catch (Exception ex) //Log error and return false if any exception occurs
{
_logger.LogError(ex.Message);
}
}

[HttpGet]
public IEnumerable<GameInfo> Get()
/// <summary>
/// Generates a placeholder list of GameInfo objects indicating failure to retrieve data.
/// Written with ChatGPT
/// </summary>
/// <returns>A collection of GameInfo objects indicating failure.</returns>
private IEnumerable<GameInfo> GenerateFailureResponse()
{
return TheInfo;
// 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<GameInfo>
{
new GameInfo
{
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<KeyValuePair<string, int>>() // Initializing an empty stack
}
};
}
}
}
}
12 changes: 6 additions & 6 deletions APIGateway/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["GameMicroServer/GameMicroServer.csproj", "GameMicroServer/"]
RUN dotnet restore "GameMicroServer/GameMicroServer.csproj"
COPY ["APIGateway/APIGateway.csproj", "APIGateway/"]
RUN dotnet restore "APIGateway/APIGateway.csproj"
COPY . .
WORKDIR "/src/GameMicroServer"
RUN dotnet build "GameMicroServer.csproj" -c Release -o /app/build
WORKDIR "/src/APIGateway"
RUN dotnet build "APIGateway.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "GameMicroServer.csproj" -c Release -o /app/publish /p:UseAppHost=false
RUN dotnet publish "APIGateway.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "GameMicroServer.dll"]
ENTRYPOINT ["dotnet", "APIGateway.dll"]
3 changes: 3 additions & 0 deletions APIGateway/GameInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
{
public class GameInfo
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Content { get; set; }
public string Description { get; set; }
public string DateAdded { get; set; }
public string HowTo { get; set; }
public string Thumbnail { get; set; }
public Stack<KeyValuePair<string, int>> LeaderBoardStack { get; set; }
}
}
10 changes: 10 additions & 0 deletions APIGateway/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Register HttpClient
builder.Services.AddHttpClient();

// This creates the timestamp for the logger.
builder.Logging.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";
});

var app = builder.Build();

// Configure the HTTP request pipeline.
Expand Down
2 changes: 1 addition & 1 deletion APIGateway/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7223;http://localhost:5130"
"applicationUrl": "https://localhost:4141"
},
"IIS Express": {
"commandName": "IISExpress",
Expand Down
20 changes: 8 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
# GameMicroService
### A Team Bobby Project
# APIGateway
### A Team [Redacted] Project
### Members:
> Isaac Camacho, Richard Cashion, Dylan Cowell, Thomas Foreman,
> Dionte Jones, Matt Justis, Jacob Klucher, Dylan Lynch,
> Caleb Rains, Chris Seals, Kyle Wittman
> Kurt Brewer, Josh Rucevice, Charlie Shahan, Ethan Webb, Ethan Hensley, Patrick Vergason, Bryson Brandon
#### CSCI 4350
#### Fall 2023, East Tennessee State University
#### Spring 2024, East Tennessee State University

### Overview:
This is a microservice that returns game info in JSON format to the [BOBBY Project](https://github.com/chrisseals98/BOBBY).
This is the API Gateway that requests and queries from the main website, routed through a single entry-point to the [[Redacted] Project Tetris, Snake, and Pong].

### Project Structure:
* The application handles HTTP calls in the microController.cs file in the /GameMicroServer/Controllers directory.
* It only handles an HTTP Get call to the path /Micro. So if the application was running locally, you would call [http://localhost/Micro](http://localhost/Micro).
* This application is deployed alongside the BucStop project with docker compose, see [BOBBY Project](https://github.com/chrisseals98/BOBBY) for more details.
* This API Gateway acts as a middle-man to facilitate interaction between the BucStop main site and the Microservice(s).
* This architecture was set up with scalability in mind, and to allow the site to function at full capacity regardless of the number of microservices it employs.

### Help
For more documentation on how to run locally and how to set up deployments, see the google docs below:
* [Running Locally](https://docs.google.com/document/d/1gfUpjZNfqWyv1ohUW1IaS8fOhXp0hOx6tFQVXBADa8Q/edit?usp=sharing)
* [How to Deploy](https://docs.google.com/document/d/1i0edcmvZm_j0zQLYiigNliW39FJuJbmhkxOCCb2NbVs/edit?usp=sharing)
* [UNDER CONSTRUCTION]
Loading