Skip to content

Commit 7d7579e

Browse files
Merge pull request #10 from TransactionProcessing/task/#9_concurrentmerchants
Added concurrent merchant processing
2 parents d6074a0 + 5b9633f commit 7d7579e

File tree

4 files changed

+109
-45
lines changed

4 files changed

+109
-45
lines changed

TransactionProcessor.DataGenerator/TransactionDataGenerator/Program.cs renamed to TransactionProcessor.DataGenerator/DataGenerator/Program.cs

Lines changed: 104 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
namespace TransactionDataGenerator
44
{
55
using System.Collections.Generic;
6+
using System.Diagnostics;
67
using System.Linq;
78
using System.Net.Http;
89
using System.Runtime.CompilerServices;
910
using System.Threading;
1011
using System.Threading.Tasks;
12+
using System.Threading.Tasks.Dataflow;
1113
using EstateManagement.Client;
1214
using EstateManagement.DataTransferObjects.Requests;
1315
using EstateManagement.DataTransferObjects.Responses;
@@ -17,6 +19,17 @@ namespace TransactionDataGenerator
1719
using TransactionProcessor.Client;
1820
using TransactionProcessor.DataTransferObjects;
1921

22+
public class Gimp
23+
{
24+
public class V1
25+
{
26+
public class GimpAddedEvent
27+
{
28+
29+
}
30+
}
31+
}
32+
2033
/// <summary>
2134
///
2235
/// </summary>
@@ -81,27 +94,28 @@ static async Task Main(string[] args)
8194
Program.TransactionProcessorClient = new TransactionProcessorClient(baseAddressFunc, httpClient);
8295

8396
// Set an estate
84-
Guid estateId = Guid.Parse("3bf2dab2-86d6-44e3-bcf8-51bec65cf8bc");
97+
Guid estateId = Guid.Parse("5b07ec2d-3856-4d05-ab31-e2dedb95ea27");
8598

8699
// Get a token
87100
await Program.GetToken(CancellationToken.None);
88101

89102
// Get the the merchant list for the estate
90103
List<MerchantResponse> merchants = await Program.EstateClient.GetMerchants(Program.TokenResponse.AccessToken, estateId, CancellationToken.None);
91-
92-
//merchants = merchants.Where(m => m.MerchantName == "S7 Merchant").ToList();
93-
104+
94105
// Set the date range
95-
DateTime startDate = new DateTime(2020,12,01);
96-
DateTime endDate = new DateTime(2020, 12, 11);
106+
DateTime startDate = new DateTime(2021,4,1);
107+
DateTime endDate = new DateTime(2021, 4, 19); // This is the date of te last generated transaction
97108
List<DateTime> dateRange = Program.GenerateDateRange(startDate, endDate);
98109

99110
// Only use merchants that have a device
100111
merchants = merchants.Where(m => m.Devices != null && m.Devices.Any()).ToList();
101-
102-
await Program.GenerateTransactions(merchants, dateRange);
103112

104-
Console.WriteLine($"Process Complete - {Program.TransactionCount} transactions generated");
113+
foreach (DateTime dateTime in dateRange)
114+
{
115+
await Program.GenerateTransactions(merchants, dateTime, CancellationToken.None);
116+
}
117+
118+
Console.WriteLine($"Process Complete");
105119
}
106120

