diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..62aef73 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,13 @@ +categories: + - title: '🚀 Features' + labels: + - 'feature' + - title: '🐛 Bug Fixes' + labels: + - 'bug' + - title: '🧰 Maintenance' + label: 'maintenance' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +template: | + ## Changes + $CHANGES diff --git a/.github/workflows/buildwindowsimage.yml b/.github/workflows/buildwindowsimage.yml new file mode 100644 index 0000000..8cc3b4c --- /dev/null +++ b/.github/workflows/buildwindowsimage.yml @@ -0,0 +1,34 @@ +name: Release + +on: + release: + types: [published] + +jobs: + build: + name: "Release" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Get the version + id: get_version + uses: battila7/get-version-action@v2 + + - name: Publish Images to Docker Hub - Pre Release + if: ${{ github.event.release.prerelease == true }} + run: | + docker build . --file EstateManagement/Dockerfilewindows --tag stuartferguson/estatereportingapi:dev + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatereportingapi:dev + + - name: Publish Images to Docker Hub - Formal Release + if: ${{ github.event.release.prerelease == false }} + run: | + docker build . --file EstateManagement/Dockerfilewindows --tag stuartferguson/estatereportingapi:latest + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatereportingapi:latest diff --git a/.github/workflows/createrelease.yml b/.github/workflows/createrelease.yml new file mode 100644 index 0000000..f2ec540 --- /dev/null +++ b/.github/workflows/createrelease.yml @@ -0,0 +1,126 @@ +name: Release + +on: + release: + types: [published] + +jobs: + build: + name: "Release" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Get the version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + + - name: Restore Nuget Packages + run: dotnet restore EstateReportingAPI.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build EstateReportingAPI.sln --configuration Release + + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet test "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj" + + - name: Publish Images to Docker Hub - Pre Release + if: ${{ github.event.release.prerelease == true }} + run: | + docker build . --file EstateReportingAPI/Dockerfile --tag stuartferguson/estatereportingapi:dev + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatereportingapi:dev + + - name: Publish Images to Docker Hub - Formal Release + if: ${{ github.event.release.prerelease == false }} + run: | + docker build . --file EstateReportingAPI/Dockerfile --tag stuartferguson/estatereportingapi:latest + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatereportingapi:latest + + - name: Publish API + if: ${{ github.event.release.prerelease == false }} + run: dotnet publish "EstateReportingAPI\EstateReportingAPI.csproj" --configuration Release --output publishOutput -r win-x64 --self-contained + + - name: Install Octopus CLI + if: ${{ github.event.release.prerelease == false }} + run: | + sudo apt update && sudo apt install --no-install-recommends gnupg curl ca-certificates apt-transport-https && \ + curl -sSfL https://apt.octopus.com/public.key | sudo apt-key add - && \ + sudo sh -c "echo deb https://apt.octopus.com/ stable main > /etc/apt/sources.list.d/octopus.com.list" && \ + sudo apt update && sudo apt install octopuscli + + - name: Pack Files for Octopus + if: ${{ github.event.release.prerelease == false }} + run: >- + octo pack + --outFolder /home/runner/work/EstateReportingAPI/EstateReportingAPI + --basePath /home/runner/work/EstateReportingAPI/EstateReportingAPI/publishOutput + --id EstateReportingAPI + --version ${{ steps.get_version.outputs.VERSION }} + --format zip + --verbose + --logLevel=verbose + + - name: Push Package to Octopus + if: ${{ github.event.release.prerelease == false }} + run: >- + octo push + --server ${{ secrets.OCTOPUS_URL }} + --apiKey ${{ secrets.OCTOPUS_APIKEY }} + --package /home/runner/work/EstateReportingAPI/EstateReportingAPI/EstateReportingAPI.${{ steps.get_version.outputs.VERSION }}.zip + --overwrite-mode IgnoreIfExists + + - name: Get Release + if: ${{ github.event.release.prerelease == false }} + id: getrelease + uses: octokit/request-action@v2.0.17 + with: + route: GET /repos/TransactionProcessing/EstateReportingAPI/releases/tags/${{ steps.get_version.outputs.VERSION }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Release Notes + if: ${{ github.event.release.prerelease == false }} + id: buildreleasenotes + uses: gr2m/get-json-paths-action@v1.x + with: + json: ${{ steps.getrelease.outputs.data }} + releasenote: "body" + + - name: Create & Deploy Release in Octopus + if: ${{ github.event.release.prerelease == false }} + run: >- + octo create-release + --server ${{ secrets.OCTOPUS_URL }} + --apiKey ${{ secrets.OCTOPUS_APIKEY }} + --project "Estate Reporting API" + --version ${{ steps.get_version.outputs.VERSION }} + --channel Default + --deployTo Staging + --waitfordeployment + --deploymenttimeout 00:05:00 + --releasenotes "${{ steps.buildreleasenotes.outputs.releasenote }}" + + #- name: Build and Publish Nuget Packages + # if: ${{ github.event.release.prerelease == false }} + # run: | + # dotnet pack "EstateManagement.Client\EstateManagement.Client.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Client.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Estate.DomainEvents\EstateManagement.Estate.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Estate.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Merchant.DomainEvents\EstateManagement.Merchant.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Merchant.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Contract.DomainEvents\EstateManagement.Contract.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Contract.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.MerchantStatement.DomainEvents\EstateManagement.MerchantStatement.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.MerchantStatement.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Database\EstateManagement.Database.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Database.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + diff --git a/.github/workflows/nightlybuild.yml b/.github/workflows/nightlybuild.yml new file mode 100644 index 0000000..7a4926e --- /dev/null +++ b/.github/workflows/nightlybuild.yml @@ -0,0 +1,86 @@ +name: Nightly Build + +on: + schedule: + - cron: "45 23 * * *" + repository_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + name: Check latest commit + outputs: + commitcount: ${{ steps.commitswithintime.outputs.number-of-commits-within-time }} + steps: + - uses: actions/checkout@v2 + #with: + #fetch-depth: 0 + + - name: Check for commits within time + #uses: AlexHolderDeveloper/CommitsWithinTime@v1.1.5 + uses: TransactionProcessing/CommitsWithinTime@1.0.0 + id: commitswithintime + with: + hours: 24 + + - name: Get the output from CommitsWithinTime + run: | + echo "The 'has-new-commits-within-time' value is ${{ steps.commitswithintime.outputs.has-new-commits-within-time }}" + echo "The 'number-of-commits-within-time' value is ${{ steps.commitswithintime.outputs.number-of-commits-within-time }}" + echo "The 'total-commits' value is ${{ steps.commitswithintime.outputs.total-commits }}" + + build: + name: "Nightly Build" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + needs: check + if: ${{ needs.check.outputs.commitcount > 0 }} + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Set Up Variables + run: echo "action_url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_ENV + + - name: Restore Nuget Packages + run: dotnet restore EstateReportingAPI.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build EstateReportingAPI.sln --configuration Release + + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet test "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov1.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" + + - name: Setup Node.js for use with actions + uses: actions/setup-node@v1.4.4 + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + files: ./lcov1.info + + - name: Build Docker Image + run: docker build . --file EstateReportingAPI/Dockerfile --tag estatereportingapi:latest + + #- name: Run Integration Tests + #run: dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" + + - uses: actions/upload-artifact@v2 + if: ${{ failure() }} + with: + name: tracelogs + path: /home/txnproc/trace/ + + - uses: dacbd/create-issue-action@main + if: ${{ failure() }} + name: Create an issue on build failure + with: + title: Investigate Nightly Build Failure + token: ${{secrets.GITHUB_TOKEN}} + labels: nightlybuild + body: Url is ${{env.action_url}} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml new file mode 100644 index 0000000..e074aaa --- /dev/null +++ b/.github/workflows/pullrequest.yml @@ -0,0 +1,40 @@ +name: Build and Test Pull Requests + +on: + pull_request: + branches: + - main + +jobs: + build: + name: "Build and Test Pull Requests" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Restore Nuget Packages + run: dotnet restore EstateReportingAPI.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build EstateReportingAPI.sln --configuration Release + + - name: Run Unit Tests + run: | + echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" + dotnet test "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj" + + - name: Build Docker Image + run: docker build . --file EstateReportingAPI/Dockerfile --tag estatereportingapi:latest + + #- name: Run Integration Tests + #run: dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" --filter Category=PRTest + + - uses: actions/upload-artifact@v2 + if: ${{ failure() }} + with: + name: tracelogs + path: /home/txnproc/trace/ \ No newline at end of file diff --git a/.github/workflows/pushtomaster.yml b/.github/workflows/pushtomaster.yml new file mode 100644 index 0000000..15f42b6 --- /dev/null +++ b/.github/workflows/pushtomaster.yml @@ -0,0 +1,82 @@ +name: Publish Pre-Release Nuget and Docker + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - main + +jobs: + build: + name: "Publish Pre-Release Nugets and Docker" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2.3.4 + with: + fetch-depth: 0 + + - name: Restore Nuget Packages + run: dotnet restore EstateReportingAPI.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build EstateReportingAPI.sln --configuration Release + + - name: 'Get Previous tag' + id: get-latest-tag + uses: actions-ecosystem/action-get-latest-tag@v1 + with: + semver_only: true + + - name: 'Bump Version' + id: bump-semver + uses: actions-ecosystem/action-bump-semver@v1 + with: + current_version: ${{ steps.get-latest-tag.outputs.tag }} + level: patch + + - name: Print Version + id: next_version + run: echo ::set-output name=VERSION::${{ steps.bump-semver.outputs.new_version }}-build$GITHUB_RUN_NUMBER + + #- name: Build and Publish Nuget Packages + # run: | + # dotnet pack "EstateManagement.Client\EstateManagement.Client.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Client.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Estate.DomainEvents\EstateManagement.Estate.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Estate.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Merchant.DomainEvents\EstateManagement.Merchant.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Merchant.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Contract.DomainEvents\EstateManagement.Contract.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Contract.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.MerchantStatement.DomainEvents\EstateManagement.MerchantStatement.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.MerchantStatement.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + # dotnet pack "EstateManagement.Database\EstateManagement.Database.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + # dotnet nuget push Nugets/EstateManagement.Database.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Publish Images to Docker Hub + run: | + docker build . --file EstateReportingAPI/Dockerfile --tag stuartferguson/estatemanagement:master + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatemanagement:master + + buildwidows: + name: "Publish Pre-Release Docker for Windows" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v2.3.4 + with: + fetch-depth: 0 + + - name: Publish Windows Images to Docker Hub + run: | + docker build . --file EstateReportingAPI/Dockerfilewindows --tag stuartferguson/estatereportingapi:master + docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + docker push stuartferguson/estatereportingapi:master \ No newline at end of file diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml new file mode 100644 index 0000000..bb787fe --- /dev/null +++ b/.github/workflows/release-management.yml @@ -0,0 +1,16 @@ +name: Release Management + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - main + +jobs: + update_draft_release: + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: toolmantim/release-drafter@v5.12.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 0000000..067cd55 --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,51 @@ +name: SonarCloud Analysis + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + name: Build and analyze + runs-on: windows-latest + steps: + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 1.11 + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Cache SonarCloud packages + uses: actions/cache@v1 + with: + path: ~\sonar\cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache SonarCloud scanner + id: cache-sonar-scanner + uses: actions/cache@v1 + 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 }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + shell: powershell + run: | + .\.sonar\scanner\dotnet-sonarscanner begin /k:"TransactionProcessing_EstateReportingAPI" /o:"transactionprocessing" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" + dotnet restore EstateReportingAPI.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + dotnet build EstateReportingAPI.sln --configuration Release + .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" \ No newline at end of file diff --git a/EstateReportingAPI.Testing/EstateReportingAPI.csproj b/EstateReportingAPI.Testing/EstateReportingAPI.csproj new file mode 100644 index 0000000..2040736 --- /dev/null +++ b/EstateReportingAPI.Testing/EstateReportingAPI.csproj @@ -0,0 +1,13 @@ + + + + net7.0 + None + + + + + + + + diff --git a/EstateReportingAPI.Tests/EstateReportingAPI.Tests.csproj b/EstateReportingAPI.Tests/EstateReportingAPI.Tests.csproj new file mode 100644 index 0000000..ed28f61 --- /dev/null +++ b/EstateReportingAPI.Tests/EstateReportingAPI.Tests.csproj @@ -0,0 +1,38 @@ + + + + net7.0 + None + false + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/EstateReportingAPI.Tests/General/BootstrapperTests.cs b/EstateReportingAPI.Tests/General/BootstrapperTests.cs new file mode 100644 index 0000000..28f9855 --- /dev/null +++ b/EstateReportingAPI.Tests/General/BootstrapperTests.cs @@ -0,0 +1,70 @@ +namespace EstateReportingAPI.Tests.General +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using EstateReportingAPI; + using Lamar; + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Moq; + using Xunit; + + [Collection("TestCollection")] + public class BootstrapperTests + { + [Fact] + public void VerifyBootstrapperIsValid() + { + Mock hostingEnvironment = new Mock(); + hostingEnvironment.Setup(he => he.EnvironmentName).Returns("Development"); + hostingEnvironment.Setup(he => he.ContentRootPath).Returns("/home"); + hostingEnvironment.Setup(he => he.ApplicationName).Returns("Test Application"); + + ServiceRegistry services = new ServiceRegistry(); + Startup s = new Startup(hostingEnvironment.Object); + Startup.Configuration = this.SetupMemoryConfiguration(); + + this.AddTestRegistrations(services, hostingEnvironment.Object); + s.ConfigureContainer(services); + Startup.Container.AssertConfigurationIsValid(AssertMode.Full); + } + + private IConfigurationRoot SetupMemoryConfiguration() + { + Dictionary configuration = new Dictionary(); + + IConfigurationBuilder builder = new ConfigurationBuilder(); + + configuration.Add("ConnectionStrings:HealthCheck", "HeathCheckConnString"); + configuration.Add("SecurityConfiguration:Authority", "https://127.0.0.1"); + configuration.Add("EventStoreSettings:ConnectionString", "https://127.0.0.1:2113"); + configuration.Add("EventStoreSettings:ConnectionName", "UnitTestConnection"); + configuration.Add("EventStoreSettings:UserName", "admin"); + configuration.Add("EventStoreSettings:Password", "changeit"); + configuration.Add("AppSettings:UseConnectionStringConfig", "false"); + configuration.Add("AppSettings:SecurityService", "http://127.0.0.1"); + configuration.Add("AppSettings:MessagingServiceApi", "http://127.0.0.1"); + configuration.Add("AppSettings:TransactionProcessorApi", "http://127.0.0.1"); + configuration.Add("AppSettings:DatabaseEngine", "SqlServer"); + + builder.AddInMemoryCollection(configuration); + + return builder.Build(); + } + + private void AddTestRegistrations(ServiceRegistry services, + IWebHostEnvironment hostingEnvironment) + { + services.AddLogging(); + DiagnosticListener diagnosticSource = new DiagnosticListener(hostingEnvironment.ApplicationName); + services.AddSingleton(diagnosticSource); + services.AddSingleton(diagnosticSource); + services.AddSingleton(hostingEnvironment); + services.AddSingleton(hostingEnvironment); + services.AddSingleton(Startup.Configuration); + } + } +} diff --git a/EstateReportingAPI.sln b/EstateReportingAPI.sln new file mode 100644 index 0000000..4edd8a0 --- /dev/null +++ b/EstateReportingAPI.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34004.107 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EstateReportingAPI", "EstateReportingAPI\EstateReportingAPI.csproj", "{8E6ED1E8-9776-49F3-ADEB-17A03318E136}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{713556C8-BFC0-4AB6-8F13-7631C1C82D07}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C48C544B-7C3B-4AA2-8A37-E49296A86499}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EstateReportingAPI", "EstateReportingAPI.Testing\EstateReportingAPI.csproj", "{DC3AEC92-739F-45E6-8513-CFAEA826984A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EstateReportingAPI.Tests", "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj", "{1124CAC0-A2B3-44FF-8B16-C8722D7042A2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8E6ED1E8-9776-49F3-ADEB-17A03318E136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E6ED1E8-9776-49F3-ADEB-17A03318E136}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E6ED1E8-9776-49F3-ADEB-17A03318E136}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E6ED1E8-9776-49F3-ADEB-17A03318E136}.Release|Any CPU.Build.0 = Release|Any CPU + {DC3AEC92-739F-45E6-8513-CFAEA826984A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC3AEC92-739F-45E6-8513-CFAEA826984A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC3AEC92-739F-45E6-8513-CFAEA826984A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC3AEC92-739F-45E6-8513-CFAEA826984A}.Release|Any CPU.Build.0 = Release|Any CPU + {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {8E6ED1E8-9776-49F3-ADEB-17A03318E136} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} + {DC3AEC92-739F-45E6-8513-CFAEA826984A} = {C48C544B-7C3B-4AA2-8A37-E49296A86499} + {1124CAC0-A2B3-44FF-8B16-C8722D7042A2} = {C48C544B-7C3B-4AA2-8A37-E49296A86499} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B2BE269B-F142-45A3-9B75-483227C765A6} + EndGlobalSection +EndGlobal diff --git a/EstateReportingAPI/.dockerignore b/EstateReportingAPI/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/EstateReportingAPI/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*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/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs b/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs new file mode 100644 index 0000000..425fcff --- /dev/null +++ b/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs @@ -0,0 +1,100 @@ +namespace EstateReportingAPI.Bootstrapper{ + using System.Diagnostics.CodeAnalysis; + using System.Reflection; + using Common; + using Lamar; + using Microsoft.AspNetCore.Authentication.JwtBearer; + using Microsoft.Extensions.Diagnostics.HealthChecks; + using Microsoft.IdentityModel.Tokens; + using Microsoft.OpenApi.Models; + using Newtonsoft.Json; + using Newtonsoft.Json.Serialization; + using Shared.General; + using Swashbuckle.AspNetCore.Filters; + + [ExcludeFromCodeCoverage] + public class MiddlewareRegistry : ServiceRegistry{ + public MiddlewareRegistry(){ + + + this.AddHealthChecks() + .AddSqlServer(connectionString:ConfigurationReader.GetConnectionString("HealthCheck"), + healthQuery:"SELECT 1;", + name:"Read Model Server", + failureStatus:HealthStatus.Degraded, + tags:new[]{ "db", "sql", "sqlserver" }); + this.AddSwaggerGen(c => { + c.SwaggerDoc("v1", + new OpenApiInfo{ + Title = "Estate Reporting API", + Version = "1.0", + Description = "A REST Api to manage all aspects of reporting for an estate (merchants, operators and contracts).", + Contact = new OpenApiContact{ + Name = "Stuart Ferguson", + Email = "golfhandicapping@btinternet.com" + } + }); + // add a custom operation filter which sets default values + c.OperationFilter(); + c.ExampleFilters(); + + //Locate the XML files being generated by ASP.NET... + var directory = new DirectoryInfo(AppContext.BaseDirectory); + var xmlFiles = directory.GetFiles("*.xml"); + + //... and tell Swagger to use those XML comments. + foreach (FileInfo fileInfo in xmlFiles){ + c.IncludeXmlComments(fileInfo.FullName); + } + }); + + this.AddSwaggerExamplesFromAssemblyOf(); + + this.AddAuthentication(options => { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddJwtBearer(options => { + options.BackchannelHttpHandler = new HttpClientHandler{ + ServerCertificateCustomValidationCallback = (message, + certificate, + chain, + sslPolicyErrors) => true + }; + options.Authority = ConfigurationReader.GetValue("SecurityConfiguration", "Authority"); + options.Audience = ConfigurationReader.GetValue("SecurityConfiguration", "ApiName"); + + options.TokenValidationParameters = new TokenValidationParameters{ + ValidateAudience = false, + ValidAudience = + ConfigurationReader.GetValue("SecurityConfiguration", "ApiName"), + ValidIssuer = + ConfigurationReader.GetValue("SecurityConfiguration", "Authority"), + }; + options.IncludeErrorDetails = true; + }); + + this.AddControllers().AddNewtonsoftJson(options => { + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + options.SerializerSettings.TypeNameHandling = TypeNameHandling.None; + options.SerializerSettings.Formatting = Formatting.Indented; + options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + }); + + Assembly assembly = this.GetType().GetTypeInfo().Assembly; + this.AddMvcCore().AddApplicationPart(assembly).AddControllersAsServices(); + } + + private HttpClientHandler ApiEndpointHttpHandler(IServiceProvider serviceProvider){ + return new HttpClientHandler{ + ServerCertificateCustomValidationCallback = (message, + cert, + chain, + errors) => { + return true; + } + }; + } + } +} \ No newline at end of file diff --git a/EstateReportingAPI/Common/SwaggerDefaultValues.cs b/EstateReportingAPI/Common/SwaggerDefaultValues.cs new file mode 100644 index 0000000..b001b35 --- /dev/null +++ b/EstateReportingAPI/Common/SwaggerDefaultValues.cs @@ -0,0 +1,45 @@ +namespace EstateReportingAPI.Common +{ + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using Microsoft.AspNetCore.Mvc.ApiExplorer; + using Microsoft.OpenApi.Models; + using Swashbuckle.AspNetCore.SwaggerGen; + + /// + /// Represents the Swagger/Swashbuckle operation filter used to document the implicit API version parameter. + /// + /// This is only required due to bugs in the . + /// Once they are fixed and published, this class can be removed. + [ExcludeFromCodeCoverage] + public class SwaggerDefaultValues : IOperationFilter + { + /// + /// Applies the filter to the specified operation using the given context. + /// + /// The operation to apply the filter to. + /// The current operation filter context. + public void Apply(OpenApiOperation operation, + OperationFilterContext context) + { + ApiDescription apiDescription = context.ApiDescription; + + if (operation.Parameters == null) + { + return; + } + + foreach (OpenApiParameter parameter in operation.Parameters) + { + ApiParameterDescription description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); + + if (parameter.Description == null) + { + parameter.Description = description.ModelMetadata?.Description; + } + + parameter.Required |= description.IsRequired; + } + } + } +} diff --git a/EstateReportingAPI/Common/SwaggerJsonConverter.cs b/EstateReportingAPI/Common/SwaggerJsonConverter.cs new file mode 100644 index 0000000..fd86308 --- /dev/null +++ b/EstateReportingAPI/Common/SwaggerJsonConverter.cs @@ -0,0 +1,80 @@ +namespace EstateReportingAPI.Common +{ + using System; + using System.Diagnostics.CodeAnalysis; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + /// + /// + /// + /// + [ExcludeFromCodeCoverage] + public class SwaggerJsonConverter : JsonConverter + { + #region Properties + + /// + /// Gets a value indicating whether this can read JSON. + /// + /// + /// true if this can read JSON; otherwise, false. + /// + public override Boolean CanRead => false; + + #endregion + + #region Methods + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override Boolean CanConvert(Type objectType) + { + return true; + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// + /// The object value. + /// + /// + /// + public override Object ReadJson(JsonReader reader, + Type objectType, + Object existingValue, + JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, + Object value, + JsonSerializer serializer) + { + // Disable sending the $type in the serialized json + serializer.TypeNameHandling = TypeNameHandling.None; + + JToken t = JToken.FromObject(value); + t.WriteTo(writer); + } + + #endregion + } +} \ No newline at end of file diff --git a/EstateReportingAPI/Dockerfile b/EstateReportingAPI/Dockerfile new file mode 100644 index 0000000..7d4ef12 --- /dev/null +++ b/EstateReportingAPI/Dockerfile @@ -0,0 +1,24 @@ +FROM stuartferguson/txnprocbase AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["EstateReportingAPI/NuGet.Config", "."] +COPY ["EstateReportingAPI/EstateReportingAPI.csproj", "EstateReportingAPI/"] +RUN dotnet restore "EstateReportingAPI/EstateReportingAPI.csproj" +COPY . . +WORKDIR "/src/EstateReportingAPI" +RUN dotnet build "EstateReportingAPI.csproj" -c Release -o /app/build + +# Sort out certificate stuff here +RUN openssl x509 -inform DER -in /src/EstateReportingAPI/aspnetapp-root-cert.cer -out /src/EstateReportingAPI/aspnetapp-root-cert.crt +RUN cp /src/EstateReportingAPI/aspnetapp-root-cert.crt /usr/local/share/ca-certificates/ +RUN update-ca-certificates + +FROM build AS publish +RUN dotnet publish "EstateReportingAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "EstateReportingAPI.dll"] \ No newline at end of file diff --git a/EstateReportingAPI/Dockerfilewindows b/EstateReportingAPI/Dockerfilewindows new file mode 100644 index 0000000..fbba360 --- /dev/null +++ b/EstateReportingAPI/Dockerfilewindows @@ -0,0 +1,24 @@ +FROM stuartferguson/txnprocbasewindows AS base +USER ContainerAdministrator +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:7.0-windowsservercore-ltsc2019 AS build +WORKDIR /src +COPY ["EstateReportingAPI/NuGet.Config", "."] +COPY ["EstateReportingAPI/EstateReportingAPI.csproj", "EstateReportingAPI/"] +RUN dotnet restore "EstateReportingAPI/EstateReportingAPI.csproj" +COPY . . +WORKDIR "/src/EstateReportingAPI" +RUN dotnet build "EstateReportingAPI.csproj" -c Release -o /app/build + +WORKDIR "/src" +RUN %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -Command Import-PfxCertificate -FilePath "Certificates/aspnetapp-root-cert.pfx" -Password (ConvertTo-SecureString -String 'password' -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\Root + +WORKDIR "/src/EstateReportingAPI" +FROM build AS publish +RUN dotnet publish "EstateReportingAPI.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "EstateReportingAPI.dll"] diff --git a/EstateReportingAPI/EstateReportingAPI.csproj b/EstateReportingAPI/EstateReportingAPI.csproj new file mode 100644 index 0000000..674f62c --- /dev/null +++ b/EstateReportingAPI/EstateReportingAPI.csproj @@ -0,0 +1,47 @@ + + + + net7.0 + enable + enable + 3ed94abc-423c-49b8-ac5d-edc80e1eaa74 + Linux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + diff --git a/EstateReportingAPI/NuGet.Config b/EstateReportingAPI/NuGet.Config new file mode 100644 index 0000000..3086e20 --- /dev/null +++ b/EstateReportingAPI/NuGet.Config @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EstateReportingAPI/Program.cs b/EstateReportingAPI/Program.cs new file mode 100644 index 0000000..846b5a2 --- /dev/null +++ b/EstateReportingAPI/Program.cs @@ -0,0 +1,41 @@ +using System.Diagnostics.CodeAnalysis; +using Lamar.Microsoft.DependencyInjection; + +namespace EstateReportingAPI; + +[ExcludeFromCodeCoverage] +public class Program{ + + public static void Main(string[] args) + { + Program.CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + + + //At this stage, we only need our hosting file for ip and ports + FileInfo fi = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location); + + IConfigurationRoot config = new ConfigurationBuilder().SetBasePath(fi.Directory.FullName) + .AddJsonFile("hosting.json", optional: true) + .AddJsonFile("hosting.development.json", optional: true) + .AddEnvironmentVariables().Build(); + + IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args); + hostBuilder.UseWindowsService(); + hostBuilder.UseLamar(); + hostBuilder.ConfigureLogging(logging => + { + logging.AddConsole(); + }); + hostBuilder.ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + webBuilder.UseConfiguration(config); + webBuilder.UseKestrel(); + }); + return hostBuilder; + } +} \ No newline at end of file diff --git a/EstateReportingAPI/Properties/launchSettings.json b/EstateReportingAPI/Properties/launchSettings.json new file mode 100644 index 0000000..97e5211 --- /dev/null +++ b/EstateReportingAPI/Properties/launchSettings.json @@ -0,0 +1,33 @@ +{ + "profiles": { + "EstateReporting": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5011" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_URLS": "https://+:443;http://+:80" + }, + "publishAllPorts": true, + "useSSL": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:61790", + "sslPort": 44313 + } + } +} \ No newline at end of file diff --git a/EstateReportingAPI/Startup.cs b/EstateReportingAPI/Startup.cs new file mode 100644 index 0000000..9c6c865 --- /dev/null +++ b/EstateReportingAPI/Startup.cs @@ -0,0 +1,95 @@ +using EstateReportingAPI.Bootstrapper; +using HealthChecks.UI.Client; +using Lamar; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using NLog.Extensions.Logging; +using Shared.Extensions; +using Shared.General; +using Shared.Logger; + +namespace EstateReportingAPI +{ + public class Startup + { + public static IConfigurationRoot Configuration { get; set; } + public static IWebHostEnvironment WebHostEnvironment { get; set; } + + public static IServiceProvider ServiceProvider { get; set; } + + public static Container Container; + public Startup(IWebHostEnvironment webHostEnvironment) + { + IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(webHostEnvironment.ContentRootPath) + .AddJsonFile("/home/txnproc/config/appsettings.json", true, true) + .AddJsonFile($"/home/txnproc/config/appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true) + .AddEnvironmentVariables(); + + Configuration = builder.Build(); + WebHostEnvironment = webHostEnvironment; + } + + public void ConfigureContainer(ServiceRegistry services) + { + + ConfigurationReader.Initialise(Configuration); + + services.IncludeRegistry(); + + Container = new Container(services); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + { + string nlogConfigFilename = "nlog.config"; + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + loggerFactory.ConfigureNLog(Path.Combine(env.ContentRootPath, nlogConfigFilename)); + loggerFactory.AddNLog(); + + Microsoft.Extensions.Logging.ILogger logger = loggerFactory.CreateLogger("EstateManagement"); + + Logger.Initialise(logger); + + Action loggerAction = message => + { + Logger.LogInformation(message); + }; + Configuration.LogConfiguration(loggerAction); + + ConfigurationReader.Initialise(Configuration); + + app.AddRequestLogging(); + app.AddResponseLogging(); + app.AddExceptionHandler(); + + app.UseRouting(); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + endpoints.MapHealthChecks("health", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = Shared.HealthChecks.HealthCheckMiddleware.WriteResponse + }); + endpoints.MapHealthChecks("healthui", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + }); + app.UseSwagger(); + + app.UseSwaggerUI(); + } + } +} \ No newline at end of file diff --git a/EstateReportingAPI/appsettings.Development.json b/EstateReportingAPI/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/EstateReportingAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/EstateReportingAPI/appsettings.json b/EstateReportingAPI/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/EstateReportingAPI/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/EstateReportingAPI/aspnetapp-root-cert.cer b/EstateReportingAPI/aspnetapp-root-cert.cer new file mode 100644 index 0000000..c6ac5e9 Binary files /dev/null and b/EstateReportingAPI/aspnetapp-root-cert.cer differ diff --git a/EstateReportingAPI/hosting.json b/EstateReportingAPI/hosting.json new file mode 100644 index 0000000..cc79720 --- /dev/null +++ b/EstateReportingAPI/hosting.json @@ -0,0 +1,3 @@ +{ + "urls": "http://*:5011" +} \ No newline at end of file diff --git a/EstateReportingAPI/nlog.config b/EstateReportingAPI/nlog.config new file mode 100644 index 0000000..fbaf827 --- /dev/null +++ b/EstateReportingAPI/nlog.config @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + +