diff --git a/TransactionProcessor.DataGenerator/DataGenerator/Program.cs b/TransactionProcessor.DataGenerator/DataGenerator/Program.cs index de547b6..99b069b 100644 --- a/TransactionProcessor.DataGenerator/DataGenerator/Program.cs +++ b/TransactionProcessor.DataGenerator/DataGenerator/Program.cs @@ -68,7 +68,7 @@ static async Task Main(string[] args) baseAddressFunc = (apiName) => { - String ipaddress = "192.168.1.133"; + String ipaddress = "192.168.0.133"; if (apiName == "EstateManagementApi") { return $"http://{ipaddress}:5000"; @@ -99,7 +99,7 @@ static async Task Main(string[] args) Program.TransactionProcessorClient = new TransactionProcessorClient(baseAddressFunc, httpClient); // Set an estate - Guid estateId = Guid.Parse("4fc2692f-067a-443e-8006-335bf2732248"); + Guid estateId = Guid.Parse("0f7040a6-e3c1-48ad-9d1b-39c1536fa688"); // Get a token await Program.GetToken(CancellationToken.None); @@ -108,13 +108,12 @@ static async Task Main(string[] args) List merchants = await Program.EstateClient.GetMerchants(Program.TokenResponse.AccessToken, estateId, CancellationToken.None); // Set the date range - DateTime startDate = new DateTime(2021,11,06); //27/7 - DateTime endDate = new DateTime(2021,11,23); // This is the date of te last generated transaction + DateTime startDate = new DateTime(2022,1,1); //27/7 + DateTime endDate = new DateTime(2022,1,2); // This is the date of te last generated transaction List dateRange = Program.GenerateDateRange(startDate, endDate); // Only use merchants that have a device - merchants = merchants.Where(m => m.Devices != null && m.Devices.Any() && - m.MerchantName != "Test Merchant 4").ToList(); + merchants = merchants.Where(m => m.Devices != null && m.Devices.Any()).ToList(); foreach (DateTime dateTime in dateRange) { @@ -142,7 +141,7 @@ private static async Task GenerateFileUploads(List merchants, EstateResponse estate = await Program.EstateClient.GetEstate(Program.TokenResponse.AccessToken, merchant.EstateId, cancellationToken); var estateUser = estate.SecurityUsers.FirstOrDefault(); - + foreach (MerchantOperatorResponse merchantOperator in merchant.Operators) { List fileData = null; @@ -421,8 +420,7 @@ await Program.EstateClient.MakeMerchantDeposit(Program.TokenResponse.AccessToken { Amount = depositAmount, DepositDateTime = dateTime.AddSeconds(55), - Reference = "Test Data Gen Deposit", - Source = MerchantDepositSource.Manual + Reference = "Test Data Gen Deposit" }, CancellationToken.None); Console.WriteLine($"Deposit made for Merchant [{merchant.MerchantName}]"); diff --git a/TransactionProcessor.DataGenerator/DataGenerator/TransactionDataGenerator.csproj b/TransactionProcessor.DataGenerator/DataGenerator/TransactionDataGenerator.csproj index d09679c..26d68cb 100644 --- a/TransactionProcessor.DataGenerator/DataGenerator/TransactionDataGenerator.csproj +++ b/TransactionProcessor.DataGenerator/DataGenerator/TransactionDataGenerator.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net5.0 diff --git a/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/Worker.cs b/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/Worker.cs index 6104e46..00a6a89 100644 --- a/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/Worker.cs +++ b/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/Worker.cs @@ -134,8 +134,7 @@ await this.EstateClient.MakeMerchantDeposit(this.TokenResponse.AccessToken, { Amount = depositAmount, DepositDateTime = dateTime, - Reference = "Test Data Gen Deposit", - Source = MerchantDepositSource.Manual + Reference = "Test Data Gen Deposit" }, CancellationToken.None); Logger.LogInformation($"Deposit made for Merchant [{merchant.MerchantName}]"); diff --git a/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/appsettings.json b/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/appsettings.json index 70889ec..a93f12a 100644 --- a/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/appsettings.json +++ b/TransactionProcessor.DataGenerator/TransactionGeneratorWorker/appsettings.json @@ -8,12 +8,12 @@ }, "AppSettings": { "PollingTimeoutInMinutes": 5, - "EstateList": "3bf2dab2-86d6-44e3-bcf8-51bec65cf8bc", + "EstateList": "0f7040a6-e3c1-48ad-9d1b-39c1536fa688", "ClientId": "serviceClient", "ClientSecret": "d192cbc46d834d0da90e8a9d50ded543", - "SecurityService": "http://192.168.1.133:5001", - "EstateManagementApi": "http://192.168.1.133:5000", - "TransactionProcessorApi": "http://192.168.1.133:5002" + "SecurityService": "http://192.168.0.133:5001", + "EstateManagementApi": "http://192.168.0.133:5000", + "TransactionProcessorApi": "http://192.168.0.133:5002" } } diff --git a/TransactionProcessor.SystemSetupTool/Program.cs b/TransactionProcessor.SystemSetupTool/Program.cs index f2a28d7..40de7d6 100644 --- a/TransactionProcessor.SystemSetupTool/Program.cs +++ b/TransactionProcessor.SystemSetupTool/Program.cs @@ -35,8 +35,8 @@ class Program static async Task Main(string[] args) { - Func estateResolver = s => { return "http://127.0.0.1:5000"; }; - Func securityResolver = s => { return "https://127.0.0.1:5001"; }; + Func estateResolver = s => { return "http://192.168.0.133:5000"; }; + Func securityResolver = s => { return "https://192.168.0.133:5001"; }; HttpClientHandler handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, @@ -51,17 +51,17 @@ static async Task Main(string[] args) Program.EstateClient = new EstateClient(estateResolver, client); Program.SecurityServiceClient = new SecurityServiceClient(securityResolver, client); - EventStoreClientSettings settings = EventStoreClientSettings.Create("esdb://admin:changeit@127.0.0.1:4113?tls=false"); + EventStoreClientSettings settings = EventStoreClientSettings.Create("esdb://admin:changeit@192.168.0.133:2113?tls=true&tlsVerifyCert=false"); Program.ProjectionClient = new EventStoreProjectionManagementClient(settings); Program.PersistentSubscriptionsClient = new EventStorePersistentSubscriptionsClient(settings); - await Program.SetupIdentityServerFromConfig(); + //await Program.SetupIdentityServerFromConfig(); // Setup latest projections await DeployProjections(); // Setup subcriptions - await SetupSubscriptions(); + //await SetupSubscriptions(); await Program.SetupEstatesFromConfig(); } @@ -83,6 +83,7 @@ private static async Task SetupSubscriptions() await PersistentSubscriptionsClient.CreateAsync(estate.Name.Replace(" ", ""), "Reporting", s); await PersistentSubscriptionsClient.CreateAsync($"FileProcessorSubscriptionStream_{estate.Name.Replace(" ", "")}", "FileProcessor", s); await PersistentSubscriptionsClient.CreateAsync($"TransactionProcessorSubscriptionStream_{estate.Name.Replace(" ", "")}", "Transaction Processor", s); + await Program.PersistentSubscriptionsClient.CreateAsync($"EstateManagementSubscriptionStream_{estate.Name.Replace(" ", "")}", "Estate Management", s); } } diff --git a/TransactionProcessor.SystemSetupTool/TransactionProcessor.SystemSetupTool.csproj b/TransactionProcessor.SystemSetupTool/TransactionProcessor.SystemSetupTool.csproj index 511b2ed..20bfa8b 100644 --- a/TransactionProcessor.SystemSetupTool/TransactionProcessor.SystemSetupTool.csproj +++ b/TransactionProcessor.SystemSetupTool/TransactionProcessor.SystemSetupTool.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net5.0 @@ -27,6 +27,9 @@ Always + + Always + Always diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/CallbackHandlerEnricher.js b/TransactionProcessor.SystemSetupTool/projections/continuous/CallbackHandlerEnricher.js new file mode 100644 index 0000000..cb2b1fa --- /dev/null +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/CallbackHandlerEnricher.js @@ -0,0 +1,80 @@ +fromStreams("$ce-EstateAggregate", "$et-CallbackReceivedEvent") + .when({ + $init: function (s, e) + { + return { + estates: [], + debug: [] + } + }, + "EstateCreatedEvent": function (s, e) { + s.estates.push({ + estateId: e.data.estateId, + estateName: e.data.estateName + }); + }, + "EstateReferenceAllocatedEvent": function (s, e) { + var estateIndex = s.estates.findIndex(element => element.estateId === e.data.estateId); + s.estates[estateIndex].reference = e.data.estateReference; + }, + "CallbackReceivedEvent": function (s, e) { + // find the estate from the reference + if (s.debug === undefined) { + s.debug = []; + } + var ref = e.data.reference.split("-"); // Element 0 is estate reference, Element 1 is merchant reference + var estate = s.estates.find(element => element.reference === ref[0]); + if (estate !== undefined && estate !== null) { + var enrichedEvent = createEnrichedEvent(e, estate); + + // Emit the enriched event + emit(getStreamName(estate, e), "CallbackReceivedEnrichedEvent", enrichedEvent); + } + else { + var enrichedEvent = createEnrichedEvent(e); + // Emit the enriched event + emit(getStreamName(estate, e), "CallbackReceivedEnrichedWithNoEstateEvent", enrichedEvent); + } + } + }); + +function createEnrichedEvent(originalEvent, estate) { + var enrichedEvent = {}; + if (estate !== undefined && estate !== null) { + enrichedEvent = { + typeString: originalEvent.data.typeString, + messageFormat: originalEvent.data.messageFormat, + callbackMessage: originalEvent.data.callbackMessage, + estateId: estate.estateId, + reference: originalEvent.data.reference + }; + } + else { + enrichedEvent = { + typeString: originalEvent.data.typeString, + messageFormat: originalEvent.data.messageFormat, + callbackMessage: originalEvent.data.callbackMessage, + reference: originalEvent.data.reference + }; + } + + return enrichedEvent; +} + +function getStreamName(estate, e) { + var streamName = ""; + if (e.data.destination === "EstateManagement") { + streamName += "EstateManagementSubscriptionStream_"; + } + + // Add the estate name + if (estate !== undefined && estate !== null) { + streamName += estate.estateName.replace(/ /g, ""); + } + else { + streamName += "UnknownEstate"; + } + + return streamName; + +} diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/EstateAggregator.js b/TransactionProcessor.SystemSetupTool/projections/continuous/EstateAggregator.js index 951eb25..526357c 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/EstateAggregator.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/EstateAggregator.js @@ -1,6 +1,3 @@ -var fromAll = fromAll || require("../../node_modules/esprojection-testing-framework").scope.fromAll; -var linkTo = linkTo || require("../../node_modules/esprojection-testing-framework").scope.linkTo; - isEstateEvent = (e) => { return (e.data && e.data.estateId); } isAnEstateCreatedEvent = (e) => { return compareEventTypeSafely(e.eventType, 'EstateCreatedEvent') }; @@ -45,4 +42,4 @@ fromAll() } } } - ); \ No newline at end of file + ); diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/EstateManagementSubscriptionStreamBuilder.js b/TransactionProcessor.SystemSetupTool/projections/continuous/EstateManagementSubscriptionStreamBuilder.js new file mode 100644 index 0000000..f6f1ffb --- /dev/null +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/EstateManagementSubscriptionStreamBuilder.js @@ -0,0 +1,61 @@ +isEstateEvent = (e) => { return (e.data && e.data.estateId); } +isAnEstateCreatedEvent = (e) => { return compareEventTypeSafely(e.eventType, 'EstateCreatedEvent') }; +compareEventTypeSafely = (sourceEventType, targetEventType) => { return (sourceEventType.toUpperCase() === targetEventType.toUpperCase()); } +isInvalidEvent = (e) => (e === null || e === undefined || e.data === undefined); + +getSupportedEventTypes = function () { + var eventTypes = []; + + eventTypes.push('TransactionHasBeenCompletedEvent'); + eventTypes.push('MerchantFeeSettledEvent'); + eventTypes.push('StatementGeneratedEvent'); + + return eventTypes; +} + +isARequiredEvent = (e) => { + var supportedEvents = getSupportedEventTypes(); + + var index = supportedEvents.indexOf(e.eventType); + + return index !== -1; +}; + +isTruncated = function (metadata) { + if (metadata && metadata['$v']) { + var parts = metadata['$v'].split(":"); + var projectionEpoch = parts[1]; + + return (projectionEpoch < 0); + } + return false; +}; + +getStreamName = function (estateName) { + return 'EstateManagementSubscriptionStream_' + estateName; +} + +fromAll() + .when({ + $init: function (s, e) { + return { estates: {} } + }, + $any: function (s, e) { + if (isTruncated(e)) return; + + if (isEstateEvent(e)) { + + if (isAnEstateCreatedEvent(e)) { + s.estates[e.data.estateId] = { + filteredName: e.data.estateName.replace(/-/gi, ""), + name: e.data.estateName.replace(/-/gi, "").replace(" ", "") + }; + } + + if (isARequiredEvent(e) === false) return; + + linkTo(getStreamName(s.estates[e.data.estateId].name), e); + } + } + } + ); diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/FileProcessorSubscriptionStreamBuilder.js b/TransactionProcessor.SystemSetupTool/projections/continuous/FileProcessorSubscriptionStreamBuilder.js index 9fe4d87..a25a997 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/FileProcessorSubscriptionStreamBuilder.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/FileProcessorSubscriptionStreamBuilder.js @@ -1,6 +1,3 @@ -var fromAll = fromAll || require("../../node_modules/esprojection-testing-framework").scope.fromAll; -var linkTo = linkTo || require("../../node_modules/esprojection-testing-framework").scope.linkTo; - isEstateEvent = (e) => { return (e.data && e.data.estateId); } isAnEstateCreatedEvent = (e) => { return compareEventTypeSafely(e.eventType, 'EstateCreatedEvent') }; compareEventTypeSafely = (sourceEventType, targetEventType) => { return (sourceEventType.toUpperCase() === targetEventType.toUpperCase()); } @@ -65,4 +62,4 @@ fromAll() } } } -); \ No newline at end of file +); diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantAggregator.js b/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantAggregator.js index 76f420e..f379c84 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantAggregator.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantAggregator.js @@ -1,6 +1,3 @@ -var fromAll = fromAll || require("../../node_modules/esprojection-testing-framework").scope.fromAll; -var linkTo = linkTo || require("../../node_modules/esprojection-testing-framework").scope.linkTo; - isValidEvent = function (e) { if (e) { @@ -34,4 +31,4 @@ fromAll() } } } - }); \ No newline at end of file + }); diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantBalanceCalculator.js b/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantBalanceCalculator.js index 97e638b..75bdb93 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantBalanceCalculator.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/MerchantBalanceCalculator.js @@ -1,7 +1,3 @@ -var fromCategory = fromCategory || require('../../node_modules/esprojection-testing-framework').scope.fromCategory; -var partitionBy = partitionBy !== null ? partitionBy : require('../../node_modules/esprojection-testing-framework').scope.partitionBy; -var emit = emit || require('../../node_modules/esprojection-testing-framework').scope.emit; - fromCategory('MerchantArchive') .foreachStream() .when({ @@ -130,7 +126,7 @@ var merchantCreatedEventHandler = function (s, e) { var emitBalanceChangedEvent = function (aggregateId, eventId, s, changeAmount, dateTime, reference) { if (s.initialised === true) { - + // Emit an opening balance event var openingBalanceEvent = { $type: getEventTypeName(), @@ -243,7 +239,7 @@ var merchantFeeAddedToTransactionEventHandler = function (s, e) { // increment the balance now incrementBalanceFromMerchantFee(s, e.data.calculatedValue, e.data.feeCalculatedDateTime); - + // emit an balance changed event here s = emitBalanceChangedEvent(e.data.transactionId, e.eventId, s, e.data.calculatedValue, e.data.feeCalculatedDateTime, "Transaction Fee Processed"); -} \ No newline at end of file +} diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionEnricher.js b/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionEnricher.js index 9587ff6..bfb9727 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionEnricher.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionEnricher.js @@ -1,8 +1,3 @@ -var fromCategory = fromCategory || require('../../node_modules/esprojection-testing-framework').scope.fromCategory; -//var partitionBy = partitionBy !== null ? partitionBy : require('../../node_modules/event-store-projection-testing').scope.partitionBy; -var emit = emit || require('../../node_modules/esprojection-testing-framework').scope.emit; -var linkTo = linkTo || require("../../node_modules/esprojection-testing-framework").scope.linkTo; - fromCategory('TransactionAggregate') .foreachStream() .when({ @@ -66,4 +61,4 @@ function serviceProviderFeeAddedToTransactionEventHandler(s, e) { function getStreamName(s) { return "TransactionEnricherResult"; -} \ No newline at end of file +} diff --git a/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionProcessorSubscriptionStreamBuilder.js b/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionProcessorSubscriptionStreamBuilder.js index 9e0f9e9..bb2b3b9 100644 --- a/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionProcessorSubscriptionStreamBuilder.js +++ b/TransactionProcessor.SystemSetupTool/projections/continuous/TransactionProcessorSubscriptionStreamBuilder.js @@ -1,6 +1,3 @@ -var fromAll = fromAll || require("../../node_modules/esprojection-testing-framework").scope.fromAll; -var linkTo = linkTo || require("../../node_modules/esprojection-testing-framework").scope.linkTo; - isEstateEvent = (e) => { return (e.data && e.data.estateId); } isAnEstateCreatedEvent = (e) => { return compareEventTypeSafely(e.eventType, 'EstateCreatedEvent') }; compareEventTypeSafely = (sourceEventType, targetEventType) => { return (sourceEventType.toUpperCase() === targetEventType.toUpperCase()); } @@ -59,4 +56,4 @@ fromAll() } } } -); \ No newline at end of file +); diff --git a/TransactionProcessor.SystemSetupTool/setupconfig.json b/TransactionProcessor.SystemSetupTool/setupconfig.json index 186d09d..7cfb573 100644 --- a/TransactionProcessor.SystemSetupTool/setupconfig.json +++ b/TransactionProcessor.SystemSetupTool/setupconfig.json @@ -23,7 +23,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@testmerchant1.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "user": { "email_address": "merchantuser@testmerchant1.co.uk", @@ -47,7 +47,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@testmerchant2.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "operators": [ "Safaricom", @@ -75,7 +75,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@testmerchant3.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "operators": [ "Safaricom", @@ -103,7 +103,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@emulatormerchant.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "operators": [ "Safaricom", @@ -131,7 +131,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@s7merchant.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "operators": [ "Safaricom", @@ -159,7 +159,7 @@ }, "contact": { "contact_name": "Test Contact", - "email_address": "testcontact@xperiamerchant.co.uk" + "email_address": "stuart_ferguson1@outlook.com" }, "operators": [ "Safaricom",