107121
/// <summary>
@@ -133,36 +147,86 @@ private static async Task GetToken(CancellationToken cancellationToken)
133147
/// <param name="merchants">The merchants.</param>
134148
/// <param name="dateRange">The date range.</param>
135149
private static async Task GenerateTransactions(List<MerchantResponse> merchants,
136-
List<DateTime> dateRange)
150+
DateTime dateTime,
151+
CancellationToken cancellationToken)
137152
{
138-
foreach (DateTime dateTime in dateRange)
153+
Int32 maxDegreeOfParallelism = 5;
154+
Int32 boundedCapacityForActionBlock = merchants.Count;
155+
156+
ActionBlock<(MerchantResponse merchant, CancellationToken cancellationToken)> workerBlock =
157+
new ActionBlock<(MerchantResponse merchant, CancellationToken cancellationToken)>(async (message) =>
158+
{
159+
try
160+
{
161+
Int32 transactionCount = 0;
162+
163+
// Do a logon transaction for each merchant
164+
await Program.DoLogonTransaction(message.merchant, dateTime);
165+
Console
166+
.WriteLine($"Logon sent for Merchant [{message.merchant.MerchantName}]");
167+
168+
// Now generate some sales
169+
List<SaleTransactionRequest> saleRequests =
170+
await Program.CreateSaleRequests(message.merchant,
171+
dateTime);
172+
173+
// Work out how much of a deposit the merchant needs (minus 1 sale)
174+
IEnumerable<Dictionary<String, String>> metadata =
175+
saleRequests.Select(s => s.AdditionalTransactionMetadata);
176+
List<String> amounts = metadata.Select(m => m["Amount"])
177+
.ToList();
178+
179+
Decimal depositAmount = amounts.TakeLast(amounts.Count - 1)
180+
.Sum(a => Decimal.Parse(a));
181+
182+
await Program.MakeMerchantDeposit(message.merchant,
183+
depositAmount,
184+
dateTime);
185+
186+
// Now send the sales
187+
saleRequests = saleRequests.OrderBy(s => s.TransactionDateTime)
188+
.ToList();
189+
foreach (SaleTransactionRequest saleTransactionRequest in
190+
saleRequests)
191+
{
192+
await Program.DoSaleTransaction(saleTransactionRequest);
193+
Console
194+
.WriteLine($"Sale sent for Merchant [{message.merchant.MerchantName}]");
195+
transactionCount++;
196+
}
197+
198+
Console.ForegroundColor = ConsoleColor.Green;
199+
Console
200+
.WriteLine($"{transactionCount} transactions generated for {message.merchant.MerchantName} on date {dateTime.ToLongDateString()}");
201+
}
202+
catch(Exception ex)
203+
{
204+
Console.ForegroundColor = ConsoleColor.Red;
205+
Console.WriteLine("Failed");
206+
Console.WriteLine(ex);
207+
}
208+
},
209+
new ExecutionDataflowBlockOptions
210+
{
211+
MaxDegreeOfParallelism = maxDegreeOfParallelism,
212+
BoundedCapacity = boundedCapacityForActionBlock
213+
});
214+
215+
216+
try
139217
{
140-
foreach (MerchantResponse merchant in merchants)
218+
foreach (var merchant in merchants)
141219
{
142-
// Do a logon transaction for each merchant
143-
await Program.DoLogonTransaction(merchant, dateTime);
144-
Console.WriteLine($"Logon sent for Merchant [{merchant.MerchantName}]");
145-
146-
// Now generate some sales
147-
List<SaleTransactionRequest> saleRequests = await Program.CreateSaleRequests(merchant, dateTime);
148-
149-
// Work out how much of a deposit the merchant needs (minus 1 sale)
150-
IEnumerable<Dictionary<String, String>> metadata = saleRequests.Select(s => s.AdditionalTransactionMetadata);
151-
List<String> amounts = metadata.Select(m => m["Amount"]).ToList();
152-
153-
Decimal depositAmount = amounts.TakeLast(amounts.Count - 1).Sum(a => Decimal.Parse(a));
154-
155-
await Program.MakeMerchantDeposit(merchant, depositAmount, dateTime);
156-
157-
// Now send the sales
158-
saleRequests = saleRequests.OrderBy(s => s.TransactionDateTime).ToList();
159-
foreach (SaleTransactionRequest saleTransactionRequest in saleRequests)
160-
{
161-
await Program.DoSaleTransaction(saleTransactionRequest);
162-
Console.WriteLine($"Sale sent for Merchant [{merchant.MerchantName}]");
163-
TransactionCount++;
164-
}
220+
await workerBlock.SendAsync((merchant, cancellationToken), cancellationToken);
165221
}
222+
223+
workerBlock.Complete();
224+
225+
await workerBlock.Completion;
226+
}
227+
catch (Exception e)
228+
{
229+
Console.WriteLine(e);
166230
}
167231
}
168232

