From 2d263898971a2956142efd6c7045f57238d02e8b Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 13 Nov 2025 14:03:24 +0000 Subject: [PATCH 01/29] shared nugets updated --- .../TransactionProcessor.Aggregates.csproj | 2 +- .../TransactionProcessor.BusinessLogic.csproj | 12 +- .../ITransactionProcessorClient.cs | 2 +- .../TransactionProcessor.Client.csproj | 4 +- .../TransactionProcessorClient.cs | 390 ++++++------------ .../TransactionProcessor.Database.csproj | 4 +- .../TransactionProcessor.DatabaseTests.csproj | 2 +- .../TransactionProcessor.DomainEvents.csproj | 2 +- ...rocessor.IntegrationTesting.Helpers.csproj | 4 +- ...ansactionProcessor.IntegrationTests.csproj | 10 +- ...ansactionProcessor.ProjectionEngine.csproj | 4 +- .../TransactionProcessor.Repository.csproj | 4 +- .../TransactionProcessor.Testing.csproj | 4 +- .../TransactionProcessor.Tests.csproj | 4 +- .../TransactionProcessor.csproj | 10 +- workload-install.ps1 | 332 +++++++++++++++ 16 files changed, 490 insertions(+), 300 deletions(-) create mode 100644 workload-install.ps1 diff --git a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj index c0ca0dec..3c8a621f 100644 --- a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj +++ b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj @@ -8,7 +8,7 @@ - + diff --git a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj index 6b95d77c..c41fc4f9 100644 --- a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj +++ b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj @@ -5,16 +5,16 @@ - - + + - + - - - + + + diff --git a/TransactionProcessor.Client/ITransactionProcessorClient.cs b/TransactionProcessor.Client/ITransactionProcessorClient.cs index 45b4a80e..9194644c 100644 --- a/TransactionProcessor.Client/ITransactionProcessorClient.cs +++ b/TransactionProcessor.Client/ITransactionProcessorClient.cs @@ -64,7 +64,7 @@ Task> GetVoucherByTransactionId(String accessToken, Guid transactionId, CancellationToken cancellationToken); - Task> RedeemVoucher(String accessToken, + Task RedeemVoucher(String accessToken, RedeemVoucherRequest redeemVoucherRequest, CancellationToken cancellationToken); diff --git a/TransactionProcessor.Client/TransactionProcessor.Client.csproj b/TransactionProcessor.Client/TransactionProcessor.Client.csproj index c30ae1f4..e2a39716 100644 --- a/TransactionProcessor.Client/TransactionProcessor.Client.csproj +++ b/TransactionProcessor.Client/TransactionProcessor.Client.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/TransactionProcessor.Client/TransactionProcessorClient.cs b/TransactionProcessor.Client/TransactionProcessorClient.cs index 9fe3bd30..91e065f3 100644 --- a/TransactionProcessor.Client/TransactionProcessorClient.cs +++ b/TransactionProcessor.Client/TransactionProcessorClient.cs @@ -48,15 +48,12 @@ public async Task> GetEstate(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - // call was successful so now deserialise the body to the response object - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -65,103 +62,48 @@ public async Task> GetEstate(String accessToken, throw exception; } } + //private async Task> SendPostRequest(String uri, String accessToken, String content, CancellationToken cancellationToken) + //{ - private async Task> SendGetRequest(String uri, String accessToken, CancellationToken cancellationToken) { - - HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); - - // Make the Http Call here - HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); - - // Process the response - Result result = await this.HandleResponseX(httpResponse, cancellationToken); - - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); - - return Result.Success(result.Data); - } - - private async Task> SendPostRequest(String uri, String accessToken, String content, CancellationToken cancellationToken) - { - - HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); - requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json"); - - // Make the Http Call here - HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); - - // Process the response - Result result = await this.HandleResponseX(httpResponse, cancellationToken); - - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); - - return Result.Success(result.Data); - } - - private async Task> SendPutRequest(String uri, String accessToken, String content, CancellationToken cancellationToken) - { - - HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, uri); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); - requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json"); - - // Make the Http Call here - HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); - - // Process the response - Result result = await this.HandleResponseX(httpResponse, cancellationToken); - - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); - - return Result.Success(result.Data); - } - - public static class AuthenticationSchemes - { - public static readonly String Bearer = "Bearer"; - } + // HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri); + // requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); + // requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json"); - private async Task> SendPatchRequest(String uri, String accessToken, String content, CancellationToken cancellationToken) - { + // // Make the Http Call here + // HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); - HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Patch, uri); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); - requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json"); + // // Process the response + // Result result = await this.HandleResponseX(httpResponse, cancellationToken); - // Make the Http Call here - HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); + // if (result.IsFailed) + // return ResultHelpers.CreateFailure(result); - // Process the response - Result result = await this.HandleResponseX(httpResponse, cancellationToken); + // return Result.Success(result.Data); + //} - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + //public static class AuthenticationSchemes + //{ + // public static readonly String Bearer = "Bearer"; + //} - return Result.Success(result.Data); - } - private async Task> SendDeleteRequest(String uri, String accessToken, CancellationToken cancellationToken) - { + //private async Task> SendDeleteRequest(String uri, String accessToken, CancellationToken cancellationToken) + //{ - HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); + // HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri); + // requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken); - // Make the Http Call here - HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); + // // Make the Http Call here + // HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken); - // Process the response - Result result = await this.HandleResponseX(httpResponse, cancellationToken); + // // Process the response + // Result result = await this.HandleResponseX(httpResponse, cancellationToken); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + // if (result.IsFailed) + // return ResultHelpers.CreateFailure(result); - return Result.Success(result.Data); - } + // return Result.Success(result.Data); + //} public async Task CreateEstate(String accessToken, CreateEstateRequest createEstateRequest, @@ -169,8 +111,7 @@ public async Task CreateEstate(String accessToken, String requestUri = this.BuildRequestUrl("/api/estates/"); try { - String requestSerialised = JsonConvert.SerializeObject(createEstateRequest); - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, createEstateRequest,accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -191,11 +132,12 @@ public async Task>> GetEstates(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/all"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + Result> result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); - ResponseData> responseData = this.HandleResponseContent>(result.Data); + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -212,9 +154,7 @@ public async Task CreateFloatForContractProduct(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/floats"); try { - String requestSerialised = JsonConvert.SerializeObject(createFloatForContractProductRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, createFloatForContractProductRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -239,14 +179,12 @@ public async Task> GetMerchantBalance(String acc if (liveBalance) requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/livebalance"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -265,14 +203,12 @@ public async Task>> GetMerchant String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/balancehistory?startDate={startDate:yyyy-MM-dd}&endDate={endDate:yyyy-MM-dd}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + Result> result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -289,14 +225,12 @@ public async Task> GetSettlementByDate(String accessT CancellationToken cancellationToken) { String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/settlements/{settlementDate.Date:yyyy-MM-dd}/merchants/{merchantId}/pending"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -313,14 +247,12 @@ public async Task> GetVoucherByCode(String accessToke String requestUri = this.BuildRequestUrl($"/api/vouchers?estateId={estateId}&voucherCode={voucherCode}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -337,14 +269,12 @@ public async Task> GetVoucherByTransactionId(String a String requestUri = this.BuildRequestUrl($"/api/vouchers?estateId={estateId}&transactionId={transactionId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -360,16 +290,12 @@ public async Task> PerformTransaction(String accessTok CancellationToken cancellationToken) { String requestUri = this.BuildRequestUrl($"/api/transactions"); try { - String requestSerialised = JsonConvert.SerializeObject(transactionRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, transactionRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return Result.Success(result.Data); } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -387,12 +313,12 @@ public async Task ProcessSettlement(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/settlements/{settlementDate.Date:yyyy-MM-dd}/merchants/{merchantId}"); try { - Result result = await this.SendPostRequest(requestUri, accessToken, String.Empty, cancellationToken); + Result result = await this.SendHttpPostRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - - return Result.Success(); + + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -415,9 +341,7 @@ public async Task RecordFloatCreditPurchase(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/floats"); try { - String requestSerialised = JsonConvert.SerializeObject(recordFloatCreditPurchaseRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, recordFloatCreditPurchaseRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -432,22 +356,20 @@ public async Task RecordFloatCreditPurchase(String accessToken, } } - public async Task> RedeemVoucher(String accessToken, - RedeemVoucherRequest redeemVoucherRequest, - CancellationToken cancellationToken) { + public async Task RedeemVoucher(String accessToken, + RedeemVoucherRequest redeemVoucherRequest, + CancellationToken cancellationToken) { String requestUri = this.BuildRequestUrl($"/api/vouchers"); try { - String requestSerialised = JsonConvert.SerializeObject(redeemVoucherRequest); - Result result = await this.SendPutRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPutRequest(requestUri, redeemVoucherRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -464,7 +386,7 @@ public async Task ResendEmailReceipt(String accessToken, String requestUri = this.BuildRequestUrl($"/api/{estateId}/transactions/{transactionId}/resendreceipt"); try { - Result result = await this.SendPostRequest(requestUri, accessToken, String.Empty, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -487,15 +409,12 @@ public async Task AddContractToMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contracts"); try { - String requestSerialised = JsonConvert.SerializeObject(addMerchantContractRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, addMerchantContractRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); - } + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message Exception exception = new($"Error adding contract {addMerchantContractRequest.ContractId} to merchant Id {merchantId} in estate {estateId}.", ex); @@ -512,14 +431,13 @@ public async Task AddDeviceToMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/devices"); try { - String requestSerialised = JsonConvert.SerializeObject(addMerchantDeviceRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + + Result result = await this.SendHttpPatchRequest(requestUri, addMerchantDeviceRequest,accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -537,14 +455,12 @@ public async Task AddMerchantAddress(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/addresses"); try { - String requestSerialised = JsonConvert.SerializeObject(newAddressRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, newAddressRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -562,14 +478,12 @@ public async Task AddMerchantContact(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contacts"); try { - String requestSerialised = JsonConvert.SerializeObject(newContactRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, newContactRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -587,14 +501,12 @@ public async Task AddProductToContract(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts/{contractId}/products"); try { - String requestSerialised = JsonConvert.SerializeObject(addProductToContractRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, addProductToContractRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -613,14 +525,12 @@ public async Task AddTransactionFeeForProductToContract(String accessTok String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts/{contractId}/products/{productId}/transactionFees"); try { - String requestSerialised = JsonConvert.SerializeObject(addTransactionFeeForProductToContractRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, addTransactionFeeForProductToContractRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -638,14 +548,12 @@ public async Task AssignOperatorToMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/operators"); try { - String requestSerialised = JsonConvert.SerializeObject(assignOperatorRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, assignOperatorRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -663,12 +571,12 @@ public async Task RemoveOperatorFromMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/operators/{operatorId}"); try { - Result result = await this.SendDeleteRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpDeleteRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -685,12 +593,12 @@ public async Task RemoveOperatorFromEstate(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators/{operatorId}"); try { - Result result = await this.SendDeleteRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpDeleteRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -708,12 +616,12 @@ public async Task RemoveContractFromMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contracts/{contractId}"); try { - Result result = await this.SendDeleteRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpDeleteRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -730,9 +638,7 @@ public async Task CreateContract(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts/"); try { - String requestSerialised = JsonConvert.SerializeObject(createContractRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, createContractRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -754,9 +660,7 @@ public async Task CreateOperator(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators"); try { - String requestSerialised = JsonConvert.SerializeObject(createOperatorRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, createOperatorRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -778,14 +682,12 @@ public async Task CreateEstateUser(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/users"); try { - String requestSerialised = JsonConvert.SerializeObject(createEstateUserRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, createEstateUserRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; ; } catch (Exception ex) { @@ -803,9 +705,7 @@ public async Task CreateMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants"); try { - String requestSerialised = JsonConvert.SerializeObject(createMerchantRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, createMerchantRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -828,14 +728,12 @@ public async Task CreateMerchantUser(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/users"); try { - String requestSerialised = JsonConvert.SerializeObject(createMerchantUserRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, createMerchantUserRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -852,14 +750,12 @@ public async Task AssignOperatorToEstate(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators"); try { - String requestSerialised = JsonConvert.SerializeObject(assignOperatorRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, assignOperatorRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -878,12 +774,12 @@ public async Task DisableTransactionFeeForProduct(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts/{contractId}/products/{productId}/transactionFees/{transactionFeeId}"); try { - Result result = await this.SendDeleteRequest(requestUri, accessToken, cancellationToken); + Result result = await this.SendHttpDeleteRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -900,15 +796,12 @@ public async Task> GetContract(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts/{contractId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - // call was successful so now deserialise the body to the response object - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -924,14 +817,12 @@ public async Task>> GetContracts(String accessToke String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/contracts"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -948,14 +839,12 @@ public async Task> GetMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -972,14 +861,12 @@ public async Task>> GetMerchantContracts(String ac String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contracts"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -995,14 +882,12 @@ public async Task>> GetMerchants(String accessToke String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1020,14 +905,12 @@ public async Task>> GetMerchants(String accessToke String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/settlements/{settlementId}?merchantId={merchantId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1046,14 +929,12 @@ public async Task>> GetMerchants(String accessToke String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/settlements?merchantId={merchantId}&start_date={startDate}&end_date={endDate}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1072,15 +953,12 @@ public async Task>> GetTransactionFee String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contracts/{contractId}/products/{productId}/transactionFees"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - // call was successful so now deserialise the body to the response object - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1098,9 +976,7 @@ public async Task MakeMerchantDeposit(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/deposits"); try { - String requestSerialised = JsonConvert.SerializeObject(makeMerchantDepositRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, makeMerchantDepositRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -1123,9 +999,7 @@ public async Task MakeMerchantWithdrawal(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/withdrawals"); try { - String requestSerialised = JsonConvert.SerializeObject(makeMerchantWithdrawalRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, makeMerchantWithdrawalRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -1148,14 +1022,12 @@ public async Task SetMerchantSettlementSchedule(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}"); try { - String requestSerialised = JsonConvert.SerializeObject(setSettlementScheduleRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, setSettlementScheduleRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1174,14 +1046,12 @@ public async Task SwapDeviceForMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/devices/{deviceIdentifier}"); try { - String requestSerialised = JsonConvert.SerializeObject(swapMerchantDeviceRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, swapMerchantDeviceRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1199,14 +1069,12 @@ public async Task UpdateMerchant(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}"); try { - String requestSerialised = JsonConvert.SerializeObject(updateMerchantRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, updateMerchantRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1225,14 +1093,12 @@ public async Task UpdateMerchantAddress(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/addresses/{addressId}"); try { - String requestSerialised = JsonConvert.SerializeObject(updatedAddressRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, updatedAddressRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1251,14 +1117,12 @@ public async Task UpdateMerchantContact(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/merchants/{merchantId}/contacts/{contactId}"); try { - String requestSerialised = JsonConvert.SerializeObject(updatedContactRequest); - - Result result = await this.SendPatchRequest(requestUri, accessToken, requestSerialised, cancellationToken); + Result result = await this.SendHttpPatchRequest(requestUri, updatedContactRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - return Result.Success(); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1276,9 +1140,7 @@ public async Task UpdateOperator(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators/{operatorId}"); try { - String requestSerialised = JsonConvert.SerializeObject(updateOperatorRequest); - - Result result = await this.SendPostRequest(requestUri, accessToken, requestSerialised, cancellationToken); + var result = await this.SendHttpPostRequest(requestUri, updateOperatorRequest, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); @@ -1300,14 +1162,12 @@ public async Task> GetOperator(String accessToken, String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators/{operatorId}"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData responseData = this.HandleResponseContent(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message @@ -1323,14 +1183,12 @@ public async Task>> GetOperators(String accessToke String requestUri = this.BuildRequestUrl($"/api/estates/{estateId}/operators"); try { - Result result = await this.SendGetRequest(requestUri, accessToken, cancellationToken); + var result = await this.SendHttpGetRequest>(requestUri, accessToken, cancellationToken); if (result.IsFailed) return ResultHelpers.CreateFailure(result); - ResponseData> responseData = this.HandleResponseContent>(result.Data); - - return Result.Success(responseData.Data); + return result; } catch (Exception ex) { // An exception has occurred, add some additional information to the message diff --git a/TransactionProcessor.Database/TransactionProcessor.Database.csproj b/TransactionProcessor.Database/TransactionProcessor.Database.csproj index c449268c..7de7d287 100644 --- a/TransactionProcessor.Database/TransactionProcessor.Database.csproj +++ b/TransactionProcessor.Database/TransactionProcessor.Database.csproj @@ -18,9 +18,9 @@ - + - + diff --git a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj index 587cf3aa..61cd5782 100644 --- a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj +++ b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj b/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj index e5e75941..8fc0839e 100644 --- a/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj +++ b/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj @@ -6,6 +6,6 @@ enable - + diff --git a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj index 3686b55c..226b62a6 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj +++ b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj @@ -7,11 +7,11 @@ - + - + diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index 5a2f00ad..cd39ce7c 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -7,16 +7,16 @@ - + - - - + + + @@ -27,7 +27,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj index 3e9da336..72e3fed9 100644 --- a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj +++ b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj index bc82c1b1..c95f6df0 100644 --- a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj +++ b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj index 18b802dc..898712aa 100644 --- a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj +++ b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj @@ -6,10 +6,10 @@ - + - + diff --git a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj index 87b2d859..127c9da7 100644 --- a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj +++ b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj @@ -7,7 +7,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/TransactionProcessor/TransactionProcessor.csproj b/TransactionProcessor/TransactionProcessor.csproj index 7815593f..c617afe2 100644 --- a/TransactionProcessor/TransactionProcessor.csproj +++ b/TransactionProcessor/TransactionProcessor.csproj @@ -10,7 +10,7 @@ - + @@ -33,11 +33,11 @@ - - - + + + - + diff --git a/workload-install.ps1 b/workload-install.ps1 new file mode 100644 index 00000000..271841b6 --- /dev/null +++ b/workload-install.ps1 @@ -0,0 +1,332 @@ +# +# Copyright (c) Samsung Electronics. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +<# +.SYNOPSIS +Installs Tizen workload manifest. +.DESCRIPTION +Installs the WorkloadManifest.json and WorkloadManifest.targets files for Tizen to the dotnet sdk. +.PARAMETER Version +Use specific VERSION +.PARAMETER DotnetInstallDir +Dotnet SDK Location installed +#> + +[cmdletbinding()] +param( + [Alias('v')][string]$Version="", + [Alias('d')][string]$DotnetInstallDir="", + [Alias('t')][string]$DotnetTargetVersionBand="", + [Alias('u')][switch]$UpdateAllWorkloads +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" +$ProgressPreference = "SilentlyContinue" + +$ManifestBaseName = "Samsung.NET.Sdk.Tizen.Manifest" +$global:FallbackId = "" + +$LatestVersionMap = [ordered]@{ + "$ManifestBaseName-6.0.100" = "7.0.101"; + "$ManifestBaseName-6.0.200" = "7.0.100-preview.13.6"; + "$ManifestBaseName-6.0.300" = "8.0.133"; + "$ManifestBaseName-6.0.400" = "9.0.104"; + "$ManifestBaseName-7.0.100-preview.6" = "7.0.100-preview.6.14"; + "$ManifestBaseName-7.0.100-preview.7" = "7.0.100-preview.7.20"; + "$ManifestBaseName-7.0.100-rc.1" = "7.0.100-rc.1.22"; + "$ManifestBaseName-7.0.100-rc.2" = "7.0.100-rc.2.24"; + "$ManifestBaseName-7.0.100" = "7.0.103"; + "$ManifestBaseName-7.0.200" = "7.0.105"; + "$ManifestBaseName-7.0.300" = "7.0.120"; + "$ManifestBaseName-7.0.400" = "10.0.106"; + "$ManifestBaseName-8.0.100-alpha.1" = "7.0.104"; + "$ManifestBaseName-8.0.100-preview.2" = "7.0.106"; + "$ManifestBaseName-8.0.100-preview.3" = "7.0.107"; + "$ManifestBaseName-8.0.100-preview.4" = "7.0.108"; + "$ManifestBaseName-8.0.100-preview.5" = "7.0.110"; + "$ManifestBaseName-8.0.100-preview.6" = "7.0.121"; + "$ManifestBaseName-8.0.100-preview.7" = "7.0.122"; + "$ManifestBaseName-8.0.100-rc.1" = "7.0.124"; + "$ManifestBaseName-8.0.100-rc.2" = "7.0.125"; + "$ManifestBaseName-8.0.100-rtm" = "7.0.127"; + "$ManifestBaseName-8.0.100" = "8.0.144"; + "$ManifestBaseName-8.0.200" = "8.0.157"; + "$ManifestBaseName-8.0.300" = "8.0.156"; + "$ManifestBaseName-8.0.400" = "10.0.109"; + "$ManifestBaseName-9.0.100-alpha.1" = "8.0.134"; + "$ManifestBaseName-9.0.100-preview.1" = "8.0.135"; + "$ManifestBaseName-9.0.100-preview.2" = "8.0.137"; + "$ManifestBaseName-9.0.100" = "10.0.104"; + "$ManifestBaseName-9.0.200" = "10.0.110"; + "$ManifestBaseName-9.0.300" = "10.0.111"; +} + +function New-TemporaryDirectory { + $parent = [System.IO.Path]::GetTempPath() + $name = [System.IO.Path]::GetRandomFileName() + New-Item -ItemType Directory -Path (Join-Path $parent $name) +} + +function Ensure-Directory([string]$TestDir) { + Try { + New-Item -ItemType Directory -Path $TestDir -Force -ErrorAction stop | Out-Null + [io.file]::OpenWrite($(Join-Path -Path $TestDir -ChildPath ".test-write-access")).Close() + Remove-Item -Path $(Join-Path -Path $TestDir -ChildPath ".test-write-access") -Force + } + Catch [System.UnauthorizedAccessException] { + Write-Error "No permission to install. Try run with administrator mode." + } +} + +function Get-LatestVersion([string]$Id) { + $attempts=3 + $sleepInSeconds=3 + do + { + try + { + $Response = Invoke-WebRequest -Uri https://api.nuget.org/v3-flatcontainer/$($Id.ToLowerInvariant())/index.json -UseBasicParsing | ConvertFrom-Json + return $Response.versions | Select-Object -Last 1 + } + catch { + Write-Host "Id: $Id" + Write-Host "An exception was caught: $($_.Exception.Message)" + } + + $attempts-- + if ($attempts -gt 0) { Start-Sleep $sleepInSeconds } + } while ($attempts -gt 0) + + if ($LatestVersionMap.Contains($Id)) + { + Write-Host "Return cached latest version." + return $LatestVersionMap.$Id + } + else + { + $SubStringId = $Id.Substring(0, $ManifestBaseName.Length + 2); + $MatchingFallbackId = @() + $MatchingFallbackVersion = @() + foreach ($key in $LatestVersionMap.Keys) { + if ($key -like "$SubStringId*") { + $MatchingFallbackId += $key + $MatchingFallbackVersion += $LatestVersionMap[$key] + } + } + if ($MatchingFallbackVersion) + { + $global:FallbackId = $MatchingFallbackId[-1] + $FallbackVersion = $MatchingFallbackVersion[-1] + Write-Host "Return fallback version: $FallbackVersion" + return $FallbackVersion + } + } + + Write-Error "Wrong Id: $Id" +} + +function Get-Package([string]$Id, [string]$Version, [string]$Destination, [string]$FileExt = "nupkg") { + $OutFileName = "$Id.$Version.$FileExt" + $OutFilePath = Join-Path -Path $Destination -ChildPath $OutFileName + + if ($Id -match ".net[0-9]+$") { + $Id = $Id -replace (".net[0-9]+", "") + } + + Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/$Id/$Version" -OutFile $OutFilePath + + return $OutFilePath +} + +function Install-Pack([string]$Id, [string]$Version, [string]$Kind) { + $TempZipFile = $(Get-Package -Id $Id -Version $Version -Destination $TempDir -FileExt "zip") + $TempUnzipDir = Join-Path -Path $TempDir -ChildPath "unzipped\$Id" + + switch ($Kind) { + "manifest" { + Expand-Archive -Path $TempZipFile -DestinationPath $TempUnzipDir + New-Item -Path $TizenManifestDir -ItemType "directory" -Force | Out-Null + Copy-Item -Path "$TempUnzipDir\data\*" -Destination $TizenManifestDir -Force + } + {($_ -eq "sdk") -or ($_ -eq "framework")} { + Expand-Archive -Path $TempZipFile -DestinationPath $TempUnzipDir + if ( ($kind -eq "sdk") -and ($Id -match ".net[0-9]+$")) { + $Id = $Id -replace (".net[0-9]+", "") + } + $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "packs\$Id\$Version") + New-Item -Path $TargetDirectory -ItemType "directory" -Force | Out-Null + Copy-Item -Path "$TempUnzipDir/*" -Destination $TargetDirectory -Recurse -Force + } + "template" { + $TargetFileName = "$Id.$Version.nupkg".ToLower() + $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "template-packs") + New-Item -Path $TargetDirectory -ItemType "directory" -Force | Out-Null + Copy-Item $TempZipFile -Destination $(Join-Path -Path $TargetDirectory -ChildPath "$TargetFileName") -Force + } + } +} + +function Remove-Pack([string]$Id, [string]$Version, [string]$Kind) { + switch ($Kind) { + "manifest" { + Remove-Item -Path $TizenManifestDir -Recurse -Force + } + {($_ -eq "sdk") -or ($_ -eq "framework")} { + $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "packs\$Id\$Version") + Remove-Item -Path $TargetDirectory -Recurse -Force + } + "template" { + $TargetFileName = "$Id.$Version.nupkg".ToLower(); + Remove-Item -Path $(Join-Path -Path $DotnetInstallDir -ChildPath "template-packs\$TargetFileName") -Force + } + } +} + +function Install-TizenWorkload([string]$DotnetVersion) +{ + $VersionSplitSymbol = '.' + $SplitVersion = $DotnetVersion.Split($VersionSplitSymbol) + + $CurrentDotnetVersion = [Version]"$($SplitVersion[0]).$($SplitVersion[1])" + $DotnetVersionBand = $SplitVersion[0] + $VersionSplitSymbol + $SplitVersion[1] + $VersionSplitSymbol + $SplitVersion[2][0] + "00" + $ManifestName = "$ManifestBaseName-$DotnetVersionBand" + + if ($DotnetTargetVersionBand -eq "" -or $UpdateAllWorkloads.IsPresent) { + if ($CurrentDotnetVersion -ge "7.0") + { + $IsPreviewVersion = $DotnetVersion.Contains("-preview") -or $DotnetVersion.Contains("-rc") -or $DotnetVersion.Contains("-alpha") + if ($IsPreviewVersion -and ($SplitVersion.Count -ge 4)) { + $DotnetTargetVersionBand = $DotnetVersionBand + $SplitVersion[2].SubString(3) + $VersionSplitSymbol + $($SplitVersion[3]) + $ManifestName = "$ManifestBaseName-$DotnetTargetVersionBand" + } + elseif ($DotnetVersion.Contains("-rtm") -and ($SplitVersion.Count -ge 3)) { + $DotnetTargetVersionBand = $DotnetVersionBand + $SplitVersion[2].SubString(3) + $ManifestName = "$ManifestBaseName-$DotnetTargetVersionBand" + } + else { + $DotnetTargetVersionBand = $DotnetVersionBand + } + } + else { + $DotnetTargetVersionBand = $DotnetVersionBand + } + } + + # Check latest version of manifest. + if ($Version -eq "" -or $UpdateAllWorkloads.IsPresent) { + $Version = Get-LatestVersion -Id $ManifestName + } + + # Check workload manifest directory. + $ManifestDir = Join-Path -Path $DotnetInstallDir -ChildPath "sdk-manifests" | Join-Path -ChildPath $DotnetTargetVersionBand + $TizenManifestDir = Join-Path -Path $ManifestDir -ChildPath "samsung.net.sdk.tizen" + $TizenManifestFile = Join-Path -Path $TizenManifestDir -ChildPath "WorkloadManifest.json" + + # Check and remove already installed old version. + if (Test-Path $TizenManifestFile) { + $ManifestJson = $(Get-Content $TizenManifestFile | ConvertFrom-Json) + $OldVersion = $ManifestJson.version + if ($OldVersion -eq $Version) { + $DotnetWorkloadList = Invoke-Expression "& '$DotnetCommand' workload list | Select-String -Pattern '^tizen'" + if ($DotnetWorkloadList) + { + Write-Host "Tizen Workload $Version version is already installed." + Continue + } + } + + Ensure-Directory $ManifestDir + Write-Host "Removing $ManifestName/$OldVersion from $ManifestDir..." + Remove-Pack -Id $ManifestName -Version $OldVersion -Kind "manifest" + $ManifestJson.packs.PSObject.Properties | ForEach-Object { + Write-Host "Removing $($_.Name)/$($_.Value.version)..." + Remove-Pack -Id $_.Name -Version $_.Value.version -Kind $_.Value.kind + } + } + + Ensure-Directory $ManifestDir + $TempDir = $(New-TemporaryDirectory) + + # Install workload manifest. + Write-Host "Installing $ManifestName/$Version to $ManifestDir..." + if ($global:FallbackId) { + Install-Pack -Id $global:FallbackId -Version $Version -Kind "manifest" + } else { + Install-Pack -Id $ManifestName -Version $Version -Kind "manifest" + } + + # Download and install workload packs. + $NewManifestJson = $(Get-Content $TizenManifestFile | ConvertFrom-Json) + $NewManifestJson.packs.PSObject.Properties | ForEach-Object { + Write-Host "Installing $($_.Name)/$($_.Value.version)..." + Install-Pack -Id $_.Name -Version $_.Value.version -Kind $_.Value.kind + } + + # Add tizen to the installed workload metadata. + # Featured version band for metadata does NOT include any preview specifier. + # https://github.com/dotnet/sdk/blob/main/documentation/general/workloads/user-local-workloads.md + New-Item -Path $(Join-Path -Path $DotnetInstallDir -ChildPath "metadata\workloads\$DotnetVersionBand\InstalledWorkloads\tizen") -Force | Out-Null + if (Test-Path $(Join-Path -Path $DotnetInstallDir -ChildPath "metadata\workloads\$DotnetVersionBand\InstallerType\msi")) { + New-Item -Path "HKLM:\SOFTWARE\Microsoft\dotnet\InstalledWorkloads\Standalone\x64\$DotnetTargetVersionBand\tizen" -Force | Out-Null + } + + # Clean up + Remove-Item -Path $TempDir -Force -Recurse + + Write-Host "Done installing Tizen workload $Version" +} + +# Check dotnet install directory. +if ($DotnetInstallDir -eq "") { + if ($Env:DOTNET_ROOT -And $(Test-Path "$Env:DOTNET_ROOT")) { + $DotnetInstallDir = $Env:DOTNET_ROOT + } else { + $DotnetInstallDir = Join-Path -Path $Env:Programfiles -ChildPath "dotnet" + } +} +if (-Not $(Test-Path "$DotnetInstallDir")) { + Write-Error "No installed dotnet '$DotnetInstallDir'." +} + +# Check installed dotnet version +$DotnetCommand = "$DotnetInstallDir\dotnet" +if (Get-Command $DotnetCommand -ErrorAction SilentlyContinue) +{ + if ($UpdateAllWorkloads.IsPresent) + { + $InstalledDotnetSdks = Invoke-Expression "& '$DotnetCommand' --list-sdks | Select-String -Pattern '^6|^7'" | ForEach-Object {$_ -replace (" \[.*","")} + } + else + { + $InstalledDotnetSdks = Invoke-Expression "& '$DotnetCommand' --version" + } +} +else +{ + Write-Error "'$DotnetCommand' occurs an error." +} + +if (-Not $InstalledDotnetSdks) +{ + Write-Host "`n.NET SDK version 6 or later is required to install Tizen Workload." +} +else +{ + foreach ($DotnetSdk in $InstalledDotnetSdks) + { + try { + Write-Host "`nCheck Tizen Workload for sdk $DotnetSdk" + Install-TizenWorkload -DotnetVersion $DotnetSdk + } + catch { + Write-Host "Failed to install Tizen Workload for sdk $DotnetSdk" + Write-Host "$_" + Continue + } + } +} + +Write-Host "`nDone" From 28b91faea3c2bebc0888c281ad735b0b381a26a5 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 13 Nov 2025 14:37:56 +0000 Subject: [PATCH 02/29] :| --- .github/workflows/pullrequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 20dfc440..a28dd538 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: - name: Install NET 9 uses: actions/setup-dotnet@v4.0.1 with: - dotnet-version: '9.0.x' + dotnet-version: '9.0.306' - name: Restore Nuget Packages run: dotnet restore TransactionProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} From 2bd039870e212ce7bac0f708a65a431668b55ead Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Fri, 14 Nov 2025 17:31:59 +0000 Subject: [PATCH 03/29] fix test failures due to http payloads --- .../Bootstrapper/MiddlewareRegistry.cs | 6 + .../Controllers/ContractController.cs | 71 ++-- .../Controllers/EstateController.cs | 56 ++- .../Controllers/FloatController.cs | 11 +- .../Controllers/MerchantController.cs | 355 ++++++++---------- .../Controllers/OperatorController.cs | 29 +- .../Controllers/SettlementController.cs | 157 ++++---- .../Controllers/TransactionController.cs | 15 +- .../Controllers/VoucherController.cs | 32 +- .../Factories/ModelFactory.cs | 114 +++--- 10 files changed, 393 insertions(+), 453 deletions(-) diff --git a/TransactionProcessor/Bootstrapper/MiddlewareRegistry.cs b/TransactionProcessor/Bootstrapper/MiddlewareRegistry.cs index 95da1cdb..c91fb378 100644 --- a/TransactionProcessor/Bootstrapper/MiddlewareRegistry.cs +++ b/TransactionProcessor/Bootstrapper/MiddlewareRegistry.cs @@ -120,6 +120,12 @@ public MiddlewareRegistry() Assembly assembly = this.GetType().GetTypeInfo().Assembly; this.AddMvcCore().AddApplicationPart(assembly).AddControllersAsServices(); + + this.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.PropertyNamingPolicy = new SnakeCaseNamingPolicy(); + options.SerializerOptions.PropertyNameCaseInsensitive = true; // optional, but safer + }); } #endregion diff --git a/TransactionProcessor/Controllers/ContractController.cs b/TransactionProcessor/Controllers/ContractController.cs index b30db4eb..0f2943e2 100644 --- a/TransactionProcessor/Controllers/ContractController.cs +++ b/TransactionProcessor/Controllers/ContractController.cs @@ -77,22 +77,17 @@ private Result StandardSecurityChecks(Guid estateId) { /// [HttpGet] [Route("{contractId}")] - public async Task GetContract([FromRoute] Guid estateId, + public async Task GetContract([FromRoute] Guid estateId, [FromRoute] Guid contractId, CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); ContractQueries.GetContractQuery query = new ContractQueries.GetContractQuery(estateId, contractId); Result result = await Mediator.Send(query, cancellationToken); - if (result.IsFailed) - { - var x = result.ToActionResultX(); - return x; - } - - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } /// @@ -103,16 +98,16 @@ public async Task GetContract([FromRoute] Guid estateId, /// [HttpGet] [Route("")] - public async Task GetContracts([FromRoute] Guid estateId, - CancellationToken cancellationToken) { + public async Task GetContracts([FromRoute] Guid estateId, + CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); ContractQueries.GetContractsQuery query = new ContractQueries.GetContractsQuery(estateId); Result> result = await Mediator.Send(query, cancellationToken); - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } @@ -126,13 +121,13 @@ public async Task GetContracts([FromRoute] Guid estateId, /// [HttpPatch] [Route("{contractId}/products")] - public async Task AddProductToContract([FromRoute] Guid estateId, - [FromRoute] Guid contractId, - [FromBody] AddProductToContractRequest addProductToContractRequest, - CancellationToken cancellationToken) { + public async Task AddProductToContract([FromRoute] Guid estateId, + [FromRoute] Guid contractId, + [FromBody] AddProductToContractRequest addProductToContractRequest, + CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); Guid productId = Guid.NewGuid(); @@ -143,7 +138,7 @@ public async Task AddProductToContract([FromRoute] Guid estateId, // Route the command Result result = await Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } @@ -158,14 +153,14 @@ public async Task AddProductToContract([FromRoute] Guid estateId, /// [HttpPatch] [Route("{contractId}/products/{productId}/transactionFees")] - public async Task AddTransactionFeeForProductToContract([FromRoute] Guid estateId, - [FromRoute] Guid contractId, - [FromRoute] Guid productId, - [FromBody] AddTransactionFeeForProductToContractRequest addTransactionFeeForProductToContractRequest, - CancellationToken cancellationToken) { + public async Task AddTransactionFeeForProductToContract([FromRoute] Guid estateId, + [FromRoute] Guid contractId, + [FromRoute] Guid productId, + [FromBody] AddTransactionFeeForProductToContractRequest addTransactionFeeForProductToContractRequest, + CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); Guid transactionFeeId = Guid.NewGuid(); // Create the command @@ -174,7 +169,7 @@ public async Task AddTransactionFeeForProductToContract([FromRout // Route the command Result result = await Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } /// @@ -188,14 +183,14 @@ public async Task AddTransactionFeeForProductToContract([FromRout /// [HttpDelete] [Route("{contractId}/products/{productId}/transactionFees/{transactionFeeId}")] - public async Task DisableTransactionFeeForProduct([FromRoute] Guid estateId, - [FromRoute] Guid contractId, - [FromRoute] Guid productId, - [FromRoute] Guid transactionFeeId, - CancellationToken cancellationToken) { + public async Task DisableTransactionFeeForProduct([FromRoute] Guid estateId, + [FromRoute] Guid contractId, + [FromRoute] Guid productId, + [FromRoute] Guid transactionFeeId, + CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); // Create the command ContractCommands.DisableTransactionFeeForProductCommand command = new(contractId, estateId, productId, transactionFeeId); @@ -203,7 +198,7 @@ public async Task DisableTransactionFeeForProduct([FromRoute] Gui Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } @@ -216,12 +211,12 @@ public async Task DisableTransactionFeeForProduct([FromRoute] Gui /// [HttpPost] [Route("")] - public async Task CreateContract([FromRoute] Guid estateId, - [FromBody] CreateContractRequest createContractRequest, - CancellationToken cancellationToken) { + public async Task CreateContract([FromRoute] Guid estateId, + [FromBody] CreateContractRequest createContractRequest, + CancellationToken cancellationToken) { Result securityChecksResult = StandardSecurityChecks(estateId); if (securityChecksResult.IsFailed) - return securityChecksResult.ToActionResultX(); + return ResponseFactory.FromResult(securityChecksResult); Guid contractId = Guid.NewGuid(); // Create the command @@ -231,7 +226,7 @@ public async Task CreateContract([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } #endregion diff --git a/TransactionProcessor/Controllers/EstateController.cs b/TransactionProcessor/Controllers/EstateController.cs index 630a8f43..8af91bd7 100644 --- a/TransactionProcessor/Controllers/EstateController.cs +++ b/TransactionProcessor/Controllers/EstateController.cs @@ -68,13 +68,13 @@ internal ClaimsPrincipal GetUser() /// [HttpPost] [Route("")] - public async Task CreateEstate([FromBody] CreateEstateRequest createEstateRequest, + public async Task CreateEstate([FromBody] CreateEstateRequest createEstateRequest, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(GetUser())) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } // Create the command @@ -83,7 +83,7 @@ public async Task CreateEstate([FromBody] CreateEstateRequest cre // Route the command Result result = await Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } /// @@ -95,68 +95,60 @@ public async Task CreateEstate([FromBody] CreateEstateRequest cre /// Estate not found with estate Id {estateId} [HttpGet] [Route("{estateId}")] - public async Task GetEstate([FromRoute] Guid estateId, + public async Task GetEstate([FromRoute] Guid estateId, CancellationToken cancellationToken) { // Get the Estate Id claim from the user Result estateIdClaimResult = ClaimsHelper.GetUserClaim(GetUser(), "EstateId", estateId.ToString()); if (estateIdClaimResult.IsFailed) - return Result.Forbidden("User estate id claim is not valid").ToActionResultX(); + return ResponseFactory.FromResult(Result.Forbidden("User estate id claim is not valid")); Claim estateIdClaim = estateIdClaimResult.Data; string estateRoleName = Environment.GetEnvironmentVariable("EstateRoleName"); if (ClaimsHelper.IsUserRolesValid(GetUser(), new[] { string.IsNullOrEmpty(estateRoleName) ? "Estate" : estateRoleName }) == false) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } if (ClaimsHelper.ValidateRouteParameter(estateId, estateIdClaim) == false) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } EstateQueries.GetEstateQuery query = new(estateId); Result result = await Mediator.Send(query, cancellationToken); - if (result.IsFailed) - { - return result.ToActionResultX(); - } - - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } [HttpGet] [Route("{estateId}/all")] - public async Task GetEstates([FromRoute] Guid estateId, + public async Task GetEstates([FromRoute] Guid estateId, CancellationToken cancellationToken) { // Get the Estate Id claim from the user Result estateIdClaimResult = ClaimsHelper.GetUserClaim(GetUser(), "EstateId", estateId.ToString()); if (estateIdClaimResult.IsFailed) - return Result.Forbidden("User estate id claim is not valid").ToActionResultX(); + return ResponseFactory.FromResult(Result.Forbidden("User estate id claim is not valid")); Claim estateIdClaim = estateIdClaimResult.Data; string estateRoleName = Environment.GetEnvironmentVariable("EstateRoleName"); if (ClaimsHelper.IsUserRolesValid(GetUser(), new[] { string.IsNullOrEmpty(estateRoleName) ? "Estate" : estateRoleName }) == false) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } if (ClaimsHelper.ValidateRouteParameter(estateId, estateIdClaim) == false) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } EstateQueries.GetEstatesQuery query = new(estateId); Result> result = await Mediator.Send(query, cancellationToken); - if (result.IsFailed) - { - return result.ToActionResultX(); - } - - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } /// @@ -167,14 +159,14 @@ public async Task GetEstates([FromRoute] Guid estateId, /// The cancellation token./// [HttpPatch] [Route("{estateId}/users")] - public async Task CreateEstateUser([FromRoute] Guid estateId, + public async Task CreateEstateUser([FromRoute] Guid estateId, [FromBody] CreateEstateUserRequest createEstateUserRequest, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(GetUser())) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } // Create the command @@ -184,17 +176,17 @@ public async Task CreateEstateUser([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{estateId}/operators")] - public async Task AssignOperator([FromRoute] Guid estateId, [FromBody] AssignOperatorRequest assignOperatorRequest, CancellationToken cancellationToken) + public async Task AssignOperator([FromRoute] Guid estateId, [FromBody] AssignOperatorRequest assignOperatorRequest, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(GetUser())) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } // Create the command @@ -204,19 +196,19 @@ public async Task AssignOperator([FromRoute] Guid estateId, [From Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpDelete] [Route("{estateId}/operators/{operatorId}")] - public async Task RemoveOperator([FromRoute] Guid estateId, + public async Task RemoveOperator([FromRoute] Guid estateId, [FromRoute] Guid operatorId, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(GetUser())) { - return Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } EstateCommands.RemoveOperatorFromEstateCommand command = new(estateId, operatorId); @@ -225,7 +217,7 @@ public async Task RemoveOperator([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } #endregion diff --git a/TransactionProcessor/Controllers/FloatController.cs b/TransactionProcessor/Controllers/FloatController.cs index ccb9cb3b..7ff8c158 100644 --- a/TransactionProcessor/Controllers/FloatController.cs +++ b/TransactionProcessor/Controllers/FloatController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Shared.Results; using Shared.Results.Web; using SimpleResults; @@ -40,22 +41,22 @@ public FloatController(IMediator mediator){ } [HttpPost] - public async Task CreateFloatForContractProduct([FromRoute] Guid estateId, [FromBody] DataTransferObjects.CreateFloatForContractProductRequest createFloatRequest, CancellationToken cancellationToken){ + public async Task CreateFloatForContractProduct([FromRoute] Guid estateId, [FromBody] DataTransferObjects.CreateFloatForContractProductRequest createFloatRequest, CancellationToken cancellationToken){ FloatCommands.CreateFloatForContractProductCommand command = new(estateId, createFloatRequest.ContractId, createFloatRequest.ProductId, createFloatRequest.CreateDateTime); Result result= await this.Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPut] - public async Task RecordFloatCreditPurchase([FromRoute] Guid estateId, [FromBody] DataTransferObjects.RecordFloatCreditPurchaseRequest recordFloatCreditPurchaseRequest, CancellationToken cancellationToken){ + public async Task RecordFloatCreditPurchase([FromRoute] Guid estateId, [FromBody] DataTransferObjects.RecordFloatCreditPurchaseRequest recordFloatCreditPurchaseRequest, CancellationToken cancellationToken){ FloatCommands.RecordCreditPurchaseForFloatCommand command = new(estateId, recordFloatCreditPurchaseRequest.FloatId, recordFloatCreditPurchaseRequest.CreditAmount, recordFloatCreditPurchaseRequest.CostPrice, recordFloatCreditPurchaseRequest.PurchaseDateTime); Result result = await this.Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } } } diff --git a/TransactionProcessor/Controllers/MerchantController.cs b/TransactionProcessor/Controllers/MerchantController.cs index 0ef62e3e..4bee4f89 100644 --- a/TransactionProcessor/Controllers/MerchantController.cs +++ b/TransactionProcessor/Controllers/MerchantController.cs @@ -120,103 +120,86 @@ private Result PerformSecurityChecks(Guid estateId,Guid merchantId) { [HttpGet] [Route("{merchantId}/balance")] [SwaggerResponse(200, "OK", typeof(MerchantBalanceResponse))] - public async Task GetMerchantBalance([FromRoute] Guid estateId, + public async Task GetMerchantBalance([FromRoute] Guid estateId, [FromRoute] Guid merchantId, CancellationToken cancellationToken) { Result securityChecksResult = PerformSecurityChecks(estateId, merchantId); - if (securityChecksResult.Status == ResultStatus.Forbidden){ - return this.Forbid(); + if (securityChecksResult.Status == ResultStatus.Forbidden) { + return ResponseFactory.FromResult(securityChecksResult); } MerchantQueries.GetMerchantBalanceQuery query = new(estateId, merchantId); Result getMerchantBalanceResult = await this.Mediator.Send(query, cancellationToken); - if (getMerchantBalanceResult.IsFailed) { - return getMerchantBalanceResult.ToActionResultX(); - } - - Result result = Result.Success(new MerchantBalanceResponse - { - Balance = getMerchantBalanceResult.Data.Balance, - MerchantId = merchantId, - AvailableBalance = getMerchantBalanceResult.Data.AvailableBalance, - EstateId = estateId + return ResponseFactory.FromResult(getMerchantBalanceResult, r => { + MerchantBalanceResponse response = new() { + Balance = r.Balance, + MerchantId = r.MerchantId, + AvailableBalance = r.AvailableBalance, + EstateId = r.EstateId + }; + return response; }); - - return result.ToActionResultX(); } [HttpGet] [Route("{merchantId}/livebalance")] [SwaggerResponse(200, "OK", typeof(MerchantBalanceResponse))] - public async Task GetMerchantBalanceLive([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - CancellationToken cancellationToken) + public async Task GetMerchantBalanceLive([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + CancellationToken cancellationToken) { Result securityChecksResult = PerformSecurityChecks(estateId, merchantId); if (securityChecksResult.Status == ResultStatus.Forbidden) { - return this.Forbid(); + return ResponseFactory.FromResult(securityChecksResult); } MerchantQueries.GetMerchantLiveBalanceQuery query = new MerchantQueries.GetMerchantLiveBalanceQuery(merchantId); Result getLiveMerchantBalanceResult = await this.Mediator.Send(query, cancellationToken); - if (getLiveMerchantBalanceResult.IsFailed) - { - return getLiveMerchantBalanceResult.ToActionResultX(); - } - - Result result = Result.Success(new MerchantBalanceResponse - { - Balance = getLiveMerchantBalanceResult.Data.merchant.balance, - MerchantId = merchantId, - AvailableBalance = getLiveMerchantBalanceResult.Data.merchant.balance, - EstateId = estateId + return ResponseFactory.FromResult(getLiveMerchantBalanceResult, r => { + MerchantBalanceResponse response = new() { + Balance = r.merchant.balance, + MerchantId = Guid.Parse(r.merchant.Id), + AvailableBalance = r.merchant.balance, + EstateId = estateId}; + return response; }); - - return result.ToActionResultX(); } [HttpGet] [Route("{merchantId}/balancehistory")] - public async Task GetMerchantBalanceHistory([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromQuery] DateTime startDate, - [FromQuery] DateTime endDate, - CancellationToken cancellationToken) { + public async Task GetMerchantBalanceHistory([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromQuery] DateTime startDate, + [FromQuery] DateTime endDate, + CancellationToken cancellationToken) { Result securityChecksResult = PerformSecurityChecks(estateId, merchantId); - if (securityChecksResult.Status == ResultStatus.Forbidden) - { - return this.Forbid(); + if (securityChecksResult.Status == ResultStatus.Forbidden) { + return ResponseFactory.FromResult(securityChecksResult); } - MerchantQueries.GetMerchantBalanceHistoryQuery query = - new MerchantQueries.GetMerchantBalanceHistoryQuery(estateId, merchantId, startDate, endDate); + MerchantQueries.GetMerchantBalanceHistoryQuery query = new(estateId, merchantId, startDate, endDate); Result> getMerchantBalanceHistoryResult = await this.Mediator.Send(query, cancellationToken); - if (getMerchantBalanceHistoryResult.IsFailed) - { - return getMerchantBalanceHistoryResult.ToActionResultX(); - } - - - List response = new List(); - getMerchantBalanceHistoryResult.Data.ForEach(h => response.Add(new MerchantBalanceChangedEntryResponse { - Balance = h.Balance, - MerchantId = h.MerchantId, - EstateId = h.EstateId, - DateTime = h.DateTime, - ChangeAmount = h.ChangeAmount, - DebitOrCredit = h.DebitOrCredit, - OriginalEventId = h.OriginalEventId, - Reference = h.Reference, - })); - - Result> result = Result.Success(response); - return result.ToActionResultX(); + return ResponseFactory.FromResult(getMerchantBalanceHistoryResult, r => { + List response = new(); + r.ForEach(h => response.Add(new MerchantBalanceChangedEntryResponse + { + Balance = h.Balance, + MerchantId = h.MerchantId, + EstateId = h.EstateId, + DateTime = h.DateTime, + ChangeAmount = h.ChangeAmount, + DebitOrCredit = h.DebitOrCredit, + OriginalEventId = h.OriginalEventId, + Reference = h.Reference, + })); + return response; + }); } private ClaimsPrincipal UserOverride; @@ -258,14 +241,14 @@ private Result PerformStandardChecks(Guid estateId) [HttpPost] [Route("")] - public async Task CreateMerchant([FromRoute] Guid estateId, - [FromBody] CreateMerchantRequest createMerchantRequest, - CancellationToken cancellationToken) + public async Task CreateMerchant([FromRoute] Guid estateId, + [FromBody] CreateMerchantRequest createMerchantRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.CreateMerchantCommand command = new(estateId, createMerchantRequest); @@ -274,21 +257,21 @@ public async Task CreateMerchant([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{merchantId}/operators")] [ProducesResponseType(typeof(AssignOperatorResponse), 201)] - public async Task AssignOperator([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - AssignOperatorRequest assignOperatorRequest, - CancellationToken cancellationToken) + public async Task AssignOperator([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + AssignOperatorRequest assignOperatorRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.AssignOperatorToMerchantCommand command = new(estateId, merchantId, assignOperatorRequest); @@ -297,19 +280,19 @@ public async Task AssignOperator([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpDelete] [Route("{merchantId}/operators/{operatorId}")] - public async Task RemoveOperator([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] Guid operatorId, - CancellationToken cancellationToken) + public async Task RemoveOperator([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] Guid operatorId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.RemoveOperatorFromMerchantCommand command = new(estateId, merchantId, operatorId); @@ -318,19 +301,19 @@ public async Task RemoveOperator([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{merchantId}/devices")] - public async Task AddDevice([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] AddMerchantDeviceRequest addMerchantDeviceRequest, - CancellationToken cancellationToken) + public async Task AddDevice([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] AddMerchantDeviceRequest addMerchantDeviceRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.AddMerchantDeviceCommand command = new(estateId, merchantId, addMerchantDeviceRequest); @@ -339,19 +322,19 @@ public async Task AddDevice([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{merchantId}/contracts")] - public async Task AddContract([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] AddMerchantContractRequest addMerchantContractRequest, - CancellationToken cancellationToken) + public async Task AddContract([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] AddMerchantContractRequest addMerchantContractRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.AddMerchantContractCommand command = new(estateId, merchantId, addMerchantContractRequest); @@ -360,19 +343,19 @@ public async Task AddContract([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpDelete] [Route("{merchantId}/contracts/{contractId}")] - public async Task RemoveContract([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] Guid contractId, - CancellationToken cancellationToken) + public async Task RemoveContract([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] Guid contractId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.RemoveMerchantContractCommand command = new(estateId, merchantId, contractId); @@ -381,19 +364,19 @@ public async Task RemoveContract([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{merchantId}/users")] - public async Task CreateMerchantUser([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] CreateMerchantUserRequest createMerchantUserRequest, - CancellationToken cancellationToken) + public async Task CreateMerchantUser([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] CreateMerchantUserRequest createMerchantUserRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.CreateMerchantUserCommand command = new(estateId, merchantId, createMerchantUserRequest); @@ -402,19 +385,19 @@ public async Task CreateMerchantUser([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPost] [Route("{merchantId}/deposits")] - public async Task MakeDeposit([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] MakeMerchantDepositRequest makeMerchantDepositRequest, - CancellationToken cancellationToken) + public async Task MakeDeposit([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] MakeMerchantDepositRequest makeMerchantDepositRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } // This will always be a manual deposit as auto ones come in via another route @@ -424,21 +407,21 @@ public async Task MakeDeposit([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPost] [Route("{merchantId}/withdrawals")] //[SwaggerResponse(201, "Created", typeof(MakeMerchantDepositResponse))] //[SwaggerResponseExample(201, typeof(MakeMerchantDepositResponseExample))] - public async Task MakeWithdrawal([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] MakeMerchantWithdrawalRequest makeMerchantWithdrawalRequest, - CancellationToken cancellationToken) + public async Task MakeWithdrawal([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] MakeMerchantWithdrawalRequest makeMerchantWithdrawalRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.MakeMerchantWithdrawalCommand command = new(estateId, merchantId, makeMerchantWithdrawalRequest); @@ -447,20 +430,20 @@ public async Task MakeWithdrawal([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPatch] [Route("{merchantId}/devices/{deviceIdentifier}")] - public async Task SwapMerchantDevice([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] string deviceIdentifier, - [FromBody] SwapMerchantDeviceRequest swapMerchantDeviceRequest, - CancellationToken cancellationToken) + public async Task SwapMerchantDevice([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] string deviceIdentifier, + [FromBody] SwapMerchantDeviceRequest swapMerchantDeviceRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.SwapMerchantDeviceCommand command = new(estateId, merchantId, deviceIdentifier, swapMerchantDeviceRequest); @@ -469,7 +452,7 @@ public async Task SwapMerchantDevice([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } private Result PerformMerchantUserChecks(Guid estateId, Guid merchantId) @@ -505,96 +488,90 @@ private Result PerformMerchantUserChecks(Guid estateId, Guid merchantId) [HttpGet] [Route("{merchantId}")] - public async Task GetMerchant([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - CancellationToken cancellationToken) + public async Task GetMerchant([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformMerchantUserChecks(estateId, merchantId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantQueries.GetMerchantQuery query = new(estateId, merchantId); // Route the query Result result = await Mediator.Send(query, cancellationToken); - if (result.IsFailed) - return result.ToActionResultX(); - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } [Route("{merchantId}/contracts")] [HttpGet] - public async Task GetMerchantContracts([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - CancellationToken cancellationToken) + public async Task GetMerchantContracts([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformMerchantUserChecks(estateId, merchantId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantQueries.GetMerchantContractsQuery query = new(estateId, merchantId); Result> result = await Mediator.Send(query, cancellationToken); - if (result.IsFailed) - return result.ToActionResultX(); - - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } [HttpGet] [Route("")] - public async Task GetMerchants([FromRoute] Guid estateId, - CancellationToken cancellationToken) + public async Task GetMerchants([FromRoute] Guid estateId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantQueries.GetMerchantsQuery query = new(estateId); Result> result = await Mediator.Send(query, cancellationToken); - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } [Route("{merchantId}/contracts/{contractId}/products/{productId}/transactionFees")] [HttpGet] - public async Task GetTransactionFeesForProduct([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] Guid contractId, - [FromRoute] Guid productId, - CancellationToken cancellationToken) + public async Task GetTransactionFeesForProduct([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] Guid contractId, + [FromRoute] Guid productId, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformMerchantUserChecks(estateId, merchantId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantQueries.GetTransactionFeesForProductQuery query = new(estateId, merchantId, contractId, productId); Result> transactionFeesResult = await Mediator.Send(query, cancellationToken); - if (transactionFeesResult.IsFailed) - return transactionFeesResult.ToActionResultX(); - List transactionFees = transactionFeesResult.Data; - return ModelFactory.ConvertFrom(transactionFees).ToActionResultX(); + + return ResponseFactory.FromResult(transactionFeesResult, ModelFactory.ConvertFrom); } [HttpPatch] [Route("{merchantId}")] - public async Task UpdateMerchant([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] UpdateMerchantRequest updateMerchantRequest, - CancellationToken cancellationToken) + public async Task UpdateMerchant([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] UpdateMerchantRequest updateMerchantRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.UpdateMerchantCommand command = new(estateId, merchantId, updateMerchantRequest); @@ -603,19 +580,19 @@ public async Task UpdateMerchant([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [Route("{merchantId}/addresses")] [HttpPatch] - public async Task AddMerchantAddress([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] DataTransferObjects.Requests.Merchant.Address addAddressRequest, - CancellationToken cancellationToken) + public async Task AddMerchantAddress([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] DataTransferObjects.Requests.Merchant.Address addAddressRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.AddMerchantAddressCommand command = new(estateId, merchantId, addAddressRequest); @@ -624,20 +601,20 @@ public async Task AddMerchantAddress([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [Route("{merchantId}/addresses/{addressId}")] [HttpPatch] - public async Task UpdateMerchantAddress([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] Guid addressId, - [FromBody] DataTransferObjects.Requests.Merchant.Address updateAddressRequest, - CancellationToken cancellationToken) + public async Task UpdateMerchantAddress([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] Guid addressId, + [FromBody] DataTransferObjects.Requests.Merchant.Address updateAddressRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.UpdateMerchantAddressCommand command = new(estateId, merchantId, addressId, updateAddressRequest); @@ -646,19 +623,19 @@ public async Task UpdateMerchantAddress([FromRoute] Guid estateId Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [Route("{merchantId}/contacts")] [HttpPatch] - public async Task AddMerchantContact([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] DataTransferObjects.Requests.Merchant.Contact addContactRequest, - CancellationToken cancellationToken) + public async Task AddMerchantContact([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] DataTransferObjects.Requests.Merchant.Contact addContactRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.AddMerchantContactCommand command = new(estateId, merchantId, addContactRequest); @@ -667,20 +644,20 @@ public async Task AddMerchantContact([FromRoute] Guid estateId, Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [Route("{merchantId}/contacts/{contactId}")] [HttpPatch] - public async Task UpdateMerchantContact([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromRoute] Guid contactId, - [FromBody] DataTransferObjects.Requests.Merchant.Contact updateContactRequest, - CancellationToken cancellationToken) + public async Task UpdateMerchantContact([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromRoute] Guid contactId, + [FromBody] DataTransferObjects.Requests.Merchant.Contact updateContactRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.UpdateMerchantContactCommand command = new(estateId, merchantId, contactId, updateContactRequest); @@ -689,19 +666,19 @@ public async Task UpdateMerchantContact([FromRoute] Guid estateId Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPost] [Route("{merchantId}/statements")] - public async Task GenerateMerchantStatement([FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - [FromBody] GenerateMerchantStatementRequest generateMerchantStatementRequest, - CancellationToken cancellationToken) + public async Task GenerateMerchantStatement([FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + [FromBody] GenerateMerchantStatementRequest generateMerchantStatementRequest, + CancellationToken cancellationToken) { Result isRequestAllowedResult = PerformStandardChecks(estateId); if (isRequestAllowedResult.IsFailed) { - return Forbid(); + return ResponseFactory.FromResult(isRequestAllowedResult); } MerchantCommands.GenerateMerchantStatementCommand command = new(estateId, merchantId, generateMerchantStatementRequest); @@ -710,6 +687,6 @@ public async Task GenerateMerchantStatement([FromRoute] Guid esta Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } } \ No newline at end of file diff --git a/TransactionProcessor/Controllers/OperatorController.cs b/TransactionProcessor/Controllers/OperatorController.cs index 460bf967..0a9cf21f 100644 --- a/TransactionProcessor/Controllers/OperatorController.cs +++ b/TransactionProcessor/Controllers/OperatorController.cs @@ -61,7 +61,7 @@ internal ClaimsPrincipal GetUser() /// [HttpPost] [Route("")] - public async Task CreateOperator([FromRoute] Guid estateId, [FromBody] CreateOperatorRequest createOperatorRequest, CancellationToken cancellationToken) + public async Task CreateOperator([FromRoute] Guid estateId, [FromBody] CreateOperatorRequest createOperatorRequest, CancellationToken cancellationToken) { // Create the command OperatorCommands.CreateOperatorCommand command = new OperatorCommands.CreateOperatorCommand(estateId, createOperatorRequest); @@ -70,13 +70,13 @@ public async Task CreateOperator([FromRoute] Guid estateId, [From Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpPost] [Route("{operatorId}")] [SwaggerResponse(200, "OK")] - public async Task UpdateOperator([FromRoute] Guid estateId, [FromRoute] Guid operatorId, [FromBody] UpdateOperatorRequest updateOperatorRequest, CancellationToken cancellationToken) + public async Task UpdateOperator([FromRoute] Guid estateId, [FromRoute] Guid operatorId, [FromBody] UpdateOperatorRequest updateOperatorRequest, CancellationToken cancellationToken) { // Create the command OperatorCommands.UpdateOperatorCommand command = new OperatorCommands.UpdateOperatorCommand(estateId, operatorId, updateOperatorRequest); @@ -85,13 +85,13 @@ public async Task UpdateOperator([FromRoute] Guid estateId, [From Result result = await Mediator.Send(command, cancellationToken); // return the result - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } [HttpGet] [Route("{operatorId}")] - public async Task GetOperator([FromRoute] Guid estateId, + public async Task GetOperator([FromRoute] Guid estateId, [FromRoute] Guid operatorId, CancellationToken cancellationToken) { @@ -99,29 +99,22 @@ public async Task GetOperator([FromRoute] Guid estateId, OperatorQueries.GetOperatorQuery query = new(estateId, operatorId); // Route the command - Result getOperatorResult = await Mediator.Send(query, cancellationToken); - if (getOperatorResult.IsFailed) - return getOperatorResult.ToActionResultX(); - - Models.Operator.Operator @operator = getOperatorResult.Data; - return ModelFactory.ConvertFrom(@operator).ToActionResultX(); + Result result = await Mediator.Send(query, cancellationToken); + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } [HttpGet] [Route("")] - public async Task GetOperators([FromRoute] Guid estateId, + public async Task GetOperators([FromRoute] Guid estateId, CancellationToken cancellationToken) { // Create the command OperatorQueries.GetOperatorsQuery query = new(estateId); // Route the command - Result> getOperatorResult = await Mediator.Send(query, cancellationToken); - if (getOperatorResult.IsFailed) - return getOperatorResult.ToActionResultX(); - - List @operatorList = getOperatorResult.Data; - return ModelFactory.ConvertFrom(@operatorList).ToActionResultX(); + Result> result = await Mediator.Send(query, cancellationToken); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } #region Others diff --git a/TransactionProcessor/Controllers/SettlementController.cs b/TransactionProcessor/Controllers/SettlementController.cs index ff44d338..09bcf08d 100644 --- a/TransactionProcessor/Controllers/SettlementController.cs +++ b/TransactionProcessor/Controllers/SettlementController.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SecurityService.DataTransferObjects.Responses; using Shared.Results; @@ -47,7 +48,7 @@ public SettlementController(IMediator mediator) [HttpGet] [Route("{settlementDate}/merchants/{merchantId}/pending")] - public async Task GetPendingSettlement([FromRoute] DateTime settlementDate, + public async Task GetPendingSettlement([FromRoute] DateTime settlementDate, [FromRoute] Guid estateId, [FromRoute] Guid merchantId, CancellationToken cancellationToken) @@ -55,106 +56,57 @@ public async Task GetPendingSettlement([FromRoute] DateTime settl SettlementQueries.GetPendingSettlementQuery query = new(settlementDate, merchantId, estateId); Result getPendingSettlementResult = await this.Mediator.Send(query, cancellationToken); - if (getPendingSettlementResult.IsFailed) - return getPendingSettlementResult.ToActionResultX(); - - SettlementResponse settlementResponse = new SettlementResponse - { - EstateId = getPendingSettlementResult.Data.EstateId, - MerchantId = getPendingSettlementResult.Data.MerchantId, - NumberOfFeesPendingSettlement = getPendingSettlementResult.Data.GetNumberOfFeesPendingSettlement(), - NumberOfFeesSettled = getPendingSettlementResult.Data.GetNumberOfFeesSettled(), - SettlementDate = getPendingSettlementResult.Data.SettlementDate, - SettlementCompleted = getPendingSettlementResult.Data.SettlementComplete - }; - - return Result.Success(settlementResponse).ToActionResultX(); - + return ResponseFactory.FromResult(getPendingSettlementResult, r => { + SettlementResponse settlementResponse = new SettlementResponse { + EstateId = r.EstateId, + MerchantId = r.MerchantId, + NumberOfFeesPendingSettlement = r.GetNumberOfFeesPendingSettlement(), + NumberOfFeesSettled = r.GetNumberOfFeesSettled(), + SettlementDate = r.SettlementDate, + SettlementCompleted = r.SettlementComplete + }; + return settlementResponse; + }); } [HttpPost] [Route("{settlementDate}/merchants/{merchantId}")] - public async Task ProcessSettlement([FromRoute] DateTime settlementDate, - [FromRoute] Guid estateId, - [FromRoute] Guid merchantId, - CancellationToken cancellationToken) + public async Task ProcessSettlement([FromRoute] DateTime settlementDate, + [FromRoute] Guid estateId, + [FromRoute] Guid merchantId, + CancellationToken cancellationToken) { SettlementCommands.ProcessSettlementCommand command = new(settlementDate, merchantId, estateId); Result result = await this.Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result, guid => guid); } [Route("{settlementId}")] [HttpGet] - public async Task GetSettlement([FromRoute] Guid estateId, - [FromQuery] Guid merchantId, - [FromRoute] Guid settlementId, - CancellationToken cancellationToken) + public async Task GetSettlement([FromRoute] Guid estateId, + [FromQuery] Guid merchantId, + [FromRoute] Guid settlementId, + CancellationToken cancellationToken) { SettlementQueries.GetSettlementQuery query = new(estateId, merchantId, settlementId); var result = await this.Mediator.Send(query, cancellationToken); - if (result.IsFailed) - return result.ToActionResultX(); - - DataTransferObjects.Responses.Settlement.SettlementResponse settlementResponse = new() { - IsCompleted = result.Data.IsCompleted, - NumberOfFeesSettled = result.Data.NumberOfFeesSettled, - SettlementDate = result.Data.SettlementDate, - SettlementFees = new(), - SettlementId = result.Data.SettlementId, - ValueOfFeesSettled = result.Data.ValueOfFeesSettled - }; - - foreach (SettlementFeeModel settlementFeeResponse in result.Data.SettlementFees) - { - settlementResponse.SettlementFees.Add(new() - { - TransactionId = settlementFeeResponse.TransactionId, - MerchantId = settlementFeeResponse.MerchantId, - MerchantName = settlementFeeResponse.MerchantName, - SettlementDate = settlementFeeResponse.SettlementDate, - SettlementId = settlementFeeResponse.SettlementId, - CalculatedValue = settlementFeeResponse.CalculatedValue, - FeeDescription = settlementFeeResponse.FeeDescription, - IsSettled = settlementFeeResponse.IsSettled, - OperatorIdentifier = settlementFeeResponse.OperatorIdentifier - }); - } - - return Result.Success(settlementResponse).ToActionResultX(); - } - [Route("")] - [HttpGet] - public async Task GetSettlements([FromRoute] Guid estateId, - [FromQuery] Guid? merchantId, - [FromQuery(Name = "start_date")] string startDate, - [FromQuery(Name = "end_date")] string endDate, - CancellationToken cancellationToken) - { - SettlementQueries.GetSettlementsQuery query = new(estateId, merchantId, startDate, endDate); - var result = await this.Mediator.Send(query, cancellationToken); - if (result.IsFailed) - return result.ToActionResultX(); - - var responses = new List(); - foreach (SettlementModel settlementResponses in result.Data) - { - DataTransferObjects.Responses.Settlement.SettlementResponse sr = new DataTransferObjects.Responses.Settlement.SettlementResponse + return ResponseFactory.FromResult(result, r => { + DataTransferObjects.Responses.Settlement.SettlementResponse settlementResponse = new() { - IsCompleted = settlementResponses.IsCompleted, - NumberOfFeesSettled = settlementResponses.NumberOfFeesSettled, - SettlementDate = settlementResponses.SettlementDate, + IsCompleted = r.IsCompleted, + NumberOfFeesSettled = r.NumberOfFeesSettled, + SettlementDate = r.SettlementDate, SettlementFees = new(), - SettlementId = settlementResponses.SettlementId, - ValueOfFeesSettled = settlementResponses.ValueOfFeesSettled + SettlementId = r.SettlementId, + ValueOfFeesSettled = r.ValueOfFeesSettled }; - foreach (SettlementFeeModel settlementFeeResponse in settlementResponses.SettlementFees) + foreach (SettlementFeeModel settlementFeeResponse in r.SettlementFees) { - sr.SettlementFees.Add(new() + settlementResponse.SettlementFees.Add(new() { TransactionId = settlementFeeResponse.TransactionId, MerchantId = settlementFeeResponse.MerchantId, @@ -167,11 +119,52 @@ public async Task GetSettlements([FromRoute] Guid estateId, OperatorIdentifier = settlementFeeResponse.OperatorIdentifier }); } - responses.Add(sr); - } + return settlementResponse; + }); + } + + [Route("")] + [HttpGet] + public async Task GetSettlements([FromRoute] Guid estateId, + [FromQuery] Guid? merchantId, + [FromQuery(Name = "start_date")] string startDate, + [FromQuery(Name = "end_date")] string endDate, + CancellationToken cancellationToken) + { + SettlementQueries.GetSettlementsQuery query = new(estateId, merchantId, startDate, endDate); + Result> result = await this.Mediator.Send(query, cancellationToken); + return ResponseFactory.FromResult(result, r => { + List responses = new List(); + foreach (SettlementModel settlementResponses in r) { + DataTransferObjects.Responses.Settlement.SettlementResponse sr = new DataTransferObjects.Responses.Settlement.SettlementResponse { + IsCompleted = settlementResponses.IsCompleted, + NumberOfFeesSettled = settlementResponses.NumberOfFeesSettled, + SettlementDate = settlementResponses.SettlementDate, + SettlementFees = new(), + SettlementId = settlementResponses.SettlementId, + ValueOfFeesSettled = settlementResponses.ValueOfFeesSettled + }; + + foreach (SettlementFeeModel settlementFeeResponse in settlementResponses.SettlementFees) { + sr.SettlementFees.Add(new() { + TransactionId = settlementFeeResponse.TransactionId, + MerchantId = settlementFeeResponse.MerchantId, + MerchantName = settlementFeeResponse.MerchantName, + SettlementDate = settlementFeeResponse.SettlementDate, + SettlementId = settlementFeeResponse.SettlementId, + CalculatedValue = settlementFeeResponse.CalculatedValue, + FeeDescription = settlementFeeResponse.FeeDescription, + IsSettled = settlementFeeResponse.IsSettled, + OperatorIdentifier = settlementFeeResponse.OperatorIdentifier + }); + } + + responses.Add(sr); + } - return Result.Success(responses).ToActionResultX(); + return responses; + }); } #endregion diff --git a/TransactionProcessor/Controllers/TransactionController.cs b/TransactionProcessor/Controllers/TransactionController.cs index 57d7ee9c..f935c983 100644 --- a/TransactionProcessor/Controllers/TransactionController.cs +++ b/TransactionProcessor/Controllers/TransactionController.cs @@ -11,6 +11,7 @@ namespace TransactionProcessor.Controllers using Humanizer; using MediatR; using Microsoft.AspNetCore.Authorization; + using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Models; using Newtonsoft.Json; @@ -66,14 +67,14 @@ public TransactionController(IMediator mediator) [SwaggerResponse(201, "Created", typeof(SerialisedMessage))] [SwaggerRequestExample(typeof(List), typeof(TransactionRequestExample))] [SwaggerResponseExample(201, typeof(TransactionResponseExample))] - public async Task PerformTransaction([FromBody] SerialisedMessage transactionRequest, + public async Task PerformTransaction([FromBody] SerialisedMessage transactionRequest, CancellationToken cancellationToken) { DateTime transactionReceivedDateTime = DateTime.Now; // Reject password tokens if (ClaimsHelper.IsPasswordToken(this.User)) { - return this.Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } Guid estateId = Guid.Parse(transactionRequest.Metadata[MetadataContants.KeyNameEstateId]); @@ -98,28 +99,28 @@ public async Task PerformTransaction([FromBody] SerialisedMessage ReconciliationRequest rr => await this.ProcessSpecificMessage(rr, cancellationToken), _ => Result.Invalid($"DTO Type {dto.GetType().Name} not supported)") }; - - return transactionResult.ToActionResultX(); + + return ResponseFactory.FromResult(transactionResult, message => message); } [HttpPost] [Route("/api/{estateId}/transactions/{transactionId}/resendreceipt")] [SwaggerResponseExample(201, typeof(TransactionResponseExample))] - public async Task ResendTransactionReceipt([FromRoute] Guid estateId, + public async Task ResendTransactionReceipt([FromRoute] Guid estateId, [FromRoute] Guid transactionId, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(this.User)) { - return this.Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } TransactionCommands.ResendTransactionReceiptCommand command= new(transactionId,estateId); var result = await this.Mediator.Send(command, cancellationToken); - return result.ToActionResultX(); + return ResponseFactory.FromResult(result); } /// diff --git a/TransactionProcessor/Controllers/VoucherController.cs b/TransactionProcessor/Controllers/VoucherController.cs index 4255d299..4025c5e7 100644 --- a/TransactionProcessor/Controllers/VoucherController.cs +++ b/TransactionProcessor/Controllers/VoucherController.cs @@ -1,4 +1,5 @@ -using Shared.Results; +using Microsoft.AspNetCore.Http; +using Shared.Results; using Shared.Results.Web; using SimpleResults; using Swashbuckle.AspNetCore.Filters; @@ -58,23 +59,20 @@ public VoucherController(IMediator mediator, [HttpPut] [SwaggerResponse(200, "OK", typeof(RedeemVoucherResponse))] [SwaggerResponseExample(200, typeof(RedeemVoucherResponseExample))] - public async Task RedeemVoucher(RedeemVoucherRequest redeemVoucherRequest, + public async Task RedeemVoucher(RedeemVoucherRequest redeemVoucherRequest, CancellationToken cancellationToken) { // Reject password tokens - if (ClaimsHelper.IsPasswordToken(this.User)) - { - return this.Forbid(); + if (ClaimsHelper.IsPasswordToken(this.User)) { + return ResponseFactory.FromResult(Result.Forbidden()); } DateTime redeemedDateTime = redeemVoucherRequest.RedeemedDateTime.HasValue ? redeemVoucherRequest.RedeemedDateTime.Value : DateTime.Now; VoucherCommands.RedeemVoucherCommand command = new(redeemVoucherRequest.EstateId, redeemVoucherRequest.VoucherCode, redeemedDateTime); Result result = await this.Mediator.Send(command, cancellationToken); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result).ToActionResultX(); - - return ModelFactory.ConvertFrom(result.Data).ToActionResultX(); + + return ResponseFactory.FromResult(result, ModelFactory.ConvertFrom); } /// @@ -87,36 +85,32 @@ public async Task RedeemVoucher(RedeemVoucherRequest redeemVouche [HttpGet] [SwaggerResponse(200, "OK", typeof(GetVoucherResponse))] [SwaggerResponseExample(200, typeof(GetVoucherResponseExample))] - public async Task GetVoucher([FromQuery] Guid estateId, + public async Task GetVoucher([FromQuery] Guid estateId, [FromQuery] String voucherCode, [FromQuery] Guid transactionId, CancellationToken cancellationToken) { // Reject password tokens if (ClaimsHelper.IsPasswordToken(this.User)) { - return this.Forbid(); + return ResponseFactory.FromResult(Result.Forbidden()); } if (String.IsNullOrEmpty(voucherCode) == false) { VoucherQueries.GetVoucherByVoucherCodeQuery queryByVoucherCode = new(estateId, voucherCode); // By code is priority Result getVoucherByCodeResult = await this.Mediator.Send(queryByVoucherCode, cancellationToken); - if (getVoucherByCodeResult.IsFailed) - return ResultHelpers.CreateFailure(getVoucherByCodeResult).ToActionResultX(); - return ModelFactory.ConvertFrom(getVoucherByCodeResult.Data).ToActionResultX(); + return ResponseFactory.FromResult(getVoucherByCodeResult, ModelFactory.ConvertFrom); } if (transactionId != Guid.Empty) { // By transaction id is an additional filter VoucherQueries.GetVoucherByTransactionIdQuery queryByTransactionId = new(estateId, transactionId); Result getVoucherByTransactionIdResult = await this.Mediator.Send(queryByTransactionId, cancellationToken); - if (getVoucherByTransactionIdResult.IsFailed) - return ResultHelpers.CreateFailure(getVoucherByTransactionIdResult).ToActionResultX(); - - return ModelFactory.ConvertFrom(getVoucherByTransactionIdResult.Data).ToActionResultX(); + + return ResponseFactory.FromResult(getVoucherByTransactionIdResult, ModelFactory.ConvertFrom); } - return Result.Invalid().ToActionResultX(); + return ResponseFactory.FromResult(Result.Invalid()); } #endregion diff --git a/TransactionProcessor/Factories/ModelFactory.cs b/TransactionProcessor/Factories/ModelFactory.cs index b7d97538..5cf2add2 100644 --- a/TransactionProcessor/Factories/ModelFactory.cs +++ b/TransactionProcessor/Factories/ModelFactory.cs @@ -1,6 +1,7 @@ using System.Linq; using SimpleResults; using TransactionProcessor.DataTransferObjects.Responses.Contract; +using TransactionProcessor.DataTransferObjects.Responses.Estate; using TransactionProcessor.DataTransferObjects.Responses.Merchant; using TransactionProcessor.DataTransferObjects.Responses.Operator; using ProductType = TransactionProcessor.DataTransferObjects.Responses.Contract.ProductType; @@ -25,23 +26,19 @@ namespace TransactionProcessor.Factories public static class ModelFactory { #region Methods - public static Result> ConvertFrom(List contracts) + public static List ConvertFrom(List contracts) { List> result = new(); contracts.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); - - if (result.Any(c => c.IsFailed)) - return Result.Failure("Failed converting contracts"); - - return Result.Success(result.Select(r => r.Data).ToList()); + + return result.Select(r => r.Data).ToList(); } - public static Result ConvertFrom(Models.Contract.Contract contract) + public static ContractResponse ConvertFrom(Models.Contract.Contract contract) { - if (contract == null) - { - return Result.Invalid("contract cannot be null"); + if (contract == null) { + return null; } ContractResponse contractResponse = new ContractResponse @@ -90,14 +87,13 @@ public static Result ConvertFrom(Models.Contract.Contract cont }); } - return Result.Success(contractResponse); + return contractResponse; } - public static Result ConvertFrom(Models.Operator.Operator @operator) + public static OperatorResponse ConvertFrom(Models.Operator.Operator @operator) { - if (@operator == null) - { - return Result.Invalid("operator cannot be null"); + if (@operator == null) { + return null; } OperatorResponse response = new(); @@ -106,31 +102,29 @@ public static Result ConvertFrom(Models.Operator.Operator @ope response.RequireCustomMerchantNumber = @operator.RequireCustomMerchantNumber; response.Name = @operator.Name; - return Result.Success(response); + return response; } - public static Result> ConvertFrom(List @operators) + public static List ConvertFrom(List @operators) { if (@operators == null || @operators.Any() == false) { - return Result.Success(new List()); + return new List(); } List> result = new(); @operators.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); - if (result.Any(c => c.IsFailed)) - return Result.Failure("Failed converting operators"); - return Result.Success(result.Select(r => r.Data).ToList()); + return result.Select(r => r.Data).ToList(); } - public static Result ConvertFrom(ProcessLogonTransactionResponse processLogonTransactionResponse) + public static SerialisedMessage ConvertFrom(ProcessLogonTransactionResponse processLogonTransactionResponse) { if (processLogonTransactionResponse == null) { - return Result.Invalid("processLogonTransactionResponse cannot be null"); + return null; } LogonTransactionResponse logonTransactionResponse = new LogonTransactionResponse @@ -142,7 +136,7 @@ public static Result ConvertFrom(ProcessLogonTransactionRespo TransactionId = processLogonTransactionResponse.TransactionId }; - return Result.Success(new SerialisedMessage + return new SerialisedMessage { Metadata = new Dictionary() { @@ -153,14 +147,14 @@ public static Result ConvertFrom(ProcessLogonTransactionRespo { TypeNameHandling = TypeNameHandling.All }) - }); + }; } - public static Result ConvertFrom(ProcessSaleTransactionResponse processSaleTransactionResponse) + public static SerialisedMessage ConvertFrom(ProcessSaleTransactionResponse processSaleTransactionResponse) { if (processSaleTransactionResponse == null) { - return Result.Invalid("processSaleTransactionResponse cannot be null"); + return null; } SaleTransactionResponse saleTransactionResponse = new SaleTransactionResponse @@ -173,7 +167,7 @@ public static Result ConvertFrom(ProcessSaleTransactionRespon TransactionId = processSaleTransactionResponse.TransactionId }; - return Result.Success(new SerialisedMessage + return new SerialisedMessage { Metadata = new Dictionary() { @@ -184,14 +178,14 @@ public static Result ConvertFrom(ProcessSaleTransactionRespon { TypeNameHandling = TypeNameHandling.All }) - }); + }; } - public static Result ConvertFrom(ProcessReconciliationTransactionResponse processReconciliationTransactionResponse) + public static SerialisedMessage ConvertFrom(ProcessReconciliationTransactionResponse processReconciliationTransactionResponse) { if (processReconciliationTransactionResponse == null) { - return Result.Invalid("processReconciliationTransactionResponse cannot be null"); + return null; } ReconciliationResponse reconciliationTransactionResponse = new ReconciliationResponse @@ -203,7 +197,7 @@ public static Result ConvertFrom(ProcessReconciliationTransac TransactionId = processReconciliationTransactionResponse.TransactionId }; - return Result.Success(new SerialisedMessage + return new SerialisedMessage { Metadata = new Dictionary() { @@ -214,7 +208,7 @@ public static Result ConvertFrom(ProcessReconciliationTransac { TypeNameHandling = TypeNameHandling.All }) - }); + }; } public static IssueVoucherResponse ConvertFrom(Models.IssueVoucherResponse issueVoucherResponse) @@ -234,11 +228,11 @@ public static IssueVoucherResponse ConvertFrom(Models.IssueVoucherResponse issue return response; } - public static Result ConvertFrom(Voucher voucherModel) + public static GetVoucherResponse ConvertFrom(Voucher voucherModel) { if (voucherModel == null) { - return Result.Invalid("voucherModel cannot be null"); + return null; } GetVoucherResponse response = new GetVoucherResponse @@ -257,13 +251,13 @@ public static Result ConvertFrom(Voucher voucherModel) VoucherId = voucherModel.VoucherId }; - return Result.Success(response); + return response; } - public static Result ConvertFrom(Models.RedeemVoucherResponse redeemVoucherResponse) + public static RedeemVoucherResponse ConvertFrom(Models.RedeemVoucherResponse redeemVoucherResponse) { if (redeemVoucherResponse == null) { - return Result.Invalid("redeemVoucherResponse cannot be null"); + return null; } RedeemVoucherResponse response = new RedeemVoucherResponse @@ -273,23 +267,23 @@ public static Result ConvertFrom(Models.RedeemVoucherResp RemainingBalance = redeemVoucherResponse.RemainingBalance }; - return Result.Success(response); + return response; } - public static Result> ConvertFrom(List estates) + public static List ConvertFrom(List estates) { - List> result = new(); + List> result = new(); estates.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); if (result.Any(c => c.IsFailed)) - return Result.Failure("Failed converting estates"); + return new List(); - return Result.Success(result.Select(r => r.Data).ToList()); + return result.Select(r => r.Data).ToList(); } - public static Result> ConvertFrom(List transactionFees) + public static List ConvertFrom(List transactionFees) { List result = new(); transactionFees.ForEach(tf => { @@ -305,22 +299,19 @@ public static Result ConvertFrom(Models.RedeemVoucherResp result.Add(transactionFee); }); - return Result.Success(result); + return result; } - public static Result> ConvertFrom(List merchants) + public static List ConvertFrom(List merchants) { List> result = new(); if (merchants == null) - return Result.Success(new List()); + return new List(); merchants.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); - - if (result.Any(c => c.IsFailed)) - return Result.Failure("Failed converting merchants"); - - return Result.Success(result.Select(r => r.Data).ToList()); + + return result.Select(r => r.Data).ToList(); } private static TransactionProcessor.DataTransferObjects.Responses.Merchant.SettlementSchedule ConvertFrom(Models.Merchant.SettlementSchedule settlementSchedule) @@ -334,11 +325,10 @@ private static TransactionProcessor.DataTransferObjects.Responses.Merchant.Settl }; } - public static Result ConvertFrom(Estate estate) + public static DataTransferObjects.Responses.Estate.EstateResponse ConvertFrom(Estate estate) { - if (estate == null) - { - return Result.Invalid("estate cannot be null"); + if (estate == null) { + return null; } DataTransferObjects.Responses.Estate.EstateResponse estateResponse = new() @@ -372,7 +362,7 @@ private static TransactionProcessor.DataTransferObjects.Responses.Merchant.Settl })); } - return Result.Success(estateResponse); + return estateResponse; } #endregion @@ -464,15 +454,13 @@ private static List ConvertFrom(List ConvertFrom(Models.Merchant.Merchant merchant) + public static MerchantResponse ConvertFrom(Models.Merchant.Merchant merchant) { - if (merchant == null) - { - return Result.Invalid("merchant cannot be null"); + if (merchant == null) { + return null; } - MerchantResponse merchantResponse = new MerchantResponse - { + MerchantResponse merchantResponse = new() { EstateId = merchant.EstateId, EstateReportingId = merchant.EstateReportingId, MerchantId = merchant.MerchantId, From 608338b52906e32eae1c706fd7f28e383fb3b19f Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Fri, 14 Nov 2025 18:23:38 +0000 Subject: [PATCH 04/29] :| --- .../Factories/ModelFactoryTests.cs | 185 +++++++----------- .../Factories/ModelFactory.cs | 49 +++-- 2 files changed, 98 insertions(+), 136 deletions(-) diff --git a/TransactionProcessor.Tests/Factories/ModelFactoryTests.cs b/TransactionProcessor.Tests/Factories/ModelFactoryTests.cs index 3f9fa80b..edb92859 100644 --- a/TransactionProcessor.Tests/Factories/ModelFactoryTests.cs +++ b/TransactionProcessor.Tests/Factories/ModelFactoryTests.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using SimpleResults; using TransactionProcessor.Aggregates; using TransactionProcessor.DataTransferObjects.Responses.Contract; using TransactionProcessor.DataTransferObjects.Responses.Estate; @@ -32,9 +31,8 @@ public void ModelFactory_Contract_ContractOnly_IsConverted() { Contract contractModel = TestData.ContractModel; - Result result= ModelFactory.ConvertFrom(contractModel); - result.IsSuccess.ShouldBeTrue(); - ContractResponse contractResponse= result.Data; + ContractResponse contractResponse = ModelFactory.ConvertFrom(contractModel); + contractResponse.ShouldNotBeNull(); contractResponse.OperatorId.ShouldBe(contractModel.OperatorId); contractResponse.OperatorName.ShouldBe(contractModel.OperatorName); @@ -48,9 +46,8 @@ public void ModelFactory_Contract_ContractWithProducts_IsConverted() { Contract contractModel = TestData.ContractModelWithProducts; - Result result = ModelFactory.ConvertFrom(contractModel); - result.IsSuccess.ShouldBeTrue(); - ContractResponse contractResponse = result.Data; + ContractResponse contractResponse = ModelFactory.ConvertFrom(contractModel); + contractResponse.ShouldNotBeNull(); contractResponse.OperatorId.ShouldBe(contractModel.OperatorId); contractResponse.ContractId.ShouldBe(contractModel.ContractId); @@ -74,11 +71,10 @@ public void ModelFactory_EstateList_IsConverted() { List estateModel = [TestData.EstateModel]; - Result> estateResponse = ModelFactory.ConvertFrom(estateModel); - estateResponse.IsSuccess.ShouldBeTrue(); - estateResponse.Data.Count.ShouldBe(1); - estateResponse.Data.Single().EstateId.ShouldBe(TestData.EstateModel.EstateId); - estateResponse.Data.Single().EstateName.ShouldBe(TestData.EstateModel.Name); + List estateResponse = ModelFactory.ConvertFrom(estateModel); + estateResponse.Count.ShouldBe(1); + estateResponse.Single().EstateId.ShouldBe(TestData.EstateModel.EstateId); + estateResponse.Single().EstateName.ShouldBe(TestData.EstateModel.Name); } [Fact] @@ -86,8 +82,8 @@ public void ModelFactory_EstateList_NullModelInList_IsConverted() { List estateModel = [null]; - Result> estateResponse = ModelFactory.ConvertFrom(estateModel); - estateResponse.IsFailed.ShouldBeTrue(); + List estateResponse = ModelFactory.ConvertFrom(estateModel); + estateResponse.ShouldBeEmpty(); } [Fact] @@ -97,9 +93,7 @@ public void ModelFactory_MerchantList_IsConverted() TestData.MerchantModelWithAddressesContactsDevicesAndOperatorsAndContracts() }; - Result> merchantResponseListResult = ModelFactory.ConvertFrom(merchantModelList); - merchantResponseListResult.IsSuccess.ShouldBeTrue(); - List merchantResponseList = merchantResponseListResult.Data; + List merchantResponseList = ModelFactory.ConvertFrom(merchantModelList); merchantResponseList.ShouldNotBeNull(); merchantResponseList.ShouldNotBeEmpty(); merchantResponseList.Count.ShouldBe(merchantModelList.Count); @@ -109,9 +103,7 @@ public void ModelFactory_MerchantList_IsConverted() public void ModelFactory_MerchantList_NullList_IsConverted() { List merchantModelList = null; - Result> merchantResponseListResult = ModelFactory.ConvertFrom(merchantModelList); - merchantResponseListResult.IsSuccess.ShouldBeTrue(); - List merchantResponseList = merchantResponseListResult.Data; + List merchantResponseList = ModelFactory.ConvertFrom(merchantModelList); merchantResponseList.ShouldNotBeNull(); merchantResponseList.ShouldBeEmpty(); } @@ -123,8 +115,8 @@ public void ModelFactory_MerchantList_NullModelInList_IsConverted() null }; - Result> result = ModelFactory.ConvertFrom(merchantModelList); - result.IsFailed.ShouldBeTrue(); + List result = ModelFactory.ConvertFrom(merchantModelList); + result.ShouldBeEmpty(); } [Fact] @@ -132,9 +124,7 @@ public void ModelFactory_Contract_ContractWithProductsAndFees_IsConverted() { Contract contractModel = TestData.ContractModelWithProductsAndTransactionFees; - Result result = ModelFactory.ConvertFrom(contractModel); - result.IsSuccess.ShouldBeTrue(); - ContractResponse contractResponse = result.Data; + ContractResponse contractResponse = ModelFactory.ConvertFrom(contractModel); contractResponse.ShouldNotBeNull(); contractResponse.OperatorId.ShouldBe(contractModel.OperatorId); @@ -170,14 +160,13 @@ public void ModelFactory_ContractList_IsConverted() TestData.ContractModel }; - Result> contractResponses = ModelFactory.ConvertFrom(contractModel); - contractResponses.IsSuccess.ShouldBeTrue(); - contractResponses.Data.ShouldNotBeNull(); - contractResponses.Data.ShouldHaveSingleItem(); - contractResponses.Data.Single().OperatorId.ShouldBe(contractModel.Single().OperatorId); - contractResponses.Data.Single().ContractId.ShouldBe(contractModel.Single().ContractId); - contractResponses.Data.Single().Description.ShouldBe(contractModel.Single().Description); - contractResponses.Data.Single().Products.ShouldBeNull(); + List contractResponses = ModelFactory.ConvertFrom(contractModel); + contractResponses.ShouldNotBeNull(); + contractResponses.ShouldHaveSingleItem(); + contractResponses.Single().OperatorId.ShouldBe(contractModel.Single().OperatorId); + contractResponses.Single().ContractId.ShouldBe(contractModel.Single().ContractId); + contractResponses.Single().Description.ShouldBe(contractModel.Single().Description); + contractResponses.Single().Products.ShouldBeNull(); } [Fact] @@ -187,8 +176,8 @@ public void ModelFactory_ContractList_ModelInListIsNull_IsConverted() null }; - Result> contractResponses = ModelFactory.ConvertFrom(contractModel); - contractResponses.IsFailed.ShouldBeTrue(); + var contractResponses = ModelFactory.ConvertFrom(contractModel); + contractResponses.Any().ShouldBeFalse(); } [Fact] @@ -196,9 +185,7 @@ public void ModelFactory_ProcessLogonTransactionResponseModel_IsConverted() { ProcessLogonTransactionResponse processLogonTransactionResponseModel = TestData.ProcessLogonTransactionResponseModel; - Result logonTransactionResult = ModelFactory.ConvertFrom(processLogonTransactionResponseModel); - logonTransactionResult.IsSuccess.ShouldBeTrue(); - SerialisedMessage logonTransactionResponse = logonTransactionResult.Data; + SerialisedMessage logonTransactionResponse = ModelFactory.ConvertFrom(processLogonTransactionResponseModel); logonTransactionResponse.ShouldNotBeNull(); logonTransactionResponse.Metadata.ShouldContainKey(MetadataContants.KeyNameEstateId); logonTransactionResponse.Metadata.ShouldContainKey(MetadataContants.KeyNameMerchantId); @@ -213,9 +200,8 @@ public void ModelFactory_ProcessLogonTransactionResponseModel_NullInput_IsConver { ProcessLogonTransactionResponse processLogonTransactionResponseModel = null; - Result logonTransactionResult = ModelFactory.ConvertFrom(processLogonTransactionResponseModel); - logonTransactionResult.IsFailed.ShouldBeTrue(); - logonTransactionResult.Status.ShouldBe(ResultStatus.Invalid); + SerialisedMessage logonTransactionResult = ModelFactory.ConvertFrom(processLogonTransactionResponseModel); + logonTransactionResult.ShouldBeNull(); } [Fact] @@ -223,9 +209,7 @@ public void ModelFactory_ProcessSaleTransactionResponseModel_IsConverted() { ProcessSaleTransactionResponse processSaleTransactionResponseModel = TestData.ProcessSaleTransactionResponseModel; - Result saleTransactionResult = ModelFactory.ConvertFrom(processSaleTransactionResponseModel); - saleTransactionResult.IsSuccess.ShouldBeTrue(); - SerialisedMessage saleTransactionResponse = saleTransactionResult.Data; + SerialisedMessage saleTransactionResponse = ModelFactory.ConvertFrom(processSaleTransactionResponseModel); saleTransactionResponse.ShouldNotBeNull(); saleTransactionResponse.Metadata.ShouldContainKey(MetadataContants.KeyNameEstateId); @@ -241,9 +225,8 @@ public void ModelFactory_ProcessSaleTransactionResponseModel_NullInput_IsConvert { ProcessSaleTransactionResponse processSaleTransactionResponseModel = null; - Result saleTransactionResult = ModelFactory.ConvertFrom(processSaleTransactionResponseModel); - saleTransactionResult.IsFailed.ShouldBeTrue(); - saleTransactionResult.Status.ShouldBe(ResultStatus.Invalid); + SerialisedMessage saleTransactionResult = ModelFactory.ConvertFrom(processSaleTransactionResponseModel); + saleTransactionResult.ShouldBeNull(); } [Fact] @@ -251,9 +234,7 @@ public void ModelFactory_ProcessReconciliationTransactionResponse_IsConverted() { ProcessReconciliationTransactionResponse processReconciliationTransactionResponseModel = TestData.ProcessReconciliationTransactionResponseModel; - Result reconciliationTransactionResult = ModelFactory.ConvertFrom(processReconciliationTransactionResponseModel); - reconciliationTransactionResult.IsSuccess.ShouldBeTrue(); - SerialisedMessage processReconciliationTransactionResponse = reconciliationTransactionResult.Data; + SerialisedMessage processReconciliationTransactionResponse = ModelFactory.ConvertFrom(processReconciliationTransactionResponseModel); processReconciliationTransactionResponse.ShouldNotBeNull(); processReconciliationTransactionResponse.Metadata.ShouldContainKey(MetadataContants.KeyNameEstateId); @@ -269,9 +250,8 @@ public void ModelFactory_ProcessReconciliationTransactionResponse_NullInput_IsCo { ProcessReconciliationTransactionResponse processReconciliationTransactionResponseModel = null; - Result reconciliationTransactionResult = ModelFactory.ConvertFrom(processReconciliationTransactionResponseModel); - reconciliationTransactionResult.IsFailed.ShouldBeTrue(); - reconciliationTransactionResult.Status.ShouldBe(ResultStatus.Invalid); + SerialisedMessage reconciliationTransactionResult = ModelFactory.ConvertFrom(processReconciliationTransactionResponseModel); + reconciliationTransactionResult.ShouldBeNull(); } [Fact] @@ -301,9 +281,7 @@ public void ModelFactory_ConvertFrom_VoucherModel_IsConverted() { Voucher model = TestData.GetVoucherAggregateWithRecipientMobile().GetVoucher(); - Result result = ModelFactory.ConvertFrom(model); - result.IsSuccess.ShouldBeTrue(); - GetVoucherResponse dto =result.Data; + GetVoucherResponse dto = ModelFactory.ConvertFrom(model); dto.ShouldNotBeNull(); dto.TransactionId.ShouldBe(model.TransactionId); dto.IssuedDateTime.ShouldBe(model.IssuedDateTime); @@ -324,19 +302,17 @@ public void ModelFactory_ConvertFrom_VoucherModel_IsConverted() public void ModelFactory_ConvertFrom_VoucherModel_NullInput_IsConverted() { Voucher model = null; - Result result = ModelFactory.ConvertFrom(model); + GetVoucherResponse result = ModelFactory.ConvertFrom(model); - result.IsFailed.ShouldBeTrue(); - result.Status.ShouldBe(ResultStatus.Invalid); + result.ShouldBeNull(); } [Fact] public void ModelFactory_ConvertFrom_RedeemVoucherResponse_IsConverted() { RedeemVoucherResponse model = TestData.RedeemVoucherResponse; - Result result = ModelFactory.ConvertFrom(model); - result.IsSuccess.ShouldBeTrue(); - DataTransferObjects.RedeemVoucherResponse dto = result.Data; + + DataTransferObjects.RedeemVoucherResponse dto = ModelFactory.ConvertFrom(model); dto.ShouldNotBeNull(); dto.ExpiryDate.ShouldBe(model.ExpiryDate); dto.VoucherCode.ShouldBe(model.VoucherCode); @@ -347,17 +323,14 @@ public void ModelFactory_ConvertFrom_RedeemVoucherResponse_IsConverted() public void ModelFactory_ConvertFrom_RedeemVoucherResponse_NullInput_IsConverted() { RedeemVoucherResponse model = null; - Result result = ModelFactory.ConvertFrom(model); - result.IsFailed.ShouldBeTrue(); - result.Status.ShouldBe(ResultStatus.Invalid); + DataTransferObjects.RedeemVoucherResponse result = ModelFactory.ConvertFrom(model); + result.ShouldBeNull(); } [Fact] public void ModelFactory_ConvertFrom_Operator_ModelConverted() { - Result result = ModelFactory.ConvertFrom(TestData.OperatorModel); - result.IsSuccess.ShouldBeTrue(); - OperatorResponse operatorResponse = result.Data; + OperatorResponse operatorResponse = ModelFactory.ConvertFrom(TestData.OperatorModel); operatorResponse.ShouldNotBeNull(); operatorResponse.OperatorId.ShouldBe(TestData.OperatorId); operatorResponse.RequireCustomTerminalNumber.ShouldBe(TestData.RequireCustomTerminalNumber); @@ -370,9 +343,8 @@ public void ModelFactory_ConvertFrom_OperatorModelIsNull_ModelConverted() { TransactionProcessor.Models.Operator.Operator operatorModel = null; - Result operatorResponseResult = ModelFactory.ConvertFrom(operatorModel); - operatorResponseResult.IsFailed.ShouldBeTrue(); - operatorResponseResult.Status.ShouldBe(ResultStatus.Invalid); + OperatorResponse operatorResponseResult = ModelFactory.ConvertFrom(operatorModel); + operatorResponseResult.ShouldBeNull(); } [Fact] @@ -382,9 +354,7 @@ public void ModelFactory_ConvertFrom_OperatorList_ModelConverted() TestData.OperatorModel }; - Result> operatorResponseResult = ModelFactory.ConvertFrom(operatorList); - operatorResponseResult.IsSuccess.ShouldBeTrue(); - List operatorResponses = operatorResponseResult.Data; + List operatorResponses = ModelFactory.ConvertFrom(operatorList); operatorResponses.ShouldNotBeNull(); operatorResponses.ShouldNotBeEmpty(); operatorResponses.Count.ShouldBe(operatorList.Count); @@ -404,9 +374,8 @@ public void ModelFactory_ConvertFrom_NullOperatorList_ModelConverted() { List operatorList = null; - Result> operatorResponseResult = ModelFactory.ConvertFrom(operatorList); - operatorResponseResult.IsSuccess.ShouldBeTrue(); - operatorResponseResult.Data.ShouldBeEmpty(); + List operatorResponse = ModelFactory.ConvertFrom(operatorList); + operatorResponse.ShouldBeEmpty(); } @@ -415,9 +384,8 @@ public void ModelFactory_ConvertFrom_EmptyOperatorList_ModelConverted() { List operatorList = new List(); - Result> operatorResponseResult = ModelFactory.ConvertFrom(operatorList); - operatorResponseResult.IsSuccess.ShouldBeTrue(); - operatorResponseResult.Data.ShouldBeEmpty(); + List operatorResponse = ModelFactory.ConvertFrom(operatorList); + operatorResponse.ShouldBeEmpty(); } @@ -428,8 +396,8 @@ public void ModelFactory_ConvertFrom_NullModelInList_ModelConverted() null }; - Result> result = ModelFactory.ConvertFrom(operatorList); - result.IsFailed.ShouldBeTrue(); + List result = ModelFactory.ConvertFrom(operatorList); + result.ShouldBeEmpty(); } @@ -438,10 +406,9 @@ public void ModelFactory_Estate_NullInput_IsConverted() { Estate estateModel = null; - Result estateResponseResult = ModelFactory.ConvertFrom(estateModel); + EstateResponse estateResponseResult = ModelFactory.ConvertFrom(estateModel); - estateResponseResult.IsFailed.ShouldBeTrue(); - estateResponseResult.Status.ShouldBe(ResultStatus.Invalid); + estateResponseResult.ShouldBeNull(); } [Fact] @@ -449,9 +416,7 @@ public void ModelFactory_Estate_WithNoOperatorsOrSecurityUsers_IsConverted() { Estate estateModel = TestData.EstateModel; - Result result = ModelFactory.ConvertFrom(estateModel); - result.IsSuccess.ShouldBeTrue(); - EstateResponse estateResponse= result.Data; + EstateResponse estateResponse= ModelFactory.ConvertFrom(estateModel); estateResponse.ShouldNotBeNull(); estateResponse.EstateId.ShouldBe(estateModel.EstateId); estateResponse.EstateName.ShouldBe(estateModel.Name); @@ -462,9 +427,8 @@ public void ModelFactory_Estate_WithOperators_IsConverted() { Estate estateModel = TestData.EstateModelWithOperators; - Result result = ModelFactory.ConvertFrom(estateModel); - result.IsSuccess.ShouldBeTrue(); - EstateResponse estateResponse = result.Data; + + EstateResponse estateResponse = ModelFactory.ConvertFrom(estateModel); estateResponse.ShouldNotBeNull(); estateResponse.EstateId.ShouldBe(estateModel.EstateId); estateResponse.EstateName.ShouldBe(estateModel.Name); @@ -477,10 +441,8 @@ public void ModelFactory_Estate_WithOperators_IsConverted() public void ModelFactory_Estate_WithSecurityUsers_IsConverted() { Estate estateModel = TestData.EstateModelWithSecurityUsers; - - Result result = ModelFactory.ConvertFrom(estateModel); - result.IsSuccess.ShouldBeTrue(); - EstateResponse estateResponse = result.Data; + + EstateResponse estateResponse = ModelFactory.ConvertFrom(estateModel); estateResponse.ShouldNotBeNull(); estateResponse.EstateId.ShouldBe(estateModel.EstateId); estateResponse.EstateName.ShouldBe(estateModel.Name); @@ -494,9 +456,7 @@ public void ModelFactory_Estate_WithOperatorsAndSecurityUsers_IsConverted() { Estate estateModel = TestData.EstateModelWithOperatorsAndSecurityUsers; - Result result = ModelFactory.ConvertFrom(estateModel); - result.IsSuccess.ShouldBeTrue(); - EstateResponse estateResponse = result.Data; + EstateResponse estateResponse = ModelFactory.ConvertFrom(estateModel); estateResponse.ShouldNotBeNull(); estateResponse.EstateId.ShouldBe(estateModel.EstateId); estateResponse.EstateName.ShouldBe(estateModel.Name); @@ -515,9 +475,7 @@ public void ModelFactory_Merchant_IsConverted(Models.Merchant.SettlementSchedule { Merchant merchantModel = TestData.MerchantModelWithAddressesContactsDevicesAndOperatorsAndContracts(settlementSchedule); - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsSuccess.ShouldBeTrue(); - MerchantResponse merchantResponse = result.Data; + MerchantResponse merchantResponse = ModelFactory.ConvertFrom(merchantModel); merchantResponse.ShouldNotBeNull(); merchantResponse.MerchantId.ShouldBe(merchantModel.MerchantId); merchantResponse.MerchantName.ShouldBe(merchantModel.MerchantName); @@ -547,9 +505,8 @@ public void ModelFactory_Merchant_NullInput_IsConverted() { Merchant merchantModel = null; - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsFailed.ShouldBeTrue(); - result.Status.ShouldBe(ResultStatus.Invalid); + MerchantResponse result = ModelFactory.ConvertFrom(merchantModel); + result.ShouldBeNull(); } [Fact] @@ -557,9 +514,7 @@ public void ModelFactory_Merchant_NullAddresses_IsConverted() { Merchant merchantModel = TestData.MerchantModelWithNullAddresses; - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsSuccess.ShouldBeTrue(); - MerchantResponse merchantResponse = result.Data; + MerchantResponse merchantResponse = ModelFactory.ConvertFrom(merchantModel); merchantResponse.ShouldNotBeNull(); merchantResponse.MerchantId.ShouldBe(merchantModel.MerchantId); @@ -592,9 +547,7 @@ public void ModelFactory_Merchant_NullContacts_IsConverted() { Merchant merchantModel = TestData.MerchantModelWithNullContacts; - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsSuccess.ShouldBeTrue(); - MerchantResponse merchantResponse = result.Data; + MerchantResponse merchantResponse = ModelFactory.ConvertFrom(merchantModel); merchantResponse.ShouldNotBeNull(); merchantResponse.MerchantId.ShouldBe(merchantModel.MerchantId); @@ -632,9 +585,7 @@ public void ModelFactory_Merchant_NullDevices_IsConverted() { Merchant merchantModel = TestData.MerchantModelWithNullDevices; - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsSuccess.ShouldBeTrue(); - MerchantResponse merchantResponse = result.Data; + MerchantResponse merchantResponse = ModelFactory.ConvertFrom(merchantModel); merchantResponse.ShouldNotBeNull(); merchantResponse.MerchantId.ShouldBe(merchantModel.MerchantId); @@ -674,9 +625,7 @@ public void ModelFactory_Merchant_NullOperators_IsConverted() { Merchant merchantModel = TestData.MerchantModelWithNullOperators; - Result result = ModelFactory.ConvertFrom(merchantModel); - result.IsSuccess.ShouldBeTrue(); - MerchantResponse merchantResponse = result.Data; + MerchantResponse merchantResponse = ModelFactory.ConvertFrom(merchantModel); merchantResponse.ShouldNotBeNull(); merchantResponse.MerchantId.ShouldBe(merchantModel.MerchantId); @@ -714,9 +663,7 @@ public void ModelFactory_TransactionFeeList_IsConverted() { List transactionFeeModelList = TestData.ProductTransactionFees; - Result> result = ModelFactory.ConvertFrom(transactionFeeModelList); - result.IsSuccess.ShouldBeTrue(); - List transactionFeeResponseList = result.Data; + List transactionFeeResponseList = ModelFactory.ConvertFrom(transactionFeeModelList); transactionFeeResponseList.ShouldNotBeNull(); transactionFeeResponseList.ShouldNotBeEmpty(); transactionFeeResponseList.Count.ShouldBe(transactionFeeModelList.Count); diff --git a/TransactionProcessor/Factories/ModelFactory.cs b/TransactionProcessor/Factories/ModelFactory.cs index 5cf2add2..aaacfabc 100644 --- a/TransactionProcessor/Factories/ModelFactory.cs +++ b/TransactionProcessor/Factories/ModelFactory.cs @@ -28,11 +28,16 @@ public static class ModelFactory #region Methods public static List ConvertFrom(List contracts) { - List> result = new(); + List result = new(); - contracts.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); - - return result.Select(r => r.Data).ToList(); + contracts.ForEach(c => { + ContractResponse converted = ModelFactory.ConvertFrom(c); + if (converted != null) { + result.Add(converted); + } + }); + + return result; } public static ContractResponse ConvertFrom(Models.Contract.Contract contract) @@ -112,12 +117,17 @@ public static List ConvertFrom(List return new List(); } - List> result = new(); + List result = new(); - @operators.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); + @operators.ForEach(c => { + var converted = ModelFactory.ConvertFrom(c); + if (converted != null) { + result.Add(converted); + } + }); - return result.Select(r => r.Data).ToList(); + return result.ToList(); } public static SerialisedMessage ConvertFrom(ProcessLogonTransactionResponse processLogonTransactionResponse) @@ -272,14 +282,15 @@ public static RedeemVoucherResponse ConvertFrom(Models.RedeemVoucherResponse red public static List ConvertFrom(List estates) { - List> result = new(); - - estates.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); - - if (result.Any(c => c.IsFailed)) - return new List(); + List result = new(); + + estates.ForEach(c => { + var converted = ModelFactory.ConvertFrom(c); + if (converted != null) + result.Add(converted); + }); - return result.Select(r => r.Data).ToList(); + return result.ToList(); } @@ -304,14 +315,18 @@ public static List ConvertFrom(List estates) public static List ConvertFrom(List merchants) { - List> result = new(); + List result = new(); if (merchants == null) return new List(); - merchants.ForEach(c => result.Add(ModelFactory.ConvertFrom(c))); + merchants.ForEach(c => { + MerchantResponse converted = ModelFactory.ConvertFrom(c); + if (converted!= null) + result.Add(converted); + }); - return result.Select(r => r.Data).ToList(); + return result; } private static TransactionProcessor.DataTransferObjects.Responses.Merchant.SettlementSchedule ConvertFrom(Models.Merchant.SettlementSchedule settlementSchedule) From f3c0b96cf929df5ce47bc4bc6a660a0b40c11e4e Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 19:39:22 +0000 Subject: [PATCH 05/29] ... --- .../SettlementResponse.cs | 13 +++++++++---- .../AssemblyInfo.cs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/TransactionProcessor.DataTransferObjects/SettlementResponse.cs b/TransactionProcessor.DataTransferObjects/SettlementResponse.cs index 39649988..71c1e592 100644 --- a/TransactionProcessor.DataTransferObjects/SettlementResponse.cs +++ b/TransactionProcessor.DataTransferObjects/SettlementResponse.cs @@ -1,4 +1,6 @@ -namespace TransactionProcessor.DataTransferObjects +using Newtonsoft.Json; + +namespace TransactionProcessor.DataTransferObjects { using System; using System.Diagnostics.CodeAnalysis; @@ -6,16 +8,19 @@ [ExcludeFromCodeCoverage] public class SettlementResponse { + [JsonProperty("estate_id")] public Guid EstateId { get; set; } - + [JsonProperty("merchant_id")] public Guid MerchantId { get; set; } + [JsonProperty("settlement_date")] public DateTime SettlementDate { get; set; } + [JsonProperty("number_of_fees_pending_settlement")] public Int32 NumberOfFeesPendingSettlement { get; set; } - + [JsonProperty("number_of_fees_settled")] public Int32 NumberOfFeesSettled { get; set; } - + [JsonProperty("settlement_completed")] public Boolean SettlementCompleted { get; set; } } } \ No newline at end of file diff --git a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs index 186aeecb..7f2a15ed 100644 --- a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs +++ b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs @@ -16,5 +16,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("25d4d6fc-b809-4acc-a910-249a03e5f07a")] -[assembly: LevelOfParallelism(2)] +[assembly: LevelOfParallelism(1)] [assembly: Parallelizable(ParallelScope.Fixtures)] \ No newline at end of file From 2c39f22fab4913839be73925e1c90da474d1624e Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 20:17:47 +0000 Subject: [PATCH 06/29] :| --- TransactionProcessor.IntegrationTests/Common/Setup.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index 42c88b4b..fbdc0b4c 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -20,6 +20,8 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); + ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(1); dockerHelper.SqlCredentials = Setup.SqlCredentials; dockerHelper.DockerCredentials = Setup.DockerCredentials; From 73dac7d2897ea1b43c83a518d26e529c416ae5b5 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 20:31:32 +0000 Subject: [PATCH 07/29] :| --- .github/workflows/pullrequest.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a28dd538..a0ec4b21 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -40,6 +40,9 @@ jobs: run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest - name: Run Integration Tests + env: + FLUENTDOCKER_DOCKER_USE_SUDO: "false" + FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest --logger "trx;LogFileName=test-results.trx" - uses: actions/upload-artifact@v4.4.0 From f2f2dfb3ba00edba4aba6e658e34c596cf3dbf67 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 20:43:46 +0000 Subject: [PATCH 08/29] :| --- .../TransactionProcessor.IntegrationTests.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index cd39ce7c..a643185b 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -8,7 +8,8 @@ - + + From 7b3a4a0413dd0810c3d159cc862d39653f9c173a Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 20:51:12 +0000 Subject: [PATCH 09/29] :| --- .../TransactionProcessor.DatabaseTests.csproj | 4 ++-- .../TransactionProcessor.IntegrationTesting.Helpers.csproj | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj index 61cd5782..034bfc24 100644 --- a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj +++ b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj @@ -13,7 +13,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + @@ -21,7 +22,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj index 226b62a6..90a43ebd 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj +++ b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj @@ -8,7 +8,8 @@ - + + From 836b2f934c8dd45dbfea613b1fa3c428c6613841 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 21:43:22 +0000 Subject: [PATCH 10/29] :| --- .github/workflows/pullrequest.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a0ec4b21..883567fd 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -16,6 +16,12 @@ jobs: steps: - uses: actions/checkout@v2.3.4 + - name: Disable sudo (FluentDocker fix) + run: | + echo '#!/bin/bash' | sudo tee /usr/local/bin/sudo > /dev/null + echo 'exec "$@"' | sudo tee -a /usr/local/bin/sudo > /dev/null + sudo chmod +x /usr/local/bin/sudo + - name: Install NET 9 uses: actions/setup-dotnet@v4.0.1 with: From e3aab76fcc1b35f8fc2d95625ccc707471876c77 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 15 Nov 2025 22:04:43 +0000 Subject: [PATCH 11/29] :| --- .github/workflows/pullrequest.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 883567fd..80e38973 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -46,10 +46,10 @@ jobs: run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest - name: Run Integration Tests - env: - FLUENTDOCKER_DOCKER_USE_SUDO: "false" - FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" - run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest --logger "trx;LogFileName=test-results.trx" + run: + FLUENTDOCKER_DOCKER_USE_SUDO=false \ + FLUENTDOCKER_DOCKER_PATH=/usr/bin/docker \ + dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest --logger "trx;LogFileName=test-results.trx" - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} From 15212cb1b0da94016c54af6fa7608bb7a10ab1c3 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 13:28:58 +0000 Subject: [PATCH 12/29] :| --- .github/workflows/pullrequest.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 80e38973..40268078 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -16,12 +16,6 @@ jobs: steps: - uses: actions/checkout@v2.3.4 - - name: Disable sudo (FluentDocker fix) - run: | - echo '#!/bin/bash' | sudo tee /usr/local/bin/sudo > /dev/null - echo 'exec "$@"' | sudo tee -a /usr/local/bin/sudo > /dev/null - sudo chmod +x /usr/local/bin/sudo - - name: Install NET 9 uses: actions/setup-dotnet@v4.0.1 with: @@ -45,11 +39,22 @@ 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 --logger "trx;LogFileName=test-results.trx" + + - name: Ensure Docker is running + run: | + sudo systemctl restart docker + sleep 3 + docker ps + - name: Run Integration Tests - run: - FLUENTDOCKER_DOCKER_USE_SUDO=false \ - FLUENTDOCKER_DOCKER_PATH=/usr/bin/docker \ - dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest --logger "trx;LogFileName=test-results.trx" + env: + FLUENTDOCKER_DOCKER_USE_SUDO: "false" + FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" + run: | + dotnet test "TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest " - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} From 726fe8f7ce01a01f9eb3d9a2635f084bf1769a3f Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 13:44:00 +0000 Subject: [PATCH 13/29] oops --- .github/workflows/pullrequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 40268078..82fd5977 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -54,7 +54,7 @@ jobs: FLUENTDOCKER_DOCKER_USE_SUDO: "false" FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" run: | - dotnet test "TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest " + dotnet test "TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj --filter Category=PRTest" - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} From d69e0f62fd2724f2d22628132ec012e4a09e5b63 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 14:02:32 +0000 Subject: [PATCH 14/29] :| --- .github/workflows/pullrequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 82fd5977..3a9f6d1c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -54,7 +54,7 @@ jobs: FLUENTDOCKER_DOCKER_USE_SUDO: "false" FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" run: | - dotnet test "TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj --filter Category=PRTest" + dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj --filter Category=PRTest" - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} From 683c50260e1d6491ff6bc94bd49c67bd50295394 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 14:11:16 +0000 Subject: [PATCH 15/29] .. --- .github/workflows/pullrequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3a9f6d1c..f2af8d12 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -54,7 +54,7 @@ jobs: FLUENTDOCKER_DOCKER_USE_SUDO: "false" FLUENTDOCKER_DOCKER_PATH: "/usr/bin/docker" run: | - dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj --filter Category=PRTest" + dotnet test "TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} From d0374d579ead04f89aa41a958d3ac11db91ba04b Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 15:32:12 +0000 Subject: [PATCH 16/29] :| --- TransactionProcessor.IntegrationTests/Common/Setup.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index fbdc0b4c..dfea870f 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -11,6 +11,11 @@ namespace TransactionProcessor.IntegrationTests.Common [Binding] public class Setup { + static Setup() { + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); + } + public static IContainerService DatabaseServerContainer; public static INetworkService DatabaseServerNetwork; public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!"); @@ -20,8 +25,6 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); - ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(1); dockerHelper.SqlCredentials = Setup.SqlCredentials; dockerHelper.DockerCredentials = Setup.DockerCredentials; From ce9fb8bc6f5226f06c630b7ee618791db9d38520 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 16:03:16 +0000 Subject: [PATCH 17/29] :| --- TransactionProcessor.IntegrationTests/Common/GenericSteps.cs | 3 +++ TransactionProcessor.IntegrationTests/Common/Setup.cs | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs index b00f94af..d840f140 100644 --- a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs @@ -26,6 +26,9 @@ public GenericSteps(ScenarioContext scenarioContext, [BeforeScenario] public async Task StartSystem() { + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); + // Initialise a logger String scenarioName = this.ScenarioContext.ScenarioInfo.Title.Replace(" ", ""); NlogLogger logger = new NlogLogger(); diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index dfea870f..42c88b4b 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -11,11 +11,6 @@ namespace TransactionProcessor.IntegrationTests.Common [Binding] public class Setup { - static Setup() { - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); - } - public static IContainerService DatabaseServerContainer; public static INetworkService DatabaseServerNetwork; public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!"); From 96cc1eea66a3799eefb2ef944f3922e5c03acf9c Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 19:06:36 +0000 Subject: [PATCH 18/29] :| --- .../Common/GenericSteps.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs index d840f140..726dfb67 100644 --- a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs @@ -8,6 +8,15 @@ namespace TransactionProcessor.IntegrationTests.Common using NLog; using Reqnroll; + public class Test{ + [BeforeTestRun] + public static async Task BeforeTestRun() + { + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); + Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); + } + } + [Binding] [Scope(Tag = "base")] public class GenericSteps @@ -26,9 +35,6 @@ public GenericSteps(ScenarioContext scenarioContext, [BeforeScenario] public async Task StartSystem() { - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); - // Initialise a logger String scenarioName = this.ScenarioContext.ScenarioInfo.Title.Replace(" ", ""); NlogLogger logger = new NlogLogger(); From 3bd7a8d078ee5fb2cb44a9a6ffe1b073f2cc8fd1 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 22:11:53 +0000 Subject: [PATCH 19/29] :| --- TransactionProcessor.IntegrationTests/Common/Setup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index 42c88b4b..e2ac6f7c 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -20,7 +20,7 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { - ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(1); + ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(5); dockerHelper.SqlCredentials = Setup.SqlCredentials; dockerHelper.DockerCredentials = Setup.DockerCredentials; dockerHelper.SqlServerContainerName = "sharedsqlserver"; From f4ad7570576bf2f702af86434b544b76cf2b2f9f Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sun, 16 Nov 2025 22:25:23 +0000 Subject: [PATCH 20/29] :| --- .github/workflows/pullrequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index f2af8d12..463b121d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -11,7 +11,7 @@ jobs: env: ASPNETCORE_ENVIRONMENT: "Production" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2.3.4 From 4ce24d8f88fca0778137443972c71eaf5dd7c3c2 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 06:49:29 +0000 Subject: [PATCH 21/29] :| --- TransactionProcessor.IntegrationTests/Common/Setup.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index e2ac6f7c..e8075109 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -2,11 +2,12 @@ namespace TransactionProcessor.IntegrationTests.Common { - using System.Threading.Tasks; using Ductus.FluentDocker.Services; using Ductus.FluentDocker.Services.Extensions; + using global::Shared.IntegrationTesting; using Reqnroll; using Shouldly; + using System.Threading.Tasks; [Binding] public class Setup @@ -20,6 +21,8 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { + dockerHelper.SetImageDetails(ContainerType.SqlServer, ("mcr.microsoft.com/mssql/server:2022-latest", false)); + ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(5); dockerHelper.SqlCredentials = Setup.SqlCredentials; dockerHelper.DockerCredentials = Setup.DockerCredentials; From 42462f1096098e713ed7cfeb1f64bcb67373daf5 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 06:57:17 +0000 Subject: [PATCH 22/29] :| --- TransactionProcessor.IntegrationTests/Common/Setup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index e8075109..8627d047 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -21,7 +21,7 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { - dockerHelper.SetImageDetails(ContainerType.SqlServer, ("mcr.microsoft.com/mssql/server:2022-latest", false)); + dockerHelper.SetImageDetails(ContainerType.SqlServer, ("mcr.microsoft.com/mssql/server:2019-latest", false)); ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(5); dockerHelper.SqlCredentials = Setup.SqlCredentials; From 420ca492b8b7b2f357ffde7f6054f17a4def5900 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 15:04:29 +0000 Subject: [PATCH 23/29] I wonder :| --- TransactionProcessor.IntegrationTests/AssemblyInfo.cs | 2 +- .../Common/DockerHelper.cs | 4 ++-- .../Common/GenericSteps.cs | 11 +---------- TransactionProcessor.IntegrationTests/Common/Setup.cs | 2 -- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs index 7f2a15ed..fdb40b94 100644 --- a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs +++ b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs @@ -16,5 +16,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("25d4d6fc-b809-4acc-a910-249a03e5f07a")] -[assembly: LevelOfParallelism(1)] +[assembly: LevelOfParallelism(3)] [assembly: Parallelizable(ParallelScope.Fixtures)] \ No newline at end of file diff --git a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs index cc73ccc6..8a7f6799 100644 --- a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs +++ b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs @@ -1,4 +1,5 @@ -using TransactionProcessor.Database.Contexts; +using Syncfusion.Pdf.Xmp; +using TransactionProcessor.Database.Contexts; namespace TransactionProcessor.IntegrationTests.Common { @@ -164,7 +165,6 @@ public override ContainerBuilder SetupSecurityServiceContainer() /// /// Name of the scenario. public override async Task StartContainersForScenarioRun(String scenarioName, DockerServices dockerServices){ - await base.StartContainersForScenarioRun(scenarioName, dockerServices); // Setup the base address resolvers diff --git a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs index 726dfb67..f06bca6d 100644 --- a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs @@ -8,15 +8,6 @@ namespace TransactionProcessor.IntegrationTests.Common using NLog; using Reqnroll; - public class Test{ - [BeforeTestRun] - public static async Task BeforeTestRun() - { - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_USE_SUDO", "false"); - Environment.SetEnvironmentVariable("FLUENTDOCKER_DOCKER_PATH", "/usr/bin/docker"); - } - } - [Binding] [Scope(Tag = "base")] public class GenericSteps @@ -60,7 +51,7 @@ public async Task StartSystem() this.TestingContext.DockerHelper.SqlCredentials = Setup.SqlCredentials; this.TestingContext.DockerHelper.SqlServerContainerName = "sharedsqlserver"; - this.TestingContext.DockerHelper.SetImageDetails(ContainerType.TransactionProcessor, ("transactionprocessor", false)); + //this.TestingContext.DockerHelper.SetImageDetails(ContainerType.TransactionProcessor, ("transactionprocessor", false)); this.TestingContext.Logger = logger; this.TestingContext.Logger.LogInformation("About to Start Containers for Scenario Run"); diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index 8627d047..e8c98d7b 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -21,8 +21,6 @@ public class Setup public static async Task GlobalSetup(DockerHelper dockerHelper) { - dockerHelper.SetImageDetails(ContainerType.SqlServer, ("mcr.microsoft.com/mssql/server:2019-latest", false)); - ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(5); dockerHelper.SqlCredentials = Setup.SqlCredentials; dockerHelper.DockerCredentials = Setup.DockerCredentials; From b5ae59861240cda8bfb1e18101fa88b500c42143 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 15:52:21 +0000 Subject: [PATCH 24/29] :| --- TransactionProcessor.IntegrationTests/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs index fdb40b94..4a480469 100644 --- a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs +++ b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs @@ -16,5 +16,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("25d4d6fc-b809-4acc-a910-249a03e5f07a")] -[assembly: LevelOfParallelism(3)] +[assembly: LevelOfParallelism(5)] [assembly: Parallelizable(ParallelScope.Fixtures)] \ No newline at end of file From 367c36e8b34cfe7cfc2416d210283c4deca699a8 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 16:10:03 +0000 Subject: [PATCH 25/29] :| --- TransactionProcessor.IntegrationTests/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs index 4a480469..f7669db4 100644 --- a/TransactionProcessor.IntegrationTests/AssemblyInfo.cs +++ b/TransactionProcessor.IntegrationTests/AssemblyInfo.cs @@ -16,5 +16,5 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("25d4d6fc-b809-4acc-a910-249a03e5f07a")] -[assembly: LevelOfParallelism(5)] +[assembly: LevelOfParallelism(8)] [assembly: Parallelizable(ParallelScope.Fixtures)] \ No newline at end of file From 9bbd31f27b0ec7e0e6cc8f3d6eb6150a8e27a91f Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 17 Nov 2025 16:47:38 +0000 Subject: [PATCH 26/29] :| --- .../Common/Setup.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index e8c98d7b..b10ea6dd 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -7,6 +7,7 @@ namespace TransactionProcessor.IntegrationTests.Common using global::Shared.IntegrationTesting; using Reqnroll; using Shouldly; + using System.Threading; using System.Threading.Tasks; [Binding] @@ -17,7 +18,7 @@ public class Setup public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!"); public static (String url, String username, String password) DockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland"); - static object padLock = new object(); // Object to lock on + private static readonly SemaphoreSlim _setupLock = new SemaphoreSlim(1, 1); public static async Task GlobalSetup(DockerHelper dockerHelper) { @@ -26,12 +27,18 @@ public static async Task GlobalSetup(DockerHelper dockerHelper) dockerHelper.DockerCredentials = Setup.DockerCredentials; dockerHelper.SqlServerContainerName = "sharedsqlserver"; - lock (Setup.padLock) + await _setupLock.WaitAsync(); + try { Setup.DatabaseServerNetwork = dockerHelper.SetupTestNetwork("sharednetwork"); dockerHelper.Logger.LogInformation("in start SetupSqlServerContainer"); - Setup.DatabaseServerContainer = dockerHelper.SetupSqlServerContainer(Setup.DatabaseServerNetwork).Result; + Setup.DatabaseServerContainer = + await dockerHelper.SetupSqlServerContainer(Setup.DatabaseServerNetwork); + } + finally + { + _setupLock.Release(); } } From 6b1757a1d0c8379b926a719d3bfedef07281bc88 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Fri, 21 Nov 2025 20:23:36 +0000 Subject: [PATCH 27/29] last chance --- .../TransactionProcessor.Aggregates.csproj | 2 +- .../TransactionProcessor.BusinessLogic.csproj | 6 +- .../TransactionProcessor.Client.csproj | 4 +- .../TransactionProcessor.Database.csproj | 4 +- .../BaseTest.cs | 1 + .../TransactionProcessor.DatabaseTests.csproj | 2 +- .../TransactionProcessor.DomainEvents.csproj | 2 +- ...rocessor.IntegrationTesting.Helpers.csproj | 4 +- .../Common/DockerHelper.cs | 134 +++++++++--------- .../Common/GenericSteps.cs | 8 +- .../Common/Setup.cs | 32 ----- ...ansactionProcessor.IntegrationTests.csproj | 4 +- ...ansactionProcessor.ProjectionEngine.csproj | 4 +- .../TransactionProcessor.Repository.csproj | 4 +- .../TransactionProcessor.Testing.csproj | 2 +- .../TransactionProcessor.Tests.csproj | 2 +- .../TransactionProcessor.csproj | 8 +- 17 files changed, 95 insertions(+), 128 deletions(-) diff --git a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj index 3c8a621f..8d10c00c 100644 --- a/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj +++ b/TransactionProcessor.Aggregates/TransactionProcessor.Aggregates.csproj @@ -8,7 +8,7 @@ - + diff --git a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj index c41fc4f9..cdc9fe2d 100644 --- a/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj +++ b/TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj @@ -6,15 +6,15 @@ - + - - + + diff --git a/TransactionProcessor.Client/TransactionProcessor.Client.csproj b/TransactionProcessor.Client/TransactionProcessor.Client.csproj index e2a39716..afb7698a 100644 --- a/TransactionProcessor.Client/TransactionProcessor.Client.csproj +++ b/TransactionProcessor.Client/TransactionProcessor.Client.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/TransactionProcessor.Database/TransactionProcessor.Database.csproj b/TransactionProcessor.Database/TransactionProcessor.Database.csproj index 7de7d287..0fd2cd9b 100644 --- a/TransactionProcessor.Database/TransactionProcessor.Database.csproj +++ b/TransactionProcessor.Database/TransactionProcessor.Database.csproj @@ -18,9 +18,9 @@ - + - + diff --git a/TransactionProcessor.DatabaseTests/BaseTest.cs b/TransactionProcessor.DatabaseTests/BaseTest.cs index ed6ca128..56b9cb45 100644 --- a/TransactionProcessor.DatabaseTests/BaseTest.cs +++ b/TransactionProcessor.DatabaseTests/BaseTest.cs @@ -17,6 +17,7 @@ using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; +using Shared.IntegrationTesting.Ductus; using TransactionProcessor.Database.Contexts; using TransactionProcessor.Repository; using Xunit.Abstractions; diff --git a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj index 034bfc24..0cb3f2a1 100644 --- a/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj +++ b/TransactionProcessor.DatabaseTests/TransactionProcessor.DatabaseTests.csproj @@ -22,7 +22,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj b/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj index 8fc0839e..a2ecf987 100644 --- a/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj +++ b/TransactionProcessor.DomainEvents/TransactionProcessor.DomainEvents.csproj @@ -6,6 +6,6 @@ enable - + diff --git a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj index 90a43ebd..936c0ce2 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj +++ b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessor.IntegrationTesting.Helpers.csproj @@ -7,12 +7,12 @@ - + - + diff --git a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs index 8a7f6799..911b0116 100644 --- a/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs +++ b/TransactionProcessor.IntegrationTests/Common/DockerHelper.cs @@ -1,4 +1,5 @@ -using Syncfusion.Pdf.Xmp; +using DotNet.Testcontainers.Builders; +using Syncfusion.Pdf.Xmp; using TransactionProcessor.Database.Contexts; namespace TransactionProcessor.IntegrationTests.Common @@ -10,7 +11,6 @@ namespace TransactionProcessor.IntegrationTests.Common using System.Threading; using System.Threading.Tasks; using Client; - using Ductus.FluentDocker.Builders; using EventStore.Client; using global::Shared.IntegrationTesting; using Newtonsoft.Json; @@ -22,7 +22,7 @@ namespace TransactionProcessor.IntegrationTests.Common /// /// /// - public class DockerHelper : global::Shared.IntegrationTesting.DockerHelper + public class DockerHelper : global::Shared.IntegrationTesting.TestContainers.DockerHelper { #region Fields public static String TestBankAccountNumber = "12345678"; @@ -92,7 +92,7 @@ public override ContainerBuilder SetupTransactionProcessorContainer(){ List variables = new List(); variables.Add($"OperatorConfiguration:PataPawaPrePay:Url=http://{this.TestHostContainerName}:{DockerPorts.TestHostPort}/api/patapawaprepay"); - this.AdditionalVariables.Add(ContainerType.FileProcessor, variables); + //this.AdditionalVariables.Add(ContainerType.FileProcessor, variables); //this.SetAdditionalVariables(ContainerType.FileProcessor, variables); return base.SetupTransactionProcessorContainer(); @@ -110,55 +110,55 @@ public override async Task CreateSubscriptions(){ } } - public override ContainerBuilder SetupSecurityServiceContainer() - { - this.Trace("About to Start Security Container"); - - List environmentVariables = this.GetCommonEnvironmentVariables(); - environmentVariables.Add($"ServiceOptions:PublicOrigin=https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}"); - environmentVariables.Add($"ServiceOptions:IssuerUrl=https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}"); - //environmentVariables.Add("ASPNETCORE_ENVIRONMENT=IntegrationTest"); - environmentVariables.Add($"urls=https://*:{DockerPorts.SecurityServiceDockerPort}"); - - environmentVariables.Add("ServiceOptions:PasswordOptions:RequiredLength=6"); - environmentVariables.Add("ServiceOptions:PasswordOptions:RequireDigit=false"); - environmentVariables.Add("ServiceOptions:PasswordOptions:RequireUpperCase=false"); - environmentVariables.Add("ServiceOptions:UserOptions:RequireUniqueEmail=false"); - environmentVariables.Add("ServiceOptions:SignInOptions:RequireConfirmedEmail=false"); - - environmentVariables.Add(this.SetConnectionString("ConnectionStrings:PersistedGrantDbContext", $"PersistedGrantStore-{this.TestId}", this.UseSecureSqlServerDatabase)); - environmentVariables.Add(this.SetConnectionString("ConnectionStrings:ConfigurationDbContext", $"Configuration-{this.TestId}", this.UseSecureSqlServerDatabase)); - environmentVariables.Add(this.SetConnectionString("ConnectionStrings:AuthenticationDbContext", $"Authentication-{this.TestId}", this.UseSecureSqlServerDatabase)); - - List additionalEnvironmentVariables = this.GetAdditionalVariables(ContainerType.SecurityService); - - if (additionalEnvironmentVariables != null) - { - environmentVariables.AddRange(additionalEnvironmentVariables); - } - - var imageDetails = this.GetImageDetails(ContainerType.SecurityService); - if (imageDetails.IsFailed) - throw new Exception(imageDetails.Message); - ContainerBuilder securityServiceContainer = new Builder().UseContainer().WithName(this.SecurityServiceContainerName) - .WithEnvironment(environmentVariables.ToArray()) - .UseImageDetails(imageDetails.Data) - .MountHostFolder(this.DockerPlatform, this.HostTraceFolder) - .SetDockerCredentials(this.DockerCredentials); - - Int32? hostPort = this.GetHostPort(ContainerType.SecurityService); - if (hostPort == null) - { - securityServiceContainer = securityServiceContainer.ExposePort(DockerPorts.SecurityServiceDockerPort); - } - else - { - securityServiceContainer = securityServiceContainer.ExposePort(hostPort.Value, DockerPorts.SecurityServiceDockerPort); - } - - // Now build and return the container - return securityServiceContainer; - } + //public override ContainerBuilder SetupSecurityServiceContainer() + //{ + // this.Trace("About to Start Security Container"); + + // List environmentVariables = this.GetCommonEnvironmentVariables(); + // environmentVariables.Add($"ServiceOptions:PublicOrigin=https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}"); + // environmentVariables.Add($"ServiceOptions:IssuerUrl=https://{this.SecurityServiceContainerName}:{DockerPorts.SecurityServiceDockerPort}"); + // //environmentVariables.Add("ASPNETCORE_ENVIRONMENT=IntegrationTest"); + // environmentVariables.Add($"urls=https://*:{DockerPorts.SecurityServiceDockerPort}"); + + // environmentVariables.Add("ServiceOptions:PasswordOptions:RequiredLength=6"); + // environmentVariables.Add("ServiceOptions:PasswordOptions:RequireDigit=false"); + // environmentVariables.Add("ServiceOptions:PasswordOptions:RequireUpperCase=false"); + // environmentVariables.Add("ServiceOptions:UserOptions:RequireUniqueEmail=false"); + // environmentVariables.Add("ServiceOptions:SignInOptions:RequireConfirmedEmail=false"); + + // environmentVariables.Add(this.SetConnectionString("ConnectionStrings:PersistedGrantDbContext", $"PersistedGrantStore-{this.TestId}", this.UseSecureSqlServerDatabase)); + // environmentVariables.Add(this.SetConnectionString("ConnectionStrings:ConfigurationDbContext", $"Configuration-{this.TestId}", this.UseSecureSqlServerDatabase)); + // environmentVariables.Add(this.SetConnectionString("ConnectionStrings:AuthenticationDbContext", $"Authentication-{this.TestId}", this.UseSecureSqlServerDatabase)); + + // List additionalEnvironmentVariables = this.GetAdditionalVariables(ContainerType.SecurityService); + + // if (additionalEnvironmentVariables != null) + // { + // environmentVariables.AddRange(additionalEnvironmentVariables); + // } + + // var imageDetails = this.GetImageDetails(ContainerType.SecurityService); + // if (imageDetails.IsFailed) + // throw new Exception(imageDetails.Message); + // ContainerBuilder securityServiceContainer = new Builder().UseContainer().WithName(this.SecurityServiceContainerName) + // .WithEnvironment(environmentVariables.ToArray()) + // .UseImageDetails(imageDetails.Data) + // .MountHostFolder(this.DockerPlatform, this.HostTraceFolder) + // .SetDockerCredentials(this.DockerCredentials); + + // Int32? hostPort = this.GetHostPort(ContainerType.SecurityService); + // if (hostPort == null) + // { + // securityServiceContainer = securityServiceContainer.ExposePort(DockerPorts.SecurityServiceDockerPort); + // } + // else + // { + // securityServiceContainer = securityServiceContainer.ExposePort(hostPort.Value, DockerPorts.SecurityServiceDockerPort); + // } + + // // Now build and return the container + // return securityServiceContainer; + //} /// /// Starts the containers for scenario run. @@ -207,20 +207,20 @@ public override async Task StopContainersForScenarioRun(DockerServices dockerSer private async Task RemoveEstateReadModel() { - List estateIdList = this.TestingContext.GetAllEstateIds(); - - foreach (Guid estateId in estateIdList) - { - String databaseName = $"EstateReportingReadModel{estateId}"; - - await Retry.For(async () => - { - // Build the connection string (to master) - String connectionString = Setup.GetLocalConnectionString(databaseName); - EstateManagementContext context = new EstateManagementContext(connectionString); - await context.Database.EnsureDeletedAsync(CancellationToken.None); - }); - } + //List estateIdList = this.TestingContext.GetAllEstateIds(); + + //foreach (Guid estateId in estateIdList) + //{ + // String databaseName = $"EstateReportingReadModel{estateId}"; + + // await Retry.For(async () => + // { + // // Build the connection string (to master) + // String connectionString = Setup.GetLocalConnectionString(databaseName); + // EstateManagementContext context = new EstateManagementContext(connectionString); + // await context.Database.EnsureDeletedAsync(CancellationToken.None); + // }); + //} } protected override List GetRequiredProjections() diff --git a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs index f06bca6d..8d4eca29 100644 --- a/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs +++ b/TransactionProcessor.IntegrationTests/Common/GenericSteps.cs @@ -32,7 +32,7 @@ public async Task StartSystem() logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName); LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly); - DockerServices dockerServices = DockerServices.CallbackHandler | DockerServices.EventStore | + DockerServices dockerServices = DockerServices.SqlServer | DockerServices.CallbackHandler | DockerServices.EventStore | DockerServices.FileProcessor | DockerServices.MessagingService | DockerServices.SecurityService | DockerServices.SqlServer | DockerServices.TestHost | DockerServices.TransactionProcessor | DockerServices.TransactionProcessorAcl; @@ -45,13 +45,11 @@ public async Task StartSystem() await Setup.GlobalSetup(this.TestingContext.DockerHelper); - this.TestingContext.DockerHelper.SqlServerContainer = Setup.DatabaseServerContainer; - this.TestingContext.DockerHelper.SqlServerNetwork = Setup.DatabaseServerNetwork; this.TestingContext.DockerHelper.DockerCredentials = Setup.DockerCredentials; this.TestingContext.DockerHelper.SqlCredentials = Setup.SqlCredentials; this.TestingContext.DockerHelper.SqlServerContainerName = "sharedsqlserver"; - //this.TestingContext.DockerHelper.SetImageDetails(ContainerType.TransactionProcessor, ("transactionprocessor", false)); + this.TestingContext.DockerHelper.SetImageDetails(ContainerType.TransactionProcessor, ("transactionprocessor", false)); this.TestingContext.Logger = logger; this.TestingContext.Logger.LogInformation("About to Start Containers for Scenario Run"); @@ -62,7 +60,7 @@ public async Task StartSystem() [AfterScenario] public async Task StopSystem(){ - DockerServices sharedDockerServices = DockerServices.SqlServer; + DockerServices sharedDockerServices = DockerServices.None; this.TestingContext.Logger.LogInformation("About to Stop Containers for Scenario Run"); await this.TestingContext.DockerHelper.StopContainersForScenarioRun(sharedDockerServices).ConfigureAwait(false); diff --git a/TransactionProcessor.IntegrationTests/Common/Setup.cs b/TransactionProcessor.IntegrationTests/Common/Setup.cs index b10ea6dd..edfff8dc 100644 --- a/TransactionProcessor.IntegrationTests/Common/Setup.cs +++ b/TransactionProcessor.IntegrationTests/Common/Setup.cs @@ -13,46 +13,14 @@ namespace TransactionProcessor.IntegrationTests.Common [Binding] public class Setup { - public static IContainerService DatabaseServerContainer; - public static INetworkService DatabaseServerNetwork; public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!"); public static (String url, String username, String password) DockerCredentials = ("https://www.docker.com", "stuartferguson", "Sc0tland"); - private static readonly SemaphoreSlim _setupLock = new SemaphoreSlim(1, 1); - public static async Task GlobalSetup(DockerHelper dockerHelper) { ShouldlyConfiguration.DefaultTaskTimeout = TimeSpan.FromMinutes(5); - dockerHelper.SqlCredentials = Setup.SqlCredentials; - dockerHelper.DockerCredentials = Setup.DockerCredentials; - dockerHelper.SqlServerContainerName = "sharedsqlserver"; - - await _setupLock.WaitAsync(); - try - { - Setup.DatabaseServerNetwork = dockerHelper.SetupTestNetwork("sharednetwork"); - - dockerHelper.Logger.LogInformation("in start SetupSqlServerContainer"); - Setup.DatabaseServerContainer = - await dockerHelper.SetupSqlServerContainer(Setup.DatabaseServerNetwork); - } - finally - { - _setupLock.Release(); - } } - public static String GetConnectionString(String databaseName) - { - return $"server={Setup.DatabaseServerContainer.Name};database={databaseName};user id={Setup.SqlCredentials.usename};password={Setup.SqlCredentials.password}"; - } - - public static String GetLocalConnectionString(String databaseName) - { - Int32 databaseHostPort = Setup.DatabaseServerContainer.ToHostExposedEndpoint("1433/tcp").Port; - - return $"server=localhost,{databaseHostPort};database={databaseName};user id={Setup.SqlCredentials.usename};password={Setup.SqlCredentials.password}"; - } } } diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj index a643185b..9ee157ba 100644 --- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj +++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj @@ -7,7 +7,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj index 72e3fed9..f0f712f8 100644 --- a/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj +++ b/TransactionProcessor.ProjectionEngine/TransactionProcessor.ProjectionEngine.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj index c95f6df0..95ee6e97 100644 --- a/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj +++ b/TransactionProcessor.Repository/TransactionProcessor.Repository.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj index 898712aa..12bfff05 100644 --- a/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj +++ b/TransactionProcessor.Testing/TransactionProcessor.Testing.csproj @@ -6,7 +6,7 @@ - + diff --git a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj index 127c9da7..5b2decee 100644 --- a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj +++ b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/TransactionProcessor/TransactionProcessor.csproj b/TransactionProcessor/TransactionProcessor.csproj index c617afe2..94d7d5a4 100644 --- a/TransactionProcessor/TransactionProcessor.csproj +++ b/TransactionProcessor/TransactionProcessor.csproj @@ -10,7 +10,7 @@ - + @@ -34,10 +34,10 @@ - - + + - + From 5214355d7210117c19747bf41e3c552f1a5dcb87 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 22 Nov 2025 18:04:45 +0000 Subject: [PATCH 28/29] Update JSON keys and voucher validation logic Updated `JsonProperty` attributes in `AddressResponse.cs` to use camelCase naming conventions for consistency. Refactored voucher validation in `TransactionProcessorSteps.cs`: - Commented out `RedeemVoucherResponse` validation logic. - Introduced `GetVoucherByCode` method to validate voucher balance, aligning with updated business logic or API behavior. --- .../Responses/Merchant/AddressResponse.cs | 8 ++++---- .../TransactionProcessorSteps.cs | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/TransactionProcessor.DataTransferObjects/Responses/Merchant/AddressResponse.cs b/TransactionProcessor.DataTransferObjects/Responses/Merchant/AddressResponse.cs index 7a1cc17a..18744f2a 100644 --- a/TransactionProcessor.DataTransferObjects/Responses/Merchant/AddressResponse.cs +++ b/TransactionProcessor.DataTransferObjects/Responses/Merchant/AddressResponse.cs @@ -24,7 +24,7 @@ public class AddressResponse /// /// The address line1. /// - [JsonProperty("address_line_1")] + [JsonProperty("address_line1")] public String AddressLine1 { get; set; } /// @@ -33,7 +33,7 @@ public class AddressResponse /// /// The address line2. /// - [JsonProperty("address_line_2")] + [JsonProperty("address_line2")] public String AddressLine2 { get; set; } /// @@ -42,7 +42,7 @@ public class AddressResponse /// /// The address line3. /// - [JsonProperty("address_line_3")] + [JsonProperty("address_line3")] public String AddressLine3 { get; set; } /// @@ -51,7 +51,7 @@ public class AddressResponse /// /// The address line4. /// - [JsonProperty("address_line_4")] + [JsonProperty("address_line4")] public String AddressLine4 { get; set; } /// diff --git a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessorSteps.cs b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessorSteps.cs index a0bd6e3e..bd1d2338 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessorSteps.cs +++ b/TransactionProcessor.IntegrationTesting.Helpers/TransactionProcessorSteps.cs @@ -456,9 +456,13 @@ await Retry.For(async () => .RedeemVoucher(accessToken, redeemVoucherRequest, CancellationToken.None) .ConfigureAwait(false); redeemVoucherResult.IsSuccess.ShouldBeTrue(); - RedeemVoucherResponse response = redeemVoucherResult.Data; - response.ShouldNotBeNull(); - response.RemainingBalance.ShouldBe(expectedBalance); + //RedeemVoucherResponse response = redeemVoucherResult.Data; + //response.ShouldNotBeNull(); + //response.RemainingBalance.ShouldBe(expectedBalance); + + var x = await this.TransactionProcessorClient.GetVoucherByCode(accessToken, estate.EstateId, voucher.VoucherCode, CancellationToken.None); + x.IsSuccess.ShouldBeTrue(); + x.Data.Balance.ShouldBe(expectedBalance); }); } From 6169be0352745a21efbebce5ef248479e4eda214 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Sat, 22 Nov 2025 21:09:14 +0000 Subject: [PATCH 29/29] remove rouge file --- workload-install.ps1 | 332 ------------------------------------------- 1 file changed, 332 deletions(-) delete mode 100644 workload-install.ps1 diff --git a/workload-install.ps1 b/workload-install.ps1 deleted file mode 100644 index 271841b6..00000000 --- a/workload-install.ps1 +++ /dev/null @@ -1,332 +0,0 @@ -# -# Copyright (c) Samsung Electronics. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -<# -.SYNOPSIS -Installs Tizen workload manifest. -.DESCRIPTION -Installs the WorkloadManifest.json and WorkloadManifest.targets files for Tizen to the dotnet sdk. -.PARAMETER Version -Use specific VERSION -.PARAMETER DotnetInstallDir -Dotnet SDK Location installed -#> - -[cmdletbinding()] -param( - [Alias('v')][string]$Version="", - [Alias('d')][string]$DotnetInstallDir="", - [Alias('t')][string]$DotnetTargetVersionBand="", - [Alias('u')][switch]$UpdateAllWorkloads -) - -Set-StrictMode -Version Latest -$ErrorActionPreference = "Stop" -$ProgressPreference = "SilentlyContinue" - -$ManifestBaseName = "Samsung.NET.Sdk.Tizen.Manifest" -$global:FallbackId = "" - -$LatestVersionMap = [ordered]@{ - "$ManifestBaseName-6.0.100" = "7.0.101"; - "$ManifestBaseName-6.0.200" = "7.0.100-preview.13.6"; - "$ManifestBaseName-6.0.300" = "8.0.133"; - "$ManifestBaseName-6.0.400" = "9.0.104"; - "$ManifestBaseName-7.0.100-preview.6" = "7.0.100-preview.6.14"; - "$ManifestBaseName-7.0.100-preview.7" = "7.0.100-preview.7.20"; - "$ManifestBaseName-7.0.100-rc.1" = "7.0.100-rc.1.22"; - "$ManifestBaseName-7.0.100-rc.2" = "7.0.100-rc.2.24"; - "$ManifestBaseName-7.0.100" = "7.0.103"; - "$ManifestBaseName-7.0.200" = "7.0.105"; - "$ManifestBaseName-7.0.300" = "7.0.120"; - "$ManifestBaseName-7.0.400" = "10.0.106"; - "$ManifestBaseName-8.0.100-alpha.1" = "7.0.104"; - "$ManifestBaseName-8.0.100-preview.2" = "7.0.106"; - "$ManifestBaseName-8.0.100-preview.3" = "7.0.107"; - "$ManifestBaseName-8.0.100-preview.4" = "7.0.108"; - "$ManifestBaseName-8.0.100-preview.5" = "7.0.110"; - "$ManifestBaseName-8.0.100-preview.6" = "7.0.121"; - "$ManifestBaseName-8.0.100-preview.7" = "7.0.122"; - "$ManifestBaseName-8.0.100-rc.1" = "7.0.124"; - "$ManifestBaseName-8.0.100-rc.2" = "7.0.125"; - "$ManifestBaseName-8.0.100-rtm" = "7.0.127"; - "$ManifestBaseName-8.0.100" = "8.0.144"; - "$ManifestBaseName-8.0.200" = "8.0.157"; - "$ManifestBaseName-8.0.300" = "8.0.156"; - "$ManifestBaseName-8.0.400" = "10.0.109"; - "$ManifestBaseName-9.0.100-alpha.1" = "8.0.134"; - "$ManifestBaseName-9.0.100-preview.1" = "8.0.135"; - "$ManifestBaseName-9.0.100-preview.2" = "8.0.137"; - "$ManifestBaseName-9.0.100" = "10.0.104"; - "$ManifestBaseName-9.0.200" = "10.0.110"; - "$ManifestBaseName-9.0.300" = "10.0.111"; -} - -function New-TemporaryDirectory { - $parent = [System.IO.Path]::GetTempPath() - $name = [System.IO.Path]::GetRandomFileName() - New-Item -ItemType Directory -Path (Join-Path $parent $name) -} - -function Ensure-Directory([string]$TestDir) { - Try { - New-Item -ItemType Directory -Path $TestDir -Force -ErrorAction stop | Out-Null - [io.file]::OpenWrite($(Join-Path -Path $TestDir -ChildPath ".test-write-access")).Close() - Remove-Item -Path $(Join-Path -Path $TestDir -ChildPath ".test-write-access") -Force - } - Catch [System.UnauthorizedAccessException] { - Write-Error "No permission to install. Try run with administrator mode." - } -} - -function Get-LatestVersion([string]$Id) { - $attempts=3 - $sleepInSeconds=3 - do - { - try - { - $Response = Invoke-WebRequest -Uri https://api.nuget.org/v3-flatcontainer/$($Id.ToLowerInvariant())/index.json -UseBasicParsing | ConvertFrom-Json - return $Response.versions | Select-Object -Last 1 - } - catch { - Write-Host "Id: $Id" - Write-Host "An exception was caught: $($_.Exception.Message)" - } - - $attempts-- - if ($attempts -gt 0) { Start-Sleep $sleepInSeconds } - } while ($attempts -gt 0) - - if ($LatestVersionMap.Contains($Id)) - { - Write-Host "Return cached latest version." - return $LatestVersionMap.$Id - } - else - { - $SubStringId = $Id.Substring(0, $ManifestBaseName.Length + 2); - $MatchingFallbackId = @() - $MatchingFallbackVersion = @() - foreach ($key in $LatestVersionMap.Keys) { - if ($key -like "$SubStringId*") { - $MatchingFallbackId += $key - $MatchingFallbackVersion += $LatestVersionMap[$key] - } - } - if ($MatchingFallbackVersion) - { - $global:FallbackId = $MatchingFallbackId[-1] - $FallbackVersion = $MatchingFallbackVersion[-1] - Write-Host "Return fallback version: $FallbackVersion" - return $FallbackVersion - } - } - - Write-Error "Wrong Id: $Id" -} - -function Get-Package([string]$Id, [string]$Version, [string]$Destination, [string]$FileExt = "nupkg") { - $OutFileName = "$Id.$Version.$FileExt" - $OutFilePath = Join-Path -Path $Destination -ChildPath $OutFileName - - if ($Id -match ".net[0-9]+$") { - $Id = $Id -replace (".net[0-9]+", "") - } - - Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/$Id/$Version" -OutFile $OutFilePath - - return $OutFilePath -} - -function Install-Pack([string]$Id, [string]$Version, [string]$Kind) { - $TempZipFile = $(Get-Package -Id $Id -Version $Version -Destination $TempDir -FileExt "zip") - $TempUnzipDir = Join-Path -Path $TempDir -ChildPath "unzipped\$Id" - - switch ($Kind) { - "manifest" { - Expand-Archive -Path $TempZipFile -DestinationPath $TempUnzipDir - New-Item -Path $TizenManifestDir -ItemType "directory" -Force | Out-Null - Copy-Item -Path "$TempUnzipDir\data\*" -Destination $TizenManifestDir -Force - } - {($_ -eq "sdk") -or ($_ -eq "framework")} { - Expand-Archive -Path $TempZipFile -DestinationPath $TempUnzipDir - if ( ($kind -eq "sdk") -and ($Id -match ".net[0-9]+$")) { - $Id = $Id -replace (".net[0-9]+", "") - } - $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "packs\$Id\$Version") - New-Item -Path $TargetDirectory -ItemType "directory" -Force | Out-Null - Copy-Item -Path "$TempUnzipDir/*" -Destination $TargetDirectory -Recurse -Force - } - "template" { - $TargetFileName = "$Id.$Version.nupkg".ToLower() - $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "template-packs") - New-Item -Path $TargetDirectory -ItemType "directory" -Force | Out-Null - Copy-Item $TempZipFile -Destination $(Join-Path -Path $TargetDirectory -ChildPath "$TargetFileName") -Force - } - } -} - -function Remove-Pack([string]$Id, [string]$Version, [string]$Kind) { - switch ($Kind) { - "manifest" { - Remove-Item -Path $TizenManifestDir -Recurse -Force - } - {($_ -eq "sdk") -or ($_ -eq "framework")} { - $TargetDirectory = $(Join-Path -Path $DotnetInstallDir -ChildPath "packs\$Id\$Version") - Remove-Item -Path $TargetDirectory -Recurse -Force - } - "template" { - $TargetFileName = "$Id.$Version.nupkg".ToLower(); - Remove-Item -Path $(Join-Path -Path $DotnetInstallDir -ChildPath "template-packs\$TargetFileName") -Force - } - } -} - -function Install-TizenWorkload([string]$DotnetVersion) -{ - $VersionSplitSymbol = '.' - $SplitVersion = $DotnetVersion.Split($VersionSplitSymbol) - - $CurrentDotnetVersion = [Version]"$($SplitVersion[0]).$($SplitVersion[1])" - $DotnetVersionBand = $SplitVersion[0] + $VersionSplitSymbol + $SplitVersion[1] + $VersionSplitSymbol + $SplitVersion[2][0] + "00" - $ManifestName = "$ManifestBaseName-$DotnetVersionBand" - - if ($DotnetTargetVersionBand -eq "" -or $UpdateAllWorkloads.IsPresent) { - if ($CurrentDotnetVersion -ge "7.0") - { - $IsPreviewVersion = $DotnetVersion.Contains("-preview") -or $DotnetVersion.Contains("-rc") -or $DotnetVersion.Contains("-alpha") - if ($IsPreviewVersion -and ($SplitVersion.Count -ge 4)) { - $DotnetTargetVersionBand = $DotnetVersionBand + $SplitVersion[2].SubString(3) + $VersionSplitSymbol + $($SplitVersion[3]) - $ManifestName = "$ManifestBaseName-$DotnetTargetVersionBand" - } - elseif ($DotnetVersion.Contains("-rtm") -and ($SplitVersion.Count -ge 3)) { - $DotnetTargetVersionBand = $DotnetVersionBand + $SplitVersion[2].SubString(3) - $ManifestName = "$ManifestBaseName-$DotnetTargetVersionBand" - } - else { - $DotnetTargetVersionBand = $DotnetVersionBand - } - } - else { - $DotnetTargetVersionBand = $DotnetVersionBand - } - } - - # Check latest version of manifest. - if ($Version -eq "" -or $UpdateAllWorkloads.IsPresent) { - $Version = Get-LatestVersion -Id $ManifestName - } - - # Check workload manifest directory. - $ManifestDir = Join-Path -Path $DotnetInstallDir -ChildPath "sdk-manifests" | Join-Path -ChildPath $DotnetTargetVersionBand - $TizenManifestDir = Join-Path -Path $ManifestDir -ChildPath "samsung.net.sdk.tizen" - $TizenManifestFile = Join-Path -Path $TizenManifestDir -ChildPath "WorkloadManifest.json" - - # Check and remove already installed old version. - if (Test-Path $TizenManifestFile) { - $ManifestJson = $(Get-Content $TizenManifestFile | ConvertFrom-Json) - $OldVersion = $ManifestJson.version - if ($OldVersion -eq $Version) { - $DotnetWorkloadList = Invoke-Expression "& '$DotnetCommand' workload list | Select-String -Pattern '^tizen'" - if ($DotnetWorkloadList) - { - Write-Host "Tizen Workload $Version version is already installed." - Continue - } - } - - Ensure-Directory $ManifestDir - Write-Host "Removing $ManifestName/$OldVersion from $ManifestDir..." - Remove-Pack -Id $ManifestName -Version $OldVersion -Kind "manifest" - $ManifestJson.packs.PSObject.Properties | ForEach-Object { - Write-Host "Removing $($_.Name)/$($_.Value.version)..." - Remove-Pack -Id $_.Name -Version $_.Value.version -Kind $_.Value.kind - } - } - - Ensure-Directory $ManifestDir - $TempDir = $(New-TemporaryDirectory) - - # Install workload manifest. - Write-Host "Installing $ManifestName/$Version to $ManifestDir..." - if ($global:FallbackId) { - Install-Pack -Id $global:FallbackId -Version $Version -Kind "manifest" - } else { - Install-Pack -Id $ManifestName -Version $Version -Kind "manifest" - } - - # Download and install workload packs. - $NewManifestJson = $(Get-Content $TizenManifestFile | ConvertFrom-Json) - $NewManifestJson.packs.PSObject.Properties | ForEach-Object { - Write-Host "Installing $($_.Name)/$($_.Value.version)..." - Install-Pack -Id $_.Name -Version $_.Value.version -Kind $_.Value.kind - } - - # Add tizen to the installed workload metadata. - # Featured version band for metadata does NOT include any preview specifier. - # https://github.com/dotnet/sdk/blob/main/documentation/general/workloads/user-local-workloads.md - New-Item -Path $(Join-Path -Path $DotnetInstallDir -ChildPath "metadata\workloads\$DotnetVersionBand\InstalledWorkloads\tizen") -Force | Out-Null - if (Test-Path $(Join-Path -Path $DotnetInstallDir -ChildPath "metadata\workloads\$DotnetVersionBand\InstallerType\msi")) { - New-Item -Path "HKLM:\SOFTWARE\Microsoft\dotnet\InstalledWorkloads\Standalone\x64\$DotnetTargetVersionBand\tizen" -Force | Out-Null - } - - # Clean up - Remove-Item -Path $TempDir -Force -Recurse - - Write-Host "Done installing Tizen workload $Version" -} - -# Check dotnet install directory. -if ($DotnetInstallDir -eq "") { - if ($Env:DOTNET_ROOT -And $(Test-Path "$Env:DOTNET_ROOT")) { - $DotnetInstallDir = $Env:DOTNET_ROOT - } else { - $DotnetInstallDir = Join-Path -Path $Env:Programfiles -ChildPath "dotnet" - } -} -if (-Not $(Test-Path "$DotnetInstallDir")) { - Write-Error "No installed dotnet '$DotnetInstallDir'." -} - -# Check installed dotnet version -$DotnetCommand = "$DotnetInstallDir\dotnet" -if (Get-Command $DotnetCommand -ErrorAction SilentlyContinue) -{ - if ($UpdateAllWorkloads.IsPresent) - { - $InstalledDotnetSdks = Invoke-Expression "& '$DotnetCommand' --list-sdks | Select-String -Pattern '^6|^7'" | ForEach-Object {$_ -replace (" \[.*","")} - } - else - { - $InstalledDotnetSdks = Invoke-Expression "& '$DotnetCommand' --version" - } -} -else -{ - Write-Error "'$DotnetCommand' occurs an error." -} - -if (-Not $InstalledDotnetSdks) -{ - Write-Host "`n.NET SDK version 6 or later is required to install Tizen Workload." -} -else -{ - foreach ($DotnetSdk in $InstalledDotnetSdks) - { - try { - Write-Host "`nCheck Tizen Workload for sdk $DotnetSdk" - Install-TizenWorkload -DotnetVersion $DotnetSdk - } - catch { - Write-Host "Failed to install Tizen Workload for sdk $DotnetSdk" - Write-Host "$_" - Continue - } - } -} - -Write-Host "`nDone"