diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..3729ff0c
--- /dev/null
+++ b/.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/.github/release-drafter.yml b/.github/release-drafter.yml
new file mode 100644
index 00000000..62aef736
--- /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/createrelease.yml b/.github/workflows/createrelease.yml
new file mode 100644
index 00000000..afe0bffa
--- /dev/null
+++ b/.github/workflows/createrelease.yml
@@ -0,0 +1,110 @@
+name: Release
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ build:
+ name: "Release"
+ env:
+ ASPNETCORE_ENVIRONMENT: "Production"
+
+ runs-on: ubuntu-16.04
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Get the version
+ id: get_version
+ run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
+
+ - name: Setup .NET Core 3.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.0.100
+
+ - name: Restore Nuget Packages
+ run: dotnet restore TransactionProcessor.sln --source https://api.nuget.org/v3/index.json --source https://www.myget.org/F/transactionprocessing/api/v3/index.json
+
+ - name: Build Code
+ run: dotnet build TransactionProcessor.sln --configuration Release
+
+ - name: Build Docker Images
+ run: |
+ docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest --tag stuartferguson/transactionprocessor:latest --tag stuartferguson/transactionprocessor:${{ steps.get_version.outputs.VERSION }}
+
+ - name: Publish Images to Docker Hub
+ run: |
+ docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }}
+ docker push stuartferguson/transactionprocessor:latest
+ docker push stuartferguson/transactionprocessor:${{ steps.get_version.outputs.VERSION }}
+
+ - name: Publish API
+ run: dotnet publish "TransactionProcessor\TransactionProcessor.csproj" --configuration Release --output publishOutput
+
+ - name: Setup .NET Core 2.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 2.0.0
+
+ - name: Extract Octopus Tools
+ run: |
+ mkdir /opt/octo
+ cd /opt/octo
+ wget -O /opt/octo/octopus.zip https://download.octopusdeploy.com/octopus-tools/6.12.0/OctopusTools.6.12.0.portable.zip
+ unzip /opt/octo/octopus.zip
+ chmod +x /opt/octo/Octo
+
+ - name: Pack Files for Octopus
+ run: >-
+ /opt/octo/Octo pack
+ --outFolder /home/runner/work/TransactionProcessor/TransactionProcessor
+ --basePath /home/runner/work/TransactionProcessor/TransactionProcessor/publishOutput
+ --id TransactionProcessor
+ --version ${{ steps.get_version.outputs.VERSION }}
+ --format zip
+ --verbose
+ --logLevel=verbose
+
+ - name: Push Package to Octopus
+ run: >-
+ /opt/octo/Octo push
+ --server http://sferguson.ddns.net:9001
+ --apiKey API-UTN58QCF8HSATACNUBY41XPUC
+ --package /home/runner/work/TransactionProcessor/TransactionProcessor/TransactionProcessor.${{ steps.get_version.outputs.VERSION }}.zip
+ --overwrite-mode IgnoreIfExists
+
+ - name: Get Release
+ id: getrelease
+ uses: octokit/request-action@v1.x
+ with:
+ route: GET /repos/StuartFerguson/TransactionProcessor/releases/tags/${{ steps.get_version.outputs.VERSION }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build Release Notes
+ id: buildreleasenotes
+ uses: gr2m/get-json-paths-action@v1.x
+ with:
+ json: ${{ steps.getrelease.outputs.data }}
+ releasenote: "body"
+
+ - name: Create & Deploy Release in Octopus
+ run: >-
+ /opt/octo/Octo create-release
+ --server http://sferguson.ddns.net:9001
+ --apiKey API-UTN58QCF8HSATACNUBY41XPUC
+ --project "Transaction Processor"
+ --version ${{ steps.get_version.outputs.VERSION }}
+ --channel Default
+ --deployTo Development
+ --waitfordeployment
+ --deploymenttimeout 00:05:00
+ --releasenotes "${{ steps.buildreleasenotes.outputs.releasenote }}"
+
+ - name: Setup .NET Core 3.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.0.100
+
diff --git a/.github/workflows/nightlybuild.yml b/.github/workflows/nightlybuild.yml
new file mode 100644
index 00000000..fd89f627
--- /dev/null
+++ b/.github/workflows/nightlybuild.yml
@@ -0,0 +1,30 @@
+name: Nightly Build
+
+on:
+ schedule:
+ - cron: "* 23 * * *"
+
+jobs:
+ build:
+ name: "Nightly Build"
+ env:
+ ASPNETCORE_ENVIRONMENT: "Production"
+
+ runs-on: ubuntu-16.04
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.0.100
+
+ - name: Restore Nuget Packages
+ run: dotnet restore TransactionProcessor.sln --source https://api.nuget.org/v3/index.json --source https://www.myget.org/F/transactionprocessing/api/v3/index.json
+
+ - name: Build Code
+ run: dotnet build TransactionProcessor.sln --configuration Release
+
+ - name: Build Docker Image
+ run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest
diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
new file mode 100644
index 00000000..c7bf4c49
--- /dev/null
+++ b/.github/workflows/pullrequest.yml
@@ -0,0 +1,32 @@
+name: Build and Test Pull Requests
+
+on:
+ pull_request:
+ branches:
+ - master
+
+jobs:
+ build:
+ name: "Build and Test Pull Requests"
+ env:
+ ASPNETCORE_ENVIRONMENT: "Production"
+
+ runs-on: ubuntu-16.04
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 3.0.100
+
+ - name: Restore Nuget Packages
+ run: dotnet restore TransactionProcessor.sln --source https://api.nuget.org/v3/index.json --source https://www.myget.org/F/transactionprocessing/api/v3/index.json
+
+ - name: Build Code
+ run: dotnet build TransactionProcessor.sln --configuration Release
+
+ - name: Build Docker Image
+ run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest
+
diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml
new file mode 100644
index 00000000..83d8d984
--- /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:
+ - master
+
+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.2.0
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 3e759b75..5ae0db95 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
*.user
*.userosscache
*.sln.docstates
+*.[Dd]evelopment.json
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
diff --git a/TransactionProcessor.BusinessLogic/CommandHandlers/CommandRouter.cs b/TransactionProcessor.BusinessLogic/CommandHandlers/CommandRouter.cs
new file mode 100644
index 00000000..a33c7f4f
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/CommandHandlers/CommandRouter.cs
@@ -0,0 +1,64 @@
+namespace TransactionProcessor.BusinessLogic.CommandHandlers
+{
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Commands;
+ using Services;
+ using Shared.DomainDrivenDesign.CommandHandling;
+
+ ///
+ ///
+ ///
+ ///
+ public class CommandRouter : ICommandRouter
+ {
+ #region Fields
+
+ ///
+ /// The transaction domain service
+ ///
+ private readonly ITransactionDomainService TransactionDomainService;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transaction domain service.
+ public CommandRouter(ITransactionDomainService transactionDomainService)
+ {
+ this.TransactionDomainService = transactionDomainService;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Routes the specified command.
+ ///
+ /// The command.
+ /// The cancellation token.
+ public async Task Route(ICommand command,
+ CancellationToken cancellationToken)
+ {
+ ICommandHandler commandHandler = CreateHandler((dynamic)command);
+
+ await commandHandler.Handle(command, cancellationToken);
+ }
+
+ ///
+ /// Creates the handler.
+ ///
+ /// The command.
+ ///
+ private ICommandHandler CreateHandler(ProcessLogonTransactionCommand command)
+ {
+ return new TransactionCommandHandler(this.TransactionDomainService);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs b/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs
new file mode 100644
index 00000000..1da86ca4
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs
@@ -0,0 +1,66 @@
+namespace TransactionProcessor.BusinessLogic.CommandHandlers
+{
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Commands;
+ using Models;
+ using Services;
+ using Shared.DomainDrivenDesign.CommandHandling;
+
+ ///
+ ///
+ ///
+ ///
+ public class TransactionCommandHandler : ICommandHandler
+ {
+ #region Fields
+
+ ///
+ /// The transaction domain service
+ ///
+ private readonly ITransactionDomainService TransactionDomainService;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The transaction domain service.
+ public TransactionCommandHandler(ITransactionDomainService transactionDomainService)
+ {
+ this.TransactionDomainService = transactionDomainService;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Handles the specified command.
+ ///
+ /// The command.
+ /// The cancellation token.
+ public async Task Handle(ICommand command,
+ CancellationToken cancellationToken)
+ {
+ await this.HandleCommand((dynamic)command, cancellationToken);
+ }
+
+ ///
+ /// Handles the command.
+ ///
+ /// The command.
+ /// The cancellation token.
+ private async Task HandleCommand(ProcessLogonTransactionCommand command,
+ CancellationToken cancellationToken)
+ {
+ ProcessLogonTransactionResponse logonResponse = await this.TransactionDomainService.ProcessLogonTransaction(cancellationToken);
+
+ command.Response = logonResponse;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs b/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs
new file mode 100644
index 00000000..8f5433cd
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs
@@ -0,0 +1,25 @@
+namespace TransactionProcessor.BusinessLogic.Commands
+{
+ using System;
+ using Models;
+ using Shared.DomainDrivenDesign.CommandHandling;
+
+ ///
+ ///
+ ///
+ ///
+ public class ProcessLogonTransactionCommand : Command
+ {
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The command identifier.
+ public ProcessLogonTransactionCommand(Guid commandId) : base(commandId)
+ {
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs
new file mode 100644
index 00000000..2cc83f9f
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs
@@ -0,0 +1,23 @@
+namespace TransactionProcessor.BusinessLogic.Services
+{
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Models;
+
+ ///
+ ///
+ ///
+ public interface ITransactionDomainService
+ {
+ #region Methods
+
+ ///
+ /// Processes the logon transaction.
+ ///
+ /// The cancellation token.
+ ///
+ Task ProcessLogonTransaction(CancellationToken cancellationToken);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs
new file mode 100644
index 00000000..3785dbca
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs
@@ -0,0 +1,31 @@
+namespace TransactionProcessor.BusinessLogic.Services
+{
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Models;
+
+ ///
+ ///
+ ///
+ ///
+ public class TransactionDomainService : ITransactionDomainService
+ {
+ #region Methods
+
+ ///
+ /// Processes the logon transaction.
+ ///
+ /// The cancellation token.
+ ///
+ public async Task ProcessLogonTransaction(CancellationToken cancellationToken)
+ {
+ return new ProcessLogonTransactionResponse
+ {
+ ResponseMessage = "SUCCESS",
+ ResponseCode = 0
+ };
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj
new file mode 100644
index 00000000..1e0a1c46
--- /dev/null
+++ b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs b/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs
new file mode 100644
index 00000000..d570e116
--- /dev/null
+++ b/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs
@@ -0,0 +1,54 @@
+namespace TransactionProcessor.DataTransferObjects
+{
+ using System;
+
+ ///
+ ///
+ ///
+ public class LogonTransactionRequest
+ {
+ #region Properties
+
+ ///
+ /// Gets or sets the imei number.
+ ///
+ ///
+ /// The imei number.
+ ///
+ public String IMEINumber { get; set; }
+
+ ///
+ /// Gets or sets the merchant identifier.
+ ///
+ ///
+ /// The merchant identifier.
+ ///
+ public Guid MerchantId { get; set; }
+
+ ///
+ /// Gets or sets the transaction date time.
+ ///
+ ///
+ /// The transaction date time.
+ ///
+ public DateTime TransactionDateTime { get; set; }
+
+ ///
+ /// Gets or sets the transaction number.
+ ///
+ ///
+ /// The transaction number.
+ ///
+ public String TransactionNumber { get; set; }
+
+ ///
+ /// Gets or sets the type of the transaction.
+ ///
+ ///
+ /// The type of the transaction.
+ ///
+ public String TransactionType { get; set; }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.DataTransferObjects/LogonTransactionResponse.cs b/TransactionProcessor.DataTransferObjects/LogonTransactionResponse.cs
new file mode 100644
index 00000000..3c59e218
--- /dev/null
+++ b/TransactionProcessor.DataTransferObjects/LogonTransactionResponse.cs
@@ -0,0 +1,30 @@
+namespace TransactionProcessor.DataTransferObjects
+{
+ using System;
+
+ ///
+ ///
+ ///
+ public class LogonTransactionResponse
+ {
+ #region Properties
+
+ ///
+ /// Gets or sets the response code.
+ ///
+ ///
+ /// The response code.
+ ///
+ public Int32 ResponseCode { get; set; }
+
+ ///
+ /// Gets or sets the response message.
+ ///
+ ///
+ /// The response message.
+ ///
+ public String ResponseMessage { get; set; }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj b/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj
new file mode 100644
index 00000000..f45bdfcc
--- /dev/null
+++ b/TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.1
+
+
+
diff --git a/TransactionProcessor.Models/ProcessLogonTransactionResponse.cs b/TransactionProcessor.Models/ProcessLogonTransactionResponse.cs
new file mode 100644
index 00000000..c394e426
--- /dev/null
+++ b/TransactionProcessor.Models/ProcessLogonTransactionResponse.cs
@@ -0,0 +1,30 @@
+namespace TransactionProcessor.Models
+{
+ using System;
+
+ ///
+ ///
+ ///
+ public class ProcessLogonTransactionResponse
+ {
+ #region Properties
+
+ ///
+ /// Gets or sets the response code.
+ ///
+ ///
+ /// The response code.
+ ///
+ public Int32 ResponseCode { get; set; }
+
+ ///
+ /// Gets or sets the response message.
+ ///
+ ///
+ /// The response message.
+ ///
+ public String ResponseMessage { get; set; }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor.Models/TransactionProcessor.Models.csproj b/TransactionProcessor.Models/TransactionProcessor.Models.csproj
new file mode 100644
index 00000000..ea83d296
--- /dev/null
+++ b/TransactionProcessor.Models/TransactionProcessor.Models.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netcoreapp3.0
+
+
+
diff --git a/TransactionProcessor.sln b/TransactionProcessor.sln
new file mode 100644
index 00000000..4f3265f2
--- /dev/null
+++ b/TransactionProcessor.sln
@@ -0,0 +1,53 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29509.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionProcessor", "TransactionProcessor\TransactionProcessor.csproj", "{1EBD3402-AF91-4919-A5A1-2E3728918507}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{749ADE74-A6F0-4469-A638-8FD7E82A8667}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{71B30DC4-AB27-4D30-8481-B4C326D074CB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionProcessor.DataTransferObjects", "TransactionProcessor.DataTransferObjects\TransactionProcessor.DataTransferObjects.csproj", "{405F1DE4-9BAA-4B5D-8707-C78B2C3E9040}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionProcessor.BusinessLogic", "TransactionProcessor.BusinessLogic\TransactionProcessor.BusinessLogic.csproj", "{6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionProcessor.Models", "TransactionProcessor.Models\TransactionProcessor.Models.csproj", "{97B646C6-7BF7-4F84-A74A-10E50A70CB91}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1EBD3402-AF91-4919-A5A1-2E3728918507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1EBD3402-AF91-4919-A5A1-2E3728918507}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1EBD3402-AF91-4919-A5A1-2E3728918507}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1EBD3402-AF91-4919-A5A1-2E3728918507}.Release|Any CPU.Build.0 = Release|Any CPU
+ {405F1DE4-9BAA-4B5D-8707-C78B2C3E9040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {405F1DE4-9BAA-4B5D-8707-C78B2C3E9040}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {405F1DE4-9BAA-4B5D-8707-C78B2C3E9040}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {405F1DE4-9BAA-4B5D-8707-C78B2C3E9040}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97B646C6-7BF7-4F84-A74A-10E50A70CB91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97B646C6-7BF7-4F84-A74A-10E50A70CB91}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97B646C6-7BF7-4F84-A74A-10E50A70CB91}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97B646C6-7BF7-4F84-A74A-10E50A70CB91}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1EBD3402-AF91-4919-A5A1-2E3728918507} = {749ADE74-A6F0-4469-A638-8FD7E82A8667}
+ {405F1DE4-9BAA-4B5D-8707-C78B2C3E9040} = {749ADE74-A6F0-4469-A638-8FD7E82A8667}
+ {6CCAAA44-AC4F-40DA-B5D4-F4390DD729C0} = {749ADE74-A6F0-4469-A638-8FD7E82A8667}
+ {97B646C6-7BF7-4F84-A74A-10E50A70CB91} = {749ADE74-A6F0-4469-A638-8FD7E82A8667}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {193D13DE-424B-4D50-B674-01F9E4CC2CA9}
+ EndGlobalSection
+EndGlobal
diff --git a/TransactionProcessor/Common/ConfigureSwaggerOptions.cs b/TransactionProcessor/Common/ConfigureSwaggerOptions.cs
new file mode 100644
index 00000000..92353d6c
--- /dev/null
+++ b/TransactionProcessor/Common/ConfigureSwaggerOptions.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TransactionProcessor.Common
+{
+ using System.Diagnostics.CodeAnalysis;
+ using Microsoft.AspNetCore.Mvc.ApiExplorer;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Options;
+ using Microsoft.OpenApi.Models;
+ using Swashbuckle.AspNetCore.SwaggerGen;
+
+ ///
+ /// Configures the Swagger generation options.
+ ///
+ /// This allows API versioning to define a Swagger document per API version after the
+ /// service has been resolved from the service container.
+ [ExcludeFromCodeCoverage]
+ public class ConfigureSwaggerOptions : IConfigureOptions
+ {
+ #region Fields
+
+ ///
+ /// The provider
+ ///
+ private readonly IApiVersionDescriptionProvider provider;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The provider used to generate Swagger documents.
+ public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;
+
+ #endregion
+
+ #region Methods
+
+ ///
+ public void Configure(SwaggerGenOptions options)
+ {
+ // add a swagger document for each discovered API version
+ // note: you might choose to skip or document deprecated API versions differently
+ foreach (ApiVersionDescription description in this.provider.ApiVersionDescriptions)
+ {
+ options.SwaggerDoc(description.GroupName, ConfigureSwaggerOptions.CreateInfoForApiVersion(description));
+ }
+ }
+
+ ///
+ /// Creates the information for API version.
+ ///
+ /// The description.
+ ///
+ private static OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
+ {
+ OpenApiInfo info = new OpenApiInfo
+ {
+ Title = "Golf Handicapping API",
+ Version = description.ApiVersion.ToString(),
+ Description = "A REST Api to manage the golf club handicapping system.",
+ Contact = new OpenApiContact
+ {
+ Name = "Stuart Ferguson",
+ Email = "golfhandicapping@btinternet.com"
+ },
+ License = new OpenApiLicense
+ {
+ Name = "TODO"
+ }
+ };
+
+ if (description.IsDeprecated)
+ {
+ info.Description += " This API version has been deprecated.";
+ }
+
+ return info;
+ }
+
+ #endregion
+ }
+}
diff --git a/TransactionProcessor/Common/SwaggerDefaultValues.cs b/TransactionProcessor/Common/SwaggerDefaultValues.cs
new file mode 100644
index 00000000..ca37aabe
--- /dev/null
+++ b/TransactionProcessor/Common/SwaggerDefaultValues.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TransactionProcessor.Common
+{
+ using System.Diagnostics.CodeAnalysis;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.AspNetCore.Mvc.Abstractions;
+ using Microsoft.AspNetCore.Mvc.ApiExplorer;
+ using Microsoft.AspNetCore.Mvc.Versioning;
+ 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;
+ ApiVersion apiVersion = apiDescription.GetApiVersion();
+ ApiVersionModel model = apiDescription.ActionDescriptor.GetApiVersionModel(ApiVersionMapping.Explicit | ApiVersionMapping.Implicit);
+
+ operation.Deprecated = model.DeprecatedApiVersions.Contains(apiVersion);
+
+ 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/TransactionProcessor/Common/SwaggerJsonConverter.cs b/TransactionProcessor/Common/SwaggerJsonConverter.cs
new file mode 100644
index 00000000..28ef4a32
--- /dev/null
+++ b/TransactionProcessor/Common/SwaggerJsonConverter.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TransactionProcessor.Common
+{
+ 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
+ }
+}
diff --git a/TransactionProcessor/Controllers/TransactionController.cs b/TransactionProcessor/Controllers/TransactionController.cs
new file mode 100644
index 00000000..752a3f27
--- /dev/null
+++ b/TransactionProcessor/Controllers/TransactionController.cs
@@ -0,0 +1,89 @@
+namespace TransactionProcessor.Controllers
+{
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using BusinessLogic.Commands;
+ using DataTransferObjects;
+ using Factories;
+ using Microsoft.AspNetCore.Mvc;
+ using Shared.DomainDrivenDesign.CommandHandling;
+
+ ///
+ ///
+ ///
+ ///
+ [ExcludeFromCodeCoverage]
+ [Route(TransactionController.ControllerRoute)]
+ [ApiController]
+ [ApiVersion("1.0")]
+ public class TransactionController : ControllerBase
+ {
+ #region Fields
+
+ ///
+ /// The command router
+ ///
+ private readonly ICommandRouter CommandRouter;
+
+ ///
+ /// The model factory
+ ///
+ private readonly IModelFactory ModelFactory;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The command router.
+ /// The model factory.
+ public TransactionController(ICommandRouter commandRouter,
+ IModelFactory modelFactory)
+ {
+ this.CommandRouter = commandRouter;
+ this.ModelFactory = modelFactory;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Logons the transaction.
+ ///
+ /// The logon transaction request.
+ /// The cancellation token.
+ ///
+ [HttpPost]
+ [Route("")]
+ public async Task LogonTransaction([FromBody] LogonTransactionRequest logonTransactionRequest,
+ CancellationToken cancellationToken)
+ {
+ ProcessLogonTransactionCommand command = new ProcessLogonTransactionCommand(Guid.NewGuid());
+
+ await this.CommandRouter.Route(command, cancellationToken);
+
+ return this.Ok(this.ModelFactory.ConvertFrom(command.Response));
+ }
+
+ #endregion
+
+ #region Others
+
+ ///
+ /// The controller name
+ ///
+ public const String ControllerName = "transactions";
+
+ ///
+ /// The controller route
+ ///
+ private const String ControllerRoute = "api/" + TransactionController.ControllerName;
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor/Dockerfile b/TransactionProcessor/Dockerfile
new file mode 100644
index 00000000..344b150d
--- /dev/null
+++ b/TransactionProcessor/Dockerfile
@@ -0,0 +1,24 @@
+FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
+WORKDIR /app
+EXPOSE 80
+
+FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
+WORKDIR /src
+COPY ["TransactionProcessor/NuGet.Config", "."]
+COPY ["TransactionProcessor/TransactionProcessor.csproj", "TransactionProcessor/"]
+COPY ["TransactionProcessor/NuGet.Config", "TransactionProcessor/"]
+COPY ["TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj", "TransactionProcessor.DataTransferObjects/"]
+COPY ["TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj", "TransactionProcessor.BusinessLogic/"]
+COPY ["TransactionProcessor.Models/TransactionProcessor.Models.csproj", "TransactionProcessor.Models/"]
+RUN dotnet restore "TransactionProcessor/TransactionProcessor.csproj"
+COPY . .
+WORKDIR "/src/TransactionProcessor"
+RUN dotnet build "TransactionProcessor.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "TransactionProcessor.csproj" -c Release -o /app/publish
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "TransactionProcessor.dll"]
\ No newline at end of file
diff --git a/TransactionProcessor/Factories/IModelFactory.cs b/TransactionProcessor/Factories/IModelFactory.cs
new file mode 100644
index 00000000..16bde727
--- /dev/null
+++ b/TransactionProcessor/Factories/IModelFactory.cs
@@ -0,0 +1,22 @@
+namespace TransactionProcessor.Factories
+{
+ using DataTransferObjects;
+ using Models;
+
+ ///
+ ///
+ ///
+ public interface IModelFactory
+ {
+ #region Methods
+
+ ///
+ /// Converts from.
+ ///
+ /// The process logon transaction response.
+ ///
+ LogonTransactionResponse ConvertFrom(ProcessLogonTransactionResponse processLogonTransactionResponse);
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor/Factories/ModelFactory.cs b/TransactionProcessor/Factories/ModelFactory.cs
new file mode 100644
index 00000000..af473e19
--- /dev/null
+++ b/TransactionProcessor/Factories/ModelFactory.cs
@@ -0,0 +1,30 @@
+namespace TransactionProcessor.Factories
+{
+ using DataTransferObjects;
+ using Models;
+
+ ///
+ ///
+ ///
+ ///
+ public class ModelFactory : IModelFactory
+ {
+ #region Methods
+
+ ///
+ /// Converts from.
+ ///
+ /// The process logon transaction response.
+ ///
+ public LogonTransactionResponse ConvertFrom(ProcessLogonTransactionResponse processLogonTransactionResponse)
+ {
+ return new LogonTransactionResponse
+ {
+ ResponseMessage = processLogonTransactionResponse.ResponseMessage,
+ ResponseCode = processLogonTransactionResponse.ResponseCode
+ };
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/TransactionProcessor/NuGet.Config b/TransactionProcessor/NuGet.Config
new file mode 100644
index 00000000..c6bc4ff9
--- /dev/null
+++ b/TransactionProcessor/NuGet.Config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TransactionProcessor/Program.cs b/TransactionProcessor/Program.cs
new file mode 100644
index 00000000..27e0dfe6
--- /dev/null
+++ b/TransactionProcessor/Program.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace TransactionProcessor
+{
+ using System.Diagnostics.CodeAnalysis;
+ using System.IO;
+ using Autofac.Extensions.DependencyInjection;
+
+ [ExcludeFromCodeCoverage]
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ Program.CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args)
+ {
+ Console.Title = "Transaction Processor";
+
+ //At this stage, we only need our hosting file for ip and ports
+ IConfigurationRoot config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("hosting.json", optional: true)
+ .AddJsonFile("hosting.development.json", optional: true)
+ .AddEnvironmentVariables().Build();
+
+ IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);
+ hostBuilder.ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ webBuilder.UseConfiguration(config);
+ webBuilder.UseKestrel();
+ }).UseServiceProviderFactory(new AutofacServiceProviderFactory());
+ return hostBuilder;
+ }
+
+ }
+}
diff --git a/TransactionProcessor/Startup.cs b/TransactionProcessor/Startup.cs
new file mode 100644
index 00000000..eb556714
--- /dev/null
+++ b/TransactionProcessor/Startup.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace TransactionProcessor
+{
+ using System.Diagnostics.CodeAnalysis;
+ using System.IO;
+ using System.Reflection;
+ using Autofac;
+ using BusinessLogic.CommandHandlers;
+ using BusinessLogic.Services;
+ using Common;
+ using Microsoft.AspNetCore.Mvc.ApiExplorer;
+ using Microsoft.AspNetCore.Mvc.Versioning;
+ using Microsoft.Extensions.Options;
+ using Newtonsoft.Json;
+ using Newtonsoft.Json.Serialization;
+ using NLog.Extensions.Logging;
+ using Shared.DomainDrivenDesign.CommandHandling;
+ using Shared.Extensions;
+ using Shared.General;
+ using Swashbuckle.AspNetCore.Filters;
+ using Swashbuckle.AspNetCore.SwaggerGen;
+
+ [ExcludeFromCodeCoverage]
+ public class Startup
+ {
+ public Startup(IWebHostEnvironment webHostEnvironment)
+ {
+ IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(webHostEnvironment.ContentRootPath)
+ .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
+ .AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true).AddEnvironmentVariables();
+
+ Startup.Configuration = builder.Build();
+ Startup.WebHostEnvironment = webHostEnvironment;
+ }
+
+ public static IConfigurationRoot Configuration { get; set; }
+
+ public static IWebHostEnvironment WebHostEnvironment { get; set; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ this.ConfigureMiddlewareServices(services);
+
+ services.AddSingleton();
+ }
+
+ public void ConfigureContainer(ContainerBuilder builder)
+ {
+ builder.RegisterType().As().SingleInstance();
+ builder.RegisterType().As().SingleInstance();
+ }
+
+ private void ConfigureMiddlewareServices(IServiceCollection services)
+ {
+ services.AddApiVersioning(
+ options =>
+ {
+ // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
+ options.ReportApiVersions = true;
+ options.DefaultApiVersion = new ApiVersion(1, 0);
+ options.AssumeDefaultVersionWhenUnspecified = true;
+ options.ApiVersionReader = new HeaderApiVersionReader("api-version");
+ });
+
+ services.AddVersionedApiExplorer(
+ options =>
+ {
+ // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
+ // note: the specified format code will format the version as "'v'major[.minor][-status]"
+ options.GroupNameFormat = "'v'VVV";
+
+ // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
+ // can also be used to control the format of the API version in route templates
+ options.SubstituteApiVersionInUrl = true;
+ });
+
+ services.AddTransient, ConfigureSwaggerOptions>();
+
+ services.AddSwaggerGen(c =>
+ {
+ // add a custom operation filter which sets default values
+ c.OperationFilter();
+ c.ExampleFilters();
+ });
+
+ services.AddSwaggerExamplesFromAssemblyOf();
+
+ services.AddControllers().AddNewtonsoftJson(options =>
+ {
+ options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+ options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
+ options.SerializerSettings.Formatting = Formatting.Indented;
+ options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
+ options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
+ });
+
+ Assembly assembly = this.GetType().GetTypeInfo().Assembly;
+ services.AddMvcCore().AddApplicationPart(assembly).AddControllersAsServices();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory,
+ IApiVersionDescriptionProvider provider)
+ {
+ String nlogConfigFilename = "nlog.config";
+
+ if (env.IsDevelopment())
+ {
+ nlogConfigFilename = $"nlog.{env.EnvironmentName}.config";
+ app.UseDeveloperExceptionPage();
+ }
+
+ loggerFactory.ConfigureNLog(Path.Combine(env.ContentRootPath, nlogConfigFilename));
+ loggerFactory.AddNLog();
+
+ ILogger logger = loggerFactory.CreateLogger("TransactionProcessor");
+
+ Logger.Initialise(logger);
+
+ ConfigurationReader.Initialise(Startup.Configuration);
+
+ app.AddRequestLogging();
+ app.AddResponseLogging();
+ app.AddExceptionHandler();
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+
+ app.UseSwagger();
+
+ app.UseSwaggerUI(
+ options =>
+ {
+ // build a swagger endpoint for each discovered API version
+ foreach (ApiVersionDescription description in provider.ApiVersionDescriptions)
+ {
+ options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
+ }
+ });
+
+ //if (String.Compare(ConfigurationReader.GetValue("EventStoreSettings", "START_PROJECTIONS"),
+ // Boolean.TrueString,
+ // StringComparison.InvariantCultureIgnoreCase) == 0)
+ //{
+ // app.PreWarm(true).Wait();
+ //}
+ //else
+ //{
+ // app.PreWarm();
+ //}
+ }
+ }
+}
diff --git a/TransactionProcessor/TransactionProcessor.csproj b/TransactionProcessor/TransactionProcessor.csproj
new file mode 100644
index 00000000..b5216dd1
--- /dev/null
+++ b/TransactionProcessor/TransactionProcessor.csproj
@@ -0,0 +1,47 @@
+
+
+
+ netcoreapp3.0
+ Linux
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/TransactionProcessor/appsettings.json b/TransactionProcessor/appsettings.json
new file mode 100644
index 00000000..d9d9a9bf
--- /dev/null
+++ b/TransactionProcessor/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/TransactionProcessor/hosting.json b/TransactionProcessor/hosting.json
new file mode 100644
index 00000000..31289e7e
--- /dev/null
+++ b/TransactionProcessor/hosting.json
@@ -0,0 +1,3 @@
+{
+ "urls": "http://*:5002"
+}
\ No newline at end of file
diff --git a/TransactionProcessor/nlog.config b/TransactionProcessor/nlog.config
new file mode 100644
index 00000000..805ddd3a
--- /dev/null
+++ b/TransactionProcessor/nlog.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TransactionProcessor/nlog.development.config b/TransactionProcessor/nlog.development.config
new file mode 100644
index 00000000..7144c7b6
--- /dev/null
+++ b/TransactionProcessor/nlog.development.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file