@@ -184,7 +248,7 @@ await Program.EstateClient.MakeMerchantDeposit(Program.TokenResponse.AccessToken
184248
new MakeMerchantDepositRequest
185249
{
186250
Amount = depositAmount,
187-
DepositDateTime = dateTime,
251+
DepositDateTime = dateTime.AddSeconds(55),
188252
Reference = "Test Data Gen Deposit",
189253
Source = MerchantDepositSource.Manual
190254
},
@@ -203,8 +267,8 @@ private static async Task DoSaleTransaction(SaleTransactionRequest saleTransacti
203267
await Program.GetToken(CancellationToken.None);
204268

205269
SerialisedMessage requestSerialisedMessage = new SerialisedMessage();
206-
requestSerialisedMessage.Metadata.Add("EstateId", saleTransactionRequest.EstateId.ToString());
207-
requestSerialisedMessage.Metadata.Add("MerchantId", saleTransactionRequest.MerchantId.ToString());
270+
requestSerialisedMessage.Metadata.Add("estate_id", saleTransactionRequest.EstateId.ToString());
271+
requestSerialisedMessage.Metadata.Add("merchant_id", saleTransactionRequest.MerchantId.ToString());
208272
requestSerialisedMessage.SerialisedData = JsonConvert.SerializeObject(saleTransactionRequest,
209273
new JsonSerializerSettings
210274
{
@@ -327,8 +391,8 @@ private static async Task DoLogonTransaction(MerchantResponse merchant,
327391
};
328392

329393
SerialisedMessage requestSerialisedMessage = new SerialisedMessage();
330-
requestSerialisedMessage.Metadata.Add("EstateId", merchant.EstateId.ToString());
331-
requestSerialisedMessage.Metadata.Add("MerchantId", merchant.MerchantId.ToString());
394+
requestSerialisedMessage.Metadata.Add("estate_id", merchant.EstateId.ToString());
395+
requestSerialisedMessage.Metadata.Add("merchant_id", merchant.MerchantId.ToString());
332396
requestSerialisedMessage.SerialisedData = JsonConvert.SerializeObject(logonTransactionRequest,
333397
new JsonSerializerSettings
334398
{
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>netcoreapp3.1</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="EstateManagement.Client" Version="1.0.6" />
9+
<PackageReference Include="EstateManagement.Client" Version="1.0.10" />
1010
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
11-
<PackageReference Include="SecurityService.Client" Version="1.0.4" />
12-
<PackageReference Include="TransactionProcessor.Client" Version="1.0.7.2" />
11+
<PackageReference Include="SecurityService.Client" Version="1.0.6" />
12+
<PackageReference Include="TransactionProcessor.Client" Version="1.0.12" />
1313
</ItemGroup>
1414

1515
</Project>

TransactionProcessor.DataGenerator/TransactionProcessor.DataGenerator.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.30523.141
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionGeneratorWorker", "TransactionGeneratorWorker\TransactionGeneratorWorker.csproj", "{DF5050CF-91D8-4248-BEF6-25FAF1A05677}"
77
EndProject
8-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionDataGenerator", "TransactionDataGenerator\TransactionDataGenerator.csproj", "{BC85594F-6F0B-425D-868F-560B9A3AC104}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionDataGenerator", "DataGenerator\TransactionDataGenerator.csproj", "{BC85594F-6F0B-425D-868F-560B9A3AC104}"
99
EndProject
1010
Global
1111
GlobalSection(SolutionConfigurationPlatforms) = preSolution

0 commit comments

Comments
 (0)