From d2c4c38d4fc44ca40f3ca9070321cd42e22e5f28 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Mon, 16 Mar 2020 12:15:45 +0000 Subject: [PATCH] Operator Message Processing added --- .../OperatorInterfaces/IOperatorProxy.cs | 33 ++++ .../OperatorInterfaces/ISafaricomProxy.cs | 47 ------ .../OperatorInterfaces/OperatorResponse.cs | 38 +++++ .../SafaricomConfiguration.cs | 62 ++++++++ .../SafaricomPinless/SafaricomPinlessProxy.cs | 145 ++++++++++++++++++ .../SafaricomPinless/SafaricomResponse.cs | 74 +++++++++ .../Services/TransactionDomainService.cs | 88 ++++++++--- .../TransactionProcessor.BusinessLogic.csproj | 6 +- .../TransactionProcessor.Client.csproj | 2 +- .../Common/DockerHelper.cs | 49 +++++- ...ansactionProcessor.IntegrationTests.csproj | 6 +- ...nProcessor.Transaction.DomainEvents.csproj | 2 +- ...ctionProcessor.TransactionAggregate.csproj | 2 +- TransactionProcessor/Startup.cs | 28 +++- .../TransactionProcessor.csproj | 2 +- TransactionProcessor/appsettings.json | 13 +- 16 files changed, 512 insertions(+), 85 deletions(-) create mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/IOperatorProxy.cs delete mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/ISafaricomProxy.cs create mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs create mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs create mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs create mode 100644 TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/IOperatorProxy.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/IOperatorProxy.cs new file mode 100644 index 00000000..1c4d2476 --- /dev/null +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/IOperatorProxy.cs @@ -0,0 +1,33 @@ +namespace TransactionProcessor.BusinessLogic.OperatorInterfaces +{ + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using EstateManagement.DataTransferObjects.Responses; + + /// + /// + /// + public interface IOperatorProxy + { + #region Methods + + /// + /// Processes the sale message. + /// + /// The transaction identifier. + /// The merchant. + /// The transaction date time. + /// The additional transaction metadata. + /// The cancellation token. + /// + Task ProcessSaleMessage(Guid transactionId, + MerchantResponse merchant, + DateTime transactionDateTime, + Dictionary additionalTransactionMetadata, + CancellationToken cancellationToken); + + #endregion + } +} \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/ISafaricomProxy.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/ISafaricomProxy.cs deleted file mode 100644 index 6f3eb4a5..00000000 --- a/TransactionProcessor.BusinessLogic/OperatorInterfaces/ISafaricomProxy.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace TransactionProcessor.BusinessLogic.OperatorInterfaces -{ - using System.Diagnostics.CodeAnalysis; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - public interface IOperatorProxy - { - Task ProcessMessage(CancellationToken cancellationToken); - } - - [ExcludeFromCodeCoverage] - public class SafaricomPinlessProxy : IOperatorProxy - { - public async Task ProcessMessage(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - } - - /*http://{{linuxservername}}:8000/api/safaricom? - VENDOR=D-S136 - Fixed - &REQTYPE=EXRCTRFREQ - Fixed - &DATA= - - - EXRCTRFREQ - Fixed - 02-JUL-2018 - From Sales Transaction - SA - Fixed - 700945625 - Config - 0322 - Config - D-S136 - Config - @SafePay33 - Config - D-S136 - Config ? - 100022814 - From Sales Transaction - 0723581504 - From Sales Transaction - 65000 - From Sales Transaction - 0 - Fixed - 0 - Fixed - 1 - Fixed - */ -} diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs new file mode 100644 index 00000000..65ee845e --- /dev/null +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs @@ -0,0 +1,38 @@ +namespace TransactionProcessor.BusinessLogic.OperatorInterfaces +{ + using System; + + /// + /// + /// + public class OperatorResponse + { + #region Properties + + /// + /// Gets or sets the authorisation code. + /// + /// + /// The authorisation code. + /// + public String AuthorisationCode { get; set; } + + /// + /// Gets or sets the response code. + /// + /// + /// The response code. + /// + public String 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.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs new file mode 100644 index 00000000..f0ef90cc --- /dev/null +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs @@ -0,0 +1,62 @@ +namespace TransactionProcessor.BusinessLogic.OperatorInterfaces.SafaricomPinless +{ + using System; + + /// + /// + /// + public class SafaricomConfiguration + { + #region Properties + + /// + /// Gets or sets the ext code. + /// + /// + /// The ext code. + /// + public String ExtCode { get; set; } + + /// + /// Gets or sets the login identifier. + /// + /// + /// The login identifier. + /// + public String LoginId { get; set; } + + /// + /// Gets or sets the msisdn. + /// + /// + /// The msisdn. + /// + public String MSISDN { get; set; } + + /// + /// Gets or sets the password. + /// + /// + /// The password. + /// + public String Password { get; set; } + + /// + /// Gets or sets the pin. + /// + /// + /// The pin. + /// + public String Pin { get; set; } + + /// + /// Gets or sets the URL. + /// + /// + /// The URL. + /// + public String Url { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs new file mode 100644 index 00000000..1631a24c --- /dev/null +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs @@ -0,0 +1,145 @@ +namespace TransactionProcessor.BusinessLogic.OperatorInterfaces.SafaricomPinless +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Net.Http; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + using System.Xml; + using System.Xml.Serialization; + using EstateManagement.DataTransferObjects.Responses; + + /// + /// + /// + /// + public class SafaricomPinlessProxy : IOperatorProxy + { + #region Fields + + private readonly HttpClient HttpClient; + + /// + /// The safaricom configuration + /// + private readonly SafaricomConfiguration SafaricomConfiguration; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The safaricom configuration. + /// The HTTP client. + public SafaricomPinlessProxy(SafaricomConfiguration safaricomConfiguration, + HttpClient httpClient) + { + this.SafaricomConfiguration = safaricomConfiguration; + this.HttpClient = httpClient; + } + + #endregion + + #region Methods + + /// + /// Processes the sale message. + /// + /// The transaction identifier. + /// The merchant. + /// The transaction date time. + /// The additional transaction metadata. + /// The cancellation token. + /// + public async Task ProcessSaleMessage(Guid transactionId, + MerchantResponse merchant, + DateTime transactionDateTime, + Dictionary additionalTransactionMetadata, + CancellationToken cancellationToken) + { + String requestUrl = this.BuildRequest(transactionDateTime, "123456789", "123456789", "1000"); + + // Concatenate the request message + HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(requestUrl)); + + // Send the request to Safaricom + HttpResponseMessage responseMessage = await this.HttpClient.SendAsync(requestMessage, cancellationToken); + + // Check the send was successful + if (responseMessage.IsSuccessStatusCode == false) + { + throw new Exception($"Error sending request [{requestUrl}] to Safaricom. Status Code [{responseMessage.StatusCode}]"); + } + + // Get the response + String responseContent = await responseMessage.Content.ReadAsStringAsync(); + + return this.CreateFrom(responseContent); + } + + /// + /// Builds the request. + /// + /// The transaction date time. + /// The external reference. + /// The customer msisdn. + /// The transaction amount. + /// + private String BuildRequest(DateTime transactionDateTime, + String externalReference, + String customerMsisdn, + String transactionAmount) + { + String requestUrl = $"{this.SafaricomConfiguration.Url}?VENDOR={this.SafaricomConfiguration.LoginId}&REQTYPE=EXRCTRFREQ&DATA="; + + StringBuilder xmlData = new StringBuilder(); + + // Now build up the XML part of the message + xmlData.Append(""); + xmlData.Append(""); + xmlData.Append("EXRCTRFREQ"); + xmlData.Append($"{transactionDateTime:dd-MMM-yyyy}"); + xmlData.Append("SA"); + xmlData.Append($"{this.SafaricomConfiguration.MSISDN}"); + xmlData.Append($"{this.SafaricomConfiguration.Pin}"); + xmlData.Append($"{this.SafaricomConfiguration.LoginId}"); + xmlData.Append($"{this.SafaricomConfiguration.Password}"); + xmlData.Append($"{this.SafaricomConfiguration.ExtCode}"); + xmlData.Append($"{externalReference}"); + xmlData.Append($"{customerMsisdn}"); + xmlData.Append($"{transactionAmount}"); + xmlData.Append("0"); + xmlData.Append("0"); + xmlData.Append("0"); + xmlData.Append(""); + + return $"{requestUrl}{xmlData}"; + } + + /// + /// Creates from. + /// + /// Content of the response. + /// + private OperatorResponse CreateFrom(String responseContent) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(responseContent); + XmlSerializer xs = new XmlSerializer(typeof(SafaricomResponse)); + SafaricomResponse cl = (SafaricomResponse)xs.Deserialize(new StringReader(doc.OuterXml)); + + return new OperatorResponse + { + AuthorisationCode = "ABCD1234", + ResponseCode = cl.TXNSTATUS.ToString(), + ResponseMessage = cl.MESSAGE + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs new file mode 100644 index 00000000..1bbd514e --- /dev/null +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs @@ -0,0 +1,74 @@ +namespace TransactionProcessor.BusinessLogic.OperatorInterfaces.SafaricomPinless +{ + using System; + using System.ComponentModel; + using System.Xml.Serialization; + + /// + /// + /// + [Serializable] + [DesignerCategory("code")] + [XmlType(AnonymousType = true)] + [XmlRoot(Namespace = "", IsNullable = false, ElementName = "COMMAND")] + public class SafaricomResponse + { + #region Properties + + /// + /// Gets or sets the type. + /// + /// + /// The type. + /// + [XmlElement(ElementName = "TYPE")] + public String TYPE { get; set; } + + /// + /// Gets or sets the txnstatus. + /// + /// + /// The txnstatus. + /// + [XmlElement(ElementName = "TXNSTATUS")] + public Int32 TXNSTATUS { get; set; } + + /// + /// Gets or sets the date. + /// + /// + /// The date. + /// + [XmlElement(ElementName = "DATE")] + public String DATE { get; set; } + + /// + /// Gets or sets the extrefnum. + /// + /// + /// The extrefnum. + /// + [XmlElement(ElementName = "EXTREFNUM")] + public String EXTREFNUM { get; set; } + + /// + /// Gets or sets the txnid. + /// + /// + /// The txnid. + /// + [XmlElement(ElementName = "TXNID")] + public String TXNID { get; set; } + + /// + /// Gets or sets the message. + /// + /// + /// The message. + /// + [XmlElement(ElementName = "MESSAGE")] + public String MESSAGE { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs index c5c03e0a..da281e91 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs @@ -166,6 +166,10 @@ public async Task ProcessSaleTransaction(Guid tr if (validationResult.responseCode == TransactionResponseCode.Success) { // TODO: Do the online processing with the operator here + MerchantResponse merchant = await this.GetMerchant(estateId, merchantId, cancellationToken); + IOperatorProxy operatorProxy = OperatorProxyResolver(operatorId); + await operatorProxy.ProcessSaleMessage(transactionId, merchant, transactionDateTime, additionalTransactionMetadata, cancellationToken); + // Record the successful validation transactionAggregate = await transactionAggregateRepository.GetLatestVersion(transactionId, cancellationToken); // TODO: Generate local authcode @@ -212,31 +216,20 @@ public async Task ProcessSaleTransaction(Guid tr { try { - - // Get a token to talk to the estate service - String clientId = ConfigurationReader.GetValue("AppSettings", "ClientId"); - String clientSecret = ConfigurationReader.GetValue("AppSettings", "ClientSecret"); - - Logger.LogInformation($"Client Id is {clientId}"); - Logger.LogInformation($"Client Secret is {clientSecret}"); - - TokenResponse token = await this.SecurityServiceClient.GetToken(clientId, clientSecret, cancellationToken); - Logger.LogInformation($"Token is {token.AccessToken}"); - EstateResponse estate = null; // Validate the Estate Record is a valid estate try { - estate = await this.EstateClient.GetEstate(token.AccessToken, estateId, cancellationToken); + estate = await this.GetEstate(estateId, cancellationToken); } catch (Exception ex) when (ex.InnerException != null && ex.InnerException.GetType() == typeof(KeyNotFoundException)) { throw new TransactionValidationException($"Estate Id [{estateId}] is not a valid estate", TransactionResponseCode.InvalidEstateId); } - + // get the merchant record and validate the device // TODO: Token - MerchantResponse merchant = await this.EstateClient.GetMerchant(token.AccessToken, estateId, merchantId, cancellationToken); + MerchantResponse merchant = await this.GetMerchant(estateId, merchantId, cancellationToken); // TODO: Remove this once GetMerchant returns correct response when merchant not found if (merchant.MerchantName == null) @@ -249,15 +242,7 @@ public async Task ProcessSaleTransaction(Guid tr { if (transactionType == TransactionType.Logon) { - // Add the device to the merchant - await this.EstateClient.AddDeviceToMerchant(token.AccessToken, - estateId, - merchantId, - new AddMerchantDeviceRequest - { - DeviceIdentifier = deviceIdentifier - }, - cancellationToken); + await this.AddDeviceToMerchant(estateId, merchantId, deviceIdentifier, cancellationToken); } else { @@ -293,6 +278,63 @@ await this.EstateClient.AddDeviceToMerchant(token.AccessToken, } + private TokenResponse TokenResponse; + + private async Task GetEstate(Guid estateId, CancellationToken cancellationToken) + { + await this.GetToken(cancellationToken); + + EstateResponse estate = await this.EstateClient.GetEstate(this.TokenResponse.AccessToken, estateId, cancellationToken); + + return estate; + } + + private async Task GetMerchant(Guid estateId, + Guid merchantId, + CancellationToken cancellationToken) + { + await this.GetToken(cancellationToken); + + MerchantResponse merchant = await this.EstateClient.GetMerchant(this.TokenResponse.AccessToken, estateId, merchantId, cancellationToken); + + return merchant; + } + + private async Task GetToken(CancellationToken cancellationToken) + { + if (this.TokenResponse == null) + { + // Get a token to talk to the estate service + String clientId = ConfigurationReader.GetValue("AppSettings", "ClientId"); + String clientSecret = ConfigurationReader.GetValue("AppSettings", "ClientSecret"); + + Logger.LogInformation($"Client Id is {clientId}"); + Logger.LogInformation($"Client Secret is {clientSecret}"); + + TokenResponse token = await this.SecurityServiceClient.GetToken(clientId, clientSecret, cancellationToken); + Logger.LogInformation($"Token is {token.AccessToken}"); + this.TokenResponse = token; + } + } + + private async Task AddDeviceToMerchant(Guid estateId, + Guid merchantId, + String deviceIdentifier, + CancellationToken cancellationToken) + { + await this.GetToken(cancellationToken); + + // Add the device to the merchant + await this.EstateClient.AddDeviceToMerchant(this.TokenResponse.AccessToken, + estateId, + merchantId, + new AddMerchantDeviceRequest + { + DeviceIdentifier = deviceIdentifier + }, + cancellationToken); + } + #endregion } } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj index f7e06e29..8f63465e 100644 --- a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj +++ b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/TransactionProcessor.Client/TransactionProcessor.Client.csproj b/TransactionProcessor.Client/TransactionProcessor.Client.csproj index cff00d63..63b91939 100644 --- a/TransactionProcessor.Client/TransactionProcessor.Client.csproj +++ b/TransactionProcessor.Client/TransactionProcessor.Client.csproj @@ -6,7 +6,7 @@ - + diff --git a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs index e5c09d1b..ad04589f 100644 --- a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs +++ b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs @@ -8,7 +8,9 @@ using System.Threading; using System.Threading.Tasks; using Client; + using Ductus.FluentDocker.Builders; using Ductus.FluentDocker.Common; + using Ductus.FluentDocker.Model.Builders; using Ductus.FluentDocker.Services; using Ductus.FluentDocker.Services.Extensions; using EstateManagement.Client; @@ -82,6 +84,8 @@ public class DockerHelper : global::Shared.IntegrationTesting.DockerHelper protected String TransactionProcessorContainerName; + protected String TestHostContainerName; + /// /// The transaction processor port /// @@ -113,6 +117,33 @@ public DockerHelper(NlogLogger logger, TestingContext testingContext) #endregion + public const Int32 TestHostPort = 9000; + + public static IContainerService SetupTestHostContainer(String containerName, ILogger logger, String imageName, + List networkServices, + String hostFolder, + (String URL, String UserName, String Password)? dockerCredentials, + Boolean forceLatestImage = false) + { + logger.LogInformation("About to Start Test Hosts Container"); + + ContainerBuilder testHostContainer = new Builder().UseContainer().WithName(containerName) + .UseImage(imageName, forceLatestImage).ExposePort(DockerHelper.TestHostPort) + .UseNetwork(networkServices.ToArray()).Mount(hostFolder, "/home", MountType.ReadWrite); + + if (dockerCredentials.HasValue) + { + testHostContainer.WithCredential(dockerCredentials.Value.URL, dockerCredentials.Value.UserName, dockerCredentials.Value.Password); + } + + // Now build and return the container + IContainerService builtContainer = testHostContainer.Build().Start().WaitForPort($"{DockerHelper.TestHostPort}/tcp", 30000); + + logger.LogInformation("Test Hosts Container Started"); + + return builtContainer; + } + #region Methods /// @@ -137,6 +168,7 @@ public override async Task StartContainersForScenarioRun(String scenarioName) this.EstateReportingContainerName = $"estatereporting{testGuid:N}"; this.SubscriptionServiceContainerName = $"subscription{testGuid:N}"; this.TransactionProcessorContainerName = $"txnprocessor{testGuid:N}"; + this.TestHostContainerName = $"testhosts{testGuid:N}"; (String, String, String) dockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland"); @@ -178,7 +210,8 @@ public override async Task StartContainersForScenarioRun(String scenarioName) this.SecurityServiceContainerName, this.EstateManagementContainerName, this.EventStoreContainerName, - ("serviceClient", "Secret1")); + ("serviceClient", "Secret1"), + this.TestHostContainerName); IContainerService estateReportingContainer = DockerHelper.SetupEstateReportingContainer(this.EstateReportingContainerName, this.Logger, @@ -197,13 +230,25 @@ public override async Task StartContainersForScenarioRun(String scenarioName) ("serviceClient", "Secret1"), true); + IContainerService testhostContainer = SetupTestHostContainer(this.TestHostContainerName, + this.Logger, + "stuartferguson/testhosts", + new List + { + testNetwork + }, + traceFolder, + dockerCredentials, + true); + this.Containers.AddRange(new List { eventStoreContainer, estateManagementContainer, securityServiceContainer, transactionProcessorContainer, - estateReportingContainer + estateReportingContainer, + testhostContainer }); // Cache the ports diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index 318130e5..ebcc0f2f 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -7,15 +7,15 @@ - + - - + + diff --git a/TransactionProcessor.Transaction.DomainEvents/TransactionProcessor.Transaction.DomainEvents.csproj b/TransactionProcessor.Transaction.DomainEvents/TransactionProcessor.Transaction.DomainEvents.csproj index a135d524..40985bc9 100644 --- a/TransactionProcessor.Transaction.DomainEvents/TransactionProcessor.Transaction.DomainEvents.csproj +++ b/TransactionProcessor.Transaction.DomainEvents/TransactionProcessor.Transaction.DomainEvents.csproj @@ -5,7 +5,7 @@ - + diff --git a/TransactionProcessor.TransactionAgrgegate/TransactionProcessor.TransactionAggregate.csproj b/TransactionProcessor.TransactionAgrgegate/TransactionProcessor.TransactionAggregate.csproj index 9b5cb053..25aeb51f 100644 --- a/TransactionProcessor.TransactionAgrgegate/TransactionProcessor.TransactionAggregate.csproj +++ b/TransactionProcessor.TransactionAgrgegate/TransactionProcessor.TransactionAggregate.csproj @@ -5,7 +5,7 @@ - + diff --git a/TransactionProcessor/Startup.cs b/TransactionProcessor/Startup.cs index f15a17a8..01cc2734 100644 --- a/TransactionProcessor/Startup.cs +++ b/TransactionProcessor/Startup.cs @@ -18,6 +18,7 @@ namespace TransactionProcessor using System.Reflection; using Autofac; using BusinessLogic.OperatorInterfaces; + using BusinessLogic.OperatorInterfaces.SafaricomPinless; using BusinessLogic.RequestHandlers; using BusinessLogic.Requests; using BusinessLogic.Services; @@ -101,6 +102,20 @@ public void ConfigureContainer(ContainerBuilder builder) builder.RegisterInstance>(eventStoreContextFunc); + SafaricomConfiguration safaricomConfiguration = new SafaricomConfiguration(); + + if (Startup.Configuration != null) + { + IConfigurationSection section = Startup.Configuration.GetSection("AppSettings:EventHandlerConfiguration"); + + if (section != null) + { + Startup.Configuration.GetSection("OperatorConfiguration:Safaricom").Bind(safaricomConfiguration); + } + } + + builder.RegisterInstance(safaricomConfiguration); + if (useConnectionStringConfig) { String connectionStringConfigurationConnString = ConfigurationReader.GetConnectionString("ConnectionStringConfiguration"); @@ -128,12 +143,21 @@ public void ConfigureContainer(ContainerBuilder builder) Uri uri = ConfigurationReader.GetBaseServerUri(api); return uri.AbsoluteUri.Substring(0, uri.AbsoluteUri.Length - 1); }); - builder.Register>(c => (operatorIdentifier) => { return new SafaricomPinlessProxy();}); + builder.Register>(c => + { + IComponentContext cx = c.Resolve(); + return operatorrIdentifier => + { + SafaricomConfiguration configuration = cx.Resolve(); + HttpClient client = cx.Resolve(); + return new SafaricomPinlessProxy(configuration, client); + }; + }); // request & notification handlers builder.Register(context => { - var c = context.Resolve(); + IComponentContext c = context.Resolve(); return t => c.Resolve(t); }); diff --git a/TransactionProcessor/TransactionProcessor.csproj b/TransactionProcessor/TransactionProcessor.csproj index f92cedb5..1ded4dba 100644 --- a/TransactionProcessor/TransactionProcessor.csproj +++ b/TransactionProcessor/TransactionProcessor.csproj @@ -20,7 +20,7 @@ - + diff --git a/TransactionProcessor/appsettings.json b/TransactionProcessor/appsettings.json index 8543a25c..46271667 100644 --- a/TransactionProcessor/appsettings.json +++ b/TransactionProcessor/appsettings.json @@ -29,5 +29,16 @@ "ApiName": "transactionProcessor", "Authority": "http://192.168.1.133:5001" }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "OperatorConfiguration": { + "Safaricom": { + "Url": "http://192.168.1.133:9000/api/safaricom", + "LoginId": "D-S136", + "MSISDN": "700945625", + "Pin": "0322", + "Password": "@SafePay33", + "ExtCode": "SA" + + } + } } \ No newline at end of file