diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..446b951 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..c539875 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,70 @@ +name: .NET + +on: + workflow_dispatch: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + name: Build and analyze + runs-on: windows-latest + env: + ProjectName: 'AStar.Dev.Api.HealthChecks' + RepositoryName: 'astar-dev-api-healthchecks' + steps: + - name: Set up JDK + uses: actions/setup-java@v4.4.0 + with: + java-version: 17 + distribution: 'zulu' + + - name: Checkout + uses: actions/checkout@v4.2.1 + with: + fetch-depth: 0 + + - name: Cache SonarCloud packages + uses: actions/cache@v4.2.3 + with: + path: ~\sonar\cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Cache SonarCloud scanner + id: cache-sonar-scanner + uses: actions/cache@v4.2.3 + with: + path: .\.sonar\scanner + key: ${{ runner.os }}-sonar-scanner + restore-keys: ${{ runner.os }}-sonar-scanner + + - name: Install SonarCloud scanner + if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' + shell: powershell + run: | + New-Item -Path .\.sonar\scanner -ItemType Directory + dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner + + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + shell: powershell + run: | + dotnet tool install --global dotnet-coverage + .\.sonar\scanner\dotnet-sonarscanner begin /k:"astar-development_${{ env.RepositoryName }}" /o:"astar-development" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml + dotnet build --configuration Release + dotnet-coverage collect 'dotnet test --filter "FullyQualifiedName!~Acceptance.Tests"' -f xml -o 'coverage.xml' + .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" + + - name: Pack NuGet package + if: github.ref == 'refs/heads/main' + run: dotnet pack .\src\${{ env.ProjectName }}\${{ env.ProjectName }}.csproj + + - name: Push to NuGet + if: github.ref == 'refs/heads/main' + run: dotnet nuget push "**\${{ env.ProjectName }}.*.nupkg" --api-key ${{secrets.nuget_api_key}} --skip-duplicate --source https://api.nuget.org/v3/index.json + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..6303ef6 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.astar-dev-api-health-checks.iml +/contentModel.xml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.gitignore b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.gitignore new file mode 100644 index 0000000..ea7b8fb --- /dev/null +++ b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/contentModel.xml +/modules.xml +/projectSettingsUpdater.xml +/.idea.AStar.Dev.Api.HealthChecks.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.name b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.name new file mode 100644 index 0000000..1ed7ba5 --- /dev/null +++ b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/.name @@ -0,0 +1 @@ +AStar.Dev.Api.HealthChecks \ No newline at end of file diff --git a/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/indexLayout.xml b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/vcs.xml b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/vcs.xml new file mode 100644 index 0000000..8306744 --- /dev/null +++ b/.idea/.idea.AStar.Dev.Api.HealthChecks/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/indexLayout.xml b/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AStar.Dev.Api.HealthChecks.sln b/AStar.Dev.Api.HealthChecks.sln new file mode 100644 index 0000000..f4ae9b6 --- /dev/null +++ b/AStar.Dev.Api.HealthChecks.sln @@ -0,0 +1,47 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9BF0D563-C690-4CC1-AE4A-4964C4CD72E5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{84BA153E-A206-44B9-B526-33D7DC15A5BD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar.Dev.Api.HealthChecks", "src\AStar.Dev.Api.HealthChecks\AStar.Dev.Api.HealthChecks.csproj", "{975F050F-B39E-4F34-9503-C55F8D59F20F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar.Dev.Api.HealthChecks.Tests.Unit", "test\AStar.Dev.Api.HealthChecks.Tests.Unit\AStar.Dev.Api.HealthChecks.Tests.Unit.csproj", "{647DBF16-4745-4E23-86F4-97959B210DCE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{3A338878-32ED-4984-AFA3-5C5F7B8A2E83}" + ProjectSection(SolutionItems) = preProject + .github\dependabot.yml = .github\dependabot.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{5974FC13-A320-481C-A449-BDFCBB9F6A76}" + ProjectSection(SolutionItems) = preProject + .github\workflows\dotnet.yml = .github\workflows\dotnet.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {975F050F-B39E-4F34-9503-C55F8D59F20F} = {9BF0D563-C690-4CC1-AE4A-4964C4CD72E5} + {647DBF16-4745-4E23-86F4-97959B210DCE} = {84BA153E-A206-44B9-B526-33D7DC15A5BD} + {5974FC13-A320-481C-A449-BDFCBB9F6A76} = {3A338878-32ED-4984-AFA3-5C5F7B8A2E83} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {975F050F-B39E-4F34-9503-C55F8D59F20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {975F050F-B39E-4F34-9503-C55F8D59F20F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {975F050F-B39E-4F34-9503-C55F8D59F20F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {975F050F-B39E-4F34-9503-C55F8D59F20F}.Release|Any CPU.Build.0 = Release|Any CPU + {647DBF16-4745-4E23-86F4-97959B210DCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {647DBF16-4745-4E23-86F4-97959B210DCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {647DBF16-4745-4E23-86F4-97959B210DCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {647DBF16-4745-4E23-86F4-97959B210DCE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/AStar.ico b/AStar.ico new file mode 100644 index 0000000..0b9aea4 Binary files /dev/null and b/AStar.ico differ diff --git a/AStar.png b/AStar.png new file mode 100644 index 0000000..8cac0a1 Binary files /dev/null and b/AStar.png differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a6afee4 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# astar-dev-all-private \ No newline at end of file diff --git a/build-and-test.ps1 b/build-and-test.ps1 new file mode 100644 index 0000000..aad68a7 --- /dev/null +++ b/build-and-test.ps1 @@ -0,0 +1,3 @@ +dotnet build +dotnet test +dotnet stryker --open-report --break-at 99 \ No newline at end of file diff --git a/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.csproj b/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.csproj new file mode 100644 index 0000000..d3f7b4f --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.csproj @@ -0,0 +1,65 @@ + + + + latest-recommended + AStar + AStar Development, 2025 + + This package contains atleast one extension method for setting up the HealthChecks. + + Over time, additional methods will be added. + + $(MSBuildProjectName).xml + True + True + True + enable + True + true + enable + AStar.png + LICENSE + https://github.com/astar-development/astar-dev-api-health-checks + Readme.md + This version only updates the GitHub actions. + true + ASP.Core HealthChecks;HealthChecks + git + https://github.com/astar-development/astar-dev-api-health-checks.git + snupkg + net9.0 + AStar API HealthChecks + 0.3.1 + + + + True + 1701;1702; + + + + True + 1701;1702; + + + + + + + + + + True + \ + + + True + \ + + + true + + + + + diff --git a/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.xml b/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.xml new file mode 100644 index 0000000..f908733 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.xml @@ -0,0 +1,63 @@ + + + + AStar.Dev.Api.HealthChecks + + + + + The class contains the relevant method(s) to configure the endpoints. + + + + + The method will add a basic health/live and health/ready endpoint. + + An instance of to configure + The original to facilitate further method chaining + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The interface. + + + + + The GetHealthAsync method will return the basic Health Status of the API. + + The token to optionally use to cancel the operation + + An instance of the class containing the text representation of the API + Health Status. + + + + diff --git a/src/AStar.Dev.Api.HealthChecks/AStar.ico b/src/AStar.Dev.Api.HealthChecks/AStar.ico new file mode 100644 index 0000000..0b9aea4 Binary files /dev/null and b/src/AStar.Dev.Api.HealthChecks/AStar.ico differ diff --git a/src/AStar.Dev.Api.HealthChecks/AStar.png b/src/AStar.Dev.Api.HealthChecks/AStar.png new file mode 100644 index 0000000..8cac0a1 Binary files /dev/null and b/src/AStar.Dev.Api.HealthChecks/AStar.png differ diff --git a/src/AStar.Dev.Api.HealthChecks/HealthCheckExtensions.cs b/src/AStar.Dev.Api.HealthChecks/HealthCheckExtensions.cs new file mode 100644 index 0000000..29056fe --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/HealthCheckExtensions.cs @@ -0,0 +1,83 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace AStar.Dev.Api.HealthChecks; + +/// +/// The class contains the relevant method(s) to configure the endpoints. +/// +public static class HealthCheckExtensions +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new() + { + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + /// + /// The method will add a basic health/live and health/ready endpoint. + /// + /// An instance of to configure + /// The original to facilitate further method chaining + public static WebApplication ConfigureHealthCheckEndpoints(this WebApplication app) + { + _ = app.MapHealthChecks("/health/live", + new() + { + ResponseWriter = WriteHealthCheckResponseAsync, + ResultStatusCodes = + { + [HealthStatus.Degraded] = StatusCodes.Status424FailedDependency, + [HealthStatus.Healthy] = StatusCodes.Status200OK, + [HealthStatus.Unhealthy] = StatusCodes.Status500InternalServerError, + }, + Predicate = _ => true, + }); + + _ = app.MapHealthChecks("/health/ready", + new() + { + ResponseWriter = WriteHealthCheckResponseAsync, + ResultStatusCodes = + { + [HealthStatus.Degraded] = StatusCodes.Status424FailedDependency, + [HealthStatus.Healthy] = StatusCodes.Status200OK, + [HealthStatus.Unhealthy] = StatusCodes.Status500InternalServerError, + }, + Predicate = _ => true, + }); + + return app; + } + + private static Task WriteHealthCheckResponseAsync( + HttpContext httpContext, + HealthReport healthReport) + { + httpContext.Response.ContentType = "application/json; charset=utf-8"; + + IEnumerable dependencyHealthChecks = healthReport.Entries.Select(static entry => new HealthStatusResponse + { + Name = entry.Key, + Description = entry.Value.Description, + Status = entry.Value.Status.ToString(), + DurationInMilliseconds = entry.Value.Duration + .TotalMilliseconds, + Data = entry.Value.Data, + Exception = entry.Value.Exception?.Message, + }); + + var healthCheckResponse = new + { + Status = healthReport.Status.ToString(), + TotalCheckExecutionTimeInMilliseconds = healthReport.TotalDuration.TotalMilliseconds, + DependencyHealthChecks = dependencyHealthChecks, + }; + + string responseString = JsonSerializer.Serialize(healthCheckResponse, JsonSerializerOptions); + + return httpContext.Response.WriteAsync(responseString); + } +} diff --git a/src/AStar.Dev.Api.HealthChecks/HealthStatusResponse.cs b/src/AStar.Dev.Api.HealthChecks/HealthStatusResponse.cs new file mode 100644 index 0000000..319e1a8 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/HealthStatusResponse.cs @@ -0,0 +1,30 @@ +namespace AStar.Dev.Api.HealthChecks; + +/// +/// +public sealed class HealthStatusResponse +{ + /// + /// + public string Name { get; set; } = string.Empty; + + /// + /// + public string? Description { get; set; } = "Unable to retrieve the description of the Health Status"; + + /// + /// + public string Status { get; set; } = string.Empty; + + /// + /// + public double DurationInMilliseconds { get; set; } + + /// + /// + public IReadOnlyDictionary? Data { get; set; } + + /// + /// + public string? Exception { get; set; } = string.Empty; +} diff --git a/src/AStar.Dev.Api.HealthChecks/IApiClient.cs b/src/AStar.Dev.Api.HealthChecks/IApiClient.cs new file mode 100644 index 0000000..6ca8c7d --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/IApiClient.cs @@ -0,0 +1,17 @@ +namespace AStar.Dev.Api.HealthChecks; + +/// +/// The interface. +/// +public interface IApiClient +{ + /// + /// The GetHealthAsync method will return the basic Health Status of the API. + /// + /// The token to optionally use to cancel the operation + /// + /// An instance of the class containing the text representation of the API + /// Health Status. + /// + public Task GetHealthAsync(CancellationToken cancellationToken = default); +} diff --git a/src/AStar.Dev.Api.HealthChecks/LICENSE b/src/AStar.Dev.Api.HealthChecks/LICENSE new file mode 100644 index 0000000..0b1b024 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 AStar Development, Jason Barden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/AStar.Dev.Api.HealthChecks/Program.cs b/src/AStar.Dev.Api.HealthChecks/Program.cs new file mode 100644 index 0000000..d2fadd5 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/Program.cs @@ -0,0 +1,7 @@ +namespace AStar.Dev.Api.HealthChecks; + +internal static class Program +{ + private static void Main() => + Console.WriteLine("Hello, World!"); +} diff --git a/src/AStar.Dev.Api.HealthChecks/Properties/launchSettings.json b/src/AStar.Dev.Api.HealthChecks/Properties/launchSettings.json new file mode 100644 index 0000000..3021047 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "AStar.Dev.Api.HealthChecks": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:56272;http://localhost:56273" + } + } +} diff --git a/src/AStar.Dev.Api.HealthChecks/Readme.md b/src/AStar.Dev.Api.HealthChecks/Readme.md new file mode 100644 index 0000000..16dacd1 --- /dev/null +++ b/src/AStar.Dev.Api.HealthChecks/Readme.md @@ -0,0 +1 @@ +Update \ No newline at end of file diff --git a/test/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj b/test/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj new file mode 100644 index 0000000..f446742 --- /dev/null +++ b/test/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj @@ -0,0 +1,46 @@ + + + + net9.0 + enable + enable + false + AStar.Dev.Api.HealthChecks + True + latest-recommended + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + True + 1701;1702;IDE0058; + + + + True + 1701;1702;IDE0058; + + +