Skip to content

Commit

Permalink
Added Azure Cosmos DB integration, saving completed games
Browse files Browse the repository at this point in the history
  • Loading branch information
kalina559 committed Jun 1, 2024
1 parent 885f8b5 commit db1f612
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/BattleshipsWebApi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
dotnet-version: ${{ env.DOTNET_CORE_VERSION }}
- name: Restore
run: dotnet restore "${{ env.WORKING_DIRECTORY }}"
- name: Replace CosmosDb secret in appsettings.json
run: |
sed -i 's/__CosmosDb-Secret__/${{ secrets.COSMOSDB_SECRET }}/g' appsettings.json
- name: Build
run: dotnet build "${{ env.WORKING_DIRECTORY }}" --configuration ${{ env.CONFIGURATION }} --no-restore
- name: Test
Expand Down
4 changes: 4 additions & 0 deletions Battleships.Common/Battleships.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions Battleships.Common/CosmosDb/GameSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json;

namespace Battleships.Common.CosmosDb
{
public class GameSession
{
[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("sessionId")]
public string SessionId { get; set; }

[JsonProperty("gameState")]
public string GameStateJson { get; set; }

[JsonProperty("dateCreated")]
public DateTime DateCreated { get; set; }
}
}
10 changes: 10 additions & 0 deletions Battleships.Common/Settings/CosmosDbSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Battleships.Common.Settings
{
public class CosmosDbSettings
{
public string Account { get; set; }
public string Key { get; set; }
public string DatabaseName { get; set; }
public string ContainerName { get; set; }
}
}
2 changes: 2 additions & 0 deletions Battleships.Core/Battleships.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Session" Version="2.2.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.40.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

Expand Down
10 changes: 10 additions & 0 deletions Battleships.Core/Interfaces/ICosmosDbService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Battleships.Common.CosmosDb;
using Battleships.Common.GameClasses;

namespace Battleships.Services.Interfaces
{
public interface ICosmosDbService
{
Task AddGameSessionAsync(GameSession gameSession);
}
}
25 changes: 25 additions & 0 deletions Battleships.Core/Services/CosmosDbService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Battleships.Common.CosmosDb;
using Battleships.Common.Settings;
using Battleships.Services.Interfaces;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.Logging;

namespace Battleships.Core.Services
{
public class CosmosDbService : ICosmosDbService
{
private readonly Container _container;
private readonly ILogger<CosmosDbService> _logger;

public CosmosDbService(ILogger<CosmosDbService> logger, CosmosDbSettings settings, CosmosClient dbClient)
{
_logger = logger;
_container = dbClient.GetContainer(settings.DatabaseName, settings.ContainerName);
}

public async Task AddGameSessionAsync(GameSession gameSession)
{
await _container.CreateItemAsync(gameSession, new PartitionKey(gameSession.SessionId));
}
}
}
33 changes: 29 additions & 4 deletions Battleships.Core/Services/GameStateService.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using Battleships.Common.GameClasses;
using Battleships.Common.CosmosDb;
using Battleships.Common.GameClasses;
using Battleships.Core.Exceptions;
using Battleships.Services.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;

namespace Battleships.Core.Services
{
public class GameStateService(IHttpContextAccessor httpContextAccessor, ILogger<GameStateService> logger, IMemoryCache memoryCache) : IGameStateService
public class GameStateService(IHttpContextAccessor httpContextAccessor, ILogger<GameStateService> logger, IMemoryCache memoryCache, ICosmosDbService cosmosDbService, IHostEnvironment env) : IGameStateService
{
public GameState GetGameState()
{
Expand All @@ -18,7 +21,7 @@ public GameState GetGameState()
{
logger.LogInformation("No game state found in cache for session ID: {sessionId}", sessionId);
return new GameState();
}
}

var deserializedGameState = DeserializeGameStateJson(gameStateJson);

Expand Down Expand Up @@ -73,7 +76,29 @@ public bool CheckWinCondition()
var allPlayerShipsSunk = gameState.UserShips.All(ship => ship.IsSunk);
var allOpponentShipsSunk = gameState.OpponentShips.All(ship => ship.IsSunk);

return allPlayerShipsSunk || allOpponentShipsSunk;
if (allPlayerShipsSunk || allOpponentShipsSunk)
{
SaveGameSessionToDb(gameState);
return true;
}

return false;
}

private void SaveGameSessionToDb(GameState gameState)
{
if (env.IsProduction())
{
var gameSession = new GameSession
{
Id = Guid.NewGuid().ToString(),
GameStateJson = JsonConvert.SerializeObject(gameState),
SessionId = httpContextAccessor.HttpContext.Request.Headers["X-Session-Id"].ToString(),
DateCreated = DateTime.UtcNow
};

cosmosDbService.AddGameSessionAsync(gameSession);
}
}

public void ClearGameState()
Expand Down
11 changes: 11 additions & 0 deletions Battleships.WebApi/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Battleships.Common.Settings;
using Battleships.Core.Services;
using Battleships.Services.Interfaces;
using Battleships.WebApi;
using System;
using System.Configuration;

var builder = WebApplication.CreateBuilder(args);

Expand Down Expand Up @@ -42,6 +46,13 @@
builder.Services.AddScoped<IGameStateService, GameStateService>();
builder.Services.AddScoped<IAiTypeService, AiTypeService>();
builder.Services.AddScoped<IRuleTypeService, RuleTypeService>();
builder.Services.AddScoped<ICosmosDbService, CosmosDbService>();

var cosmosDbSettings = new CosmosDbSettings();
builder.Configuration.Bind(nameof(CosmosDbSettings), cosmosDbSettings);
builder.Services.AddSingleton(cosmosDbSettings);

ServiceCollectionSetup.InitializeCosmosClientInstanceAsync(cosmosDbSettings, builder.Services);


// Configure logging
Expand Down
21 changes: 21 additions & 0 deletions Battleships.WebApi/ServiceCollectionSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Battleships.Common.Settings;
using Battleships.Core.Services;
using Microsoft.Azure.Cosmos;

namespace Battleships.WebApi
{
public static class ServiceCollectionSetup
{
public static void InitializeCosmosClientInstanceAsync(CosmosDbSettings settings, IServiceCollection services)
{
CosmosClient client = new CosmosClient(settings.Account, settings.Key);
services.AddSingleton(client);

services.AddSingleton(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<CosmosDbService>>();
return new CosmosDbService(logger, settings, client);
});
}
}
}
8 changes: 7 additions & 1 deletion Battleships.WebApi/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"CosmosDbSettings": {
"Account": "https://kalj-cosmos-db.documents.azure.com:443/",
"Key": "__CosmosDb-Secret__", // you need to add the correct key here when running locally
"DatabaseName": "BattleshipsDatabase",
"ContainerName": "GameSessions"
}
}

0 comments on commit db1f612

Please sign in to comment.