Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/createrelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
run: |
docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest --tag stuartferguson/transactionprocessor:latest --tag stuartferguson/transactionprocessor:${{ steps.get_version.outputs.VERSION }}

- name: Run Integration Tests
run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj"

- name: Publish Images to Docker Hub
run: |
docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/nightlybuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ jobs:

- name: Build Docker Image
run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest

- name: Run Integration Tests
run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj"
2 changes: 2 additions & 0 deletions .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ jobs:
- name: Build Docker Image
run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest

- name: Run Integration Tests
run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
# TransactionProcessor
# TransactionProcessor

## Build Status

[![Last Nightly Build Status Badge](https://github.com/StuartFerguson/TransactionProcessor/workflows/Nightly%20Build/badge.svg)](https://github.com/StuartFerguson/TransactionProcessor/workflows/Nightly%20Build/badge.svg)
[![Last Release Build Status Badge](https://github.com/StuartFerguson/TransactionProcessor/workflows/Release/badge.svg)](https://github.com/StuartFerguson/TransactionProcessor/workflows/Release/badge.svg)

## Nuget Versions



## Code Coverage Results

[![Coverage Status](https://coveralls.io/repos/github/StuartFerguson/TransactionProcessor/badge.svg)](https://coveralls.io/github/StuartFerguson/TransactionProcessor)

## Code Quality Results

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5bcb33c3c68e473193a872f0d3375f61)](https://www.codacy.com/manual/stuart_ferguson1/TransactionProcessor?utm_source=github.com&utm_medium=referral&utm_content=StuartFerguson/TransactionProcessor&utm_campaign=Badge_Grade)
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public async Task<ProcessLogonTransactionResponse> ProcessLogonTransaction(Guid
return new ProcessLogonTransactionResponse
{
ResponseMessage = transactionAggregate.ResponseMessage,
ResponseCode = transactionAggregate.ResponseCode
ResponseCode = transactionAggregate.ResponseCode,
EstateId = estateId,
MerchantId = merchantId
};
}

Expand Down
37 changes: 37 additions & 0 deletions TransactionProcessor.DataTransferObjects/DataTransferObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace TransactionProcessor.DataTransferObjects
{
using System;

/// <summary>
///
/// </summary>
public abstract class DataTransferObject
{
#region Properties

// This only here as a shell base class...
/// <summary>
/// Gets or sets the estate identifier.
/// </summary>
/// <value>
/// The estate identifier.
/// </value>
public Guid EstateId { get; set; }

/// <summary>
/// Gets or sets the merchant identifier.
/// </summary>
/// <value>
/// The merchant identifier.
/// </value>
public Guid MerchantId { get; set; }

#endregion
}

public class MetadataContants
{
public const String KeyNameEstateId = "EstateId";
public const String KeyNameMerchantId = "MerchantId";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
///
/// </summary>
[ExcludeFromCodeCoverage]
public class LogonTransactionRequest
public class LogonTransactionRequest : DataTransferObject
{
#region Properties

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ public class LogonTransactionResponse
{
#region Properties

public Guid EstateId { get; set; }
public Guid MerchantId { get; set; }

/// <summary>
/// Gets or sets the response code.
/// </summary>
Expand Down
46 changes: 46 additions & 0 deletions TransactionProcessor.DataTransferObjects/SerialisedMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace TransactionProcessor.DataTransferObjects
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

/// <summary>
///
/// </summary>
public class SerialisedMessage
{
#region Constructors

/// <summary>
/// Initializes a new instance of the <see cref="SerialisedMessage"/> class.
/// </summary>
public SerialisedMessage()
{
this.Metadata = new Dictionary<String, String>();
}

#endregion

#region Properties

/// <summary>
/// Gets or sets the metadata.
/// </summary>
/// <value>
/// The metadata.
/// </value>
[JsonProperty("metadata")]
public Dictionary<String, String> Metadata { get; set; }

/// <summary>
/// Gets or sets the serialised data.
/// </summary>
/// <value>
/// The serialised data.
/// </value>
[JsonProperty("serialised_data")]
public String SerialisedData { get; set; }

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

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

</Project>
171 changes: 165 additions & 6 deletions TransactionProcessor.IntegrationTests/Common/DockerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,169 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace TransactionProcessor.IntegrationTests.Common
namespace TransactionProcessor.IntegrationTests.Common
{
class DockerHelper
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Ductus.FluentDocker.Builders;
using Ductus.FluentDocker.Model.Builders;
using Ductus.FluentDocker.Services;
using Ductus.FluentDocker.Services.Extensions;
using EstateManagement.Client;

public class DockerHelper
{
protected INetworkService TestNetwork;

protected Int32 EstateManagementPort;
protected Int32 TransactionProcessorPort;
protected Int32 EventStorePort;

protected IContainerService EstateManagementContainer;
protected IContainerService TransactionProcessorContainer;
protected IContainerService EventStoreContainer;

public IEstateClient EstateClient;
public HttpClient HttpClient;

protected String EventStoreConnectionString;

protected String EstateManagementContainerName;
protected String TransactionProcessorContainerName;
protected String EventStoreContainerName;

private void SetupTestNetwork()
{
// Build a network
this.TestNetwork = new Ductus.FluentDocker.Builders.Builder().UseNetwork($"testnetwork{Guid.NewGuid()}").Build();
}
public Guid TestId;
private void SetupEventStoreContainer(String traceFolder)
{
// Event Store Container
this.EventStoreContainer = new Ductus.FluentDocker.Builders.Builder()
.UseContainer()
.UseImage("eventstore/eventstore:release-5.0.2")
.ExposePort(2113)
.ExposePort(1113)
.WithName(this.EventStoreContainerName)
.WithEnvironment("EVENTSTORE_RUN_PROJECTIONS=all", "EVENTSTORE_START_STANDARD_PROJECTIONS=true")
.UseNetwork(this.TestNetwork)
.Mount(traceFolder, "/var/log/eventstore", MountType.ReadWrite)
.Build()
.Start().WaitForPort("2113/tcp", 30000);
}

public async Task StartContainersForScenarioRun(String scenarioName)
{
String traceFolder = $"/home/ubuntu/estatemanagement/trace/{scenarioName}/";

Logging.Enabled();

Guid testGuid = Guid.NewGuid();
this.TestId = testGuid;

// Setup the container names
this.EstateManagementContainerName = $"estate{testGuid:N}";
this.TransactionProcessorContainerName = $"txnprocessor{testGuid:N}";
this.EventStoreContainerName = $"eventstore{testGuid:N}";

this.EventStoreConnectionString =
$"EventStoreSettings:ConnectionString=ConnectTo=tcp://admin:changeit@{this.EventStoreContainerName}:1113;VerboseLogging=true;";

this.SetupTestNetwork();
this.SetupEventStoreContainer(traceFolder);
this.SetupEstateManagementContainer(traceFolder);
this.SetupTransactionProcessorContainer(traceFolder);

// Cache the ports
this.EstateManagementPort = this.EstateManagementContainer.ToHostExposedEndpoint("5000/tcp").Port;
this.TransactionProcessorPort = this.TransactionProcessorContainer.ToHostExposedEndpoint("5002/tcp").Port;
this.EventStorePort = this.EventStoreContainer.ToHostExposedEndpoint("2113/tcp").Port;

// Setup the base address resolver
Func<String, String> estateManagementBaseAddressResolver = api => $"http://127.0.0.1:{this.EstateManagementPort}";
Func<String, String> transactionProcessorBaseAddressResolver = api => $"http://127.0.0.1:{this.TransactionProcessorPort}";

HttpClient httpClient = new HttpClient();
this.EstateClient = new EstateClient(estateManagementBaseAddressResolver, httpClient);

// TODO: Use this to talk to txn processor until we have a client
this.HttpClient = new HttpClient();
this.HttpClient.BaseAddress = new Uri(transactionProcessorBaseAddressResolver(String.Empty));
}

public async Task StopContainersForScenarioRun()
{
try
{
if (this.TransactionProcessorContainer != null)
{
this.TransactionProcessorContainer.StopOnDispose = true;
this.TransactionProcessorContainer.RemoveOnDispose = true;
this.TransactionProcessorContainer.Dispose();
}

if (this.EstateManagementContainer != null)
{
this.EstateManagementContainer.StopOnDispose = true;
this.EstateManagementContainer.RemoveOnDispose = true;
this.EstateManagementContainer.Dispose();
}

if (this.EventStoreContainer != null)
{
this.EventStoreContainer.StopOnDispose = true;
this.EventStoreContainer.RemoveOnDispose = true;
this.EventStoreContainer.Dispose();
}

if (this.TestNetwork != null)
{
this.TestNetwork.Stop();
this.TestNetwork.Remove(true);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}

private void SetupEstateManagementContainer(String traceFolder)
{
// Management API Container
this.EstateManagementContainer = new Builder()
.UseContainer()
.WithName(this.EstateManagementContainerName)
.WithEnvironment(this.EventStoreConnectionString) //,
//"AppSettings:MigrateDatabase=true",
//"EventStoreSettings:START_PROJECTIONS=true",
//"EventStoreSettings:ContinuousProjectionsFolder=/app/projections/continuous")
.WithCredential("https://www.docker.com", "stuartferguson", "Sc0tland")
.UseImage("stuartferguson/estatemanagement")
.ExposePort(5000)
.UseNetwork(new List<INetworkService> { this.TestNetwork, Setup.DatabaseServerNetwork }.ToArray())
.Mount(traceFolder, "/home", MountType.ReadWrite)
.Build()
.Start().WaitForPort("5000/tcp", 30000);
}

private void SetupTransactionProcessorContainer(String traceFolder)
{
// Management API Container
this.TransactionProcessorContainer = new Builder()
.UseContainer()
.WithName(this.TransactionProcessorContainerName)
.WithEnvironment(this.EventStoreConnectionString) //,
//"AppSettings:MigrateDatabase=true",
//"EventStoreSettings:START_PROJECTIONS=true",
//"EventStoreSettings:ContinuousProjectionsFolder=/app/projections/continuous")
.UseImage("transactionprocessor")
.ExposePort(5002)
.UseNetwork(new List<INetworkService> { this.TestNetwork, Setup.DatabaseServerNetwork }.ToArray())
.Mount(traceFolder, "/home", MountType.ReadWrite)
.Build()
.Start().WaitForPort("5002/tcp", 30000);
}
}
}
39 changes: 39 additions & 0 deletions TransactionProcessor.IntegrationTests/Common/GenericSteps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace TransactionProcessor.IntegrationTests.Common
{
using System.Threading.Tasks;
using TechTalk.SpecFlow;

[Binding]
[Scope(Tag = "base")]
public class GenericSteps
{
private readonly ScenarioContext ScenarioContext;

private readonly TestingContext TestingContext;

public GenericSteps(ScenarioContext scenarioContext,
TestingContext testingContext)
{
this.ScenarioContext = scenarioContext;
this.TestingContext = testingContext;
}

[BeforeScenario()]
public async Task StartSystem()
{
String scenarioName = this.ScenarioContext.ScenarioInfo.Title.Replace(" ", "");
this.TestingContext.DockerHelper = new DockerHelper();
await this.TestingContext.DockerHelper.StartContainersForScenarioRun(scenarioName).ConfigureAwait(false);
}

[AfterScenario()]
public async Task StopSystem()
{
await this.TestingContext.DockerHelper.StopContainersForScenarioRun().ConfigureAwait(false);
}
}
}
Loading