From ccef9c067a9015793ab1f34f2a2ce4d07292cf98 Mon Sep 17 00:00:00 2001 From: Yami An Date: Sat, 3 Feb 2024 01:15:24 +0700 Subject: [PATCH 1/3] 240203 --- .../appsettings.Development.json | 4 +- .../appsettings.Production.json | 4 +- .../RemoteService/IRemoteService.cs | 11 +++ .../Requests/EcommerceLoginRequest.cs | 8 ++ .../Services/IEcommerceService.cs | 12 +++ .../YANLib.Application.Contracts.csproj | 1 + .../Implements/DeveloperTypeRedisService.cs | 4 +- .../YANLib.Application.Redis.csproj | 1 + .../RemoteService/RemoteService.cs | 77 +++++++++++++++++++ .../Services/EcommerceService.cs | 54 +++++++++++++ .../Validations/EcommerceValidation.cs | 35 +++++++++ .../YANLib.Application.csproj | 1 + .../Localization/YANLib/vi.json | 2 + .../YANLibDomainErrorCodes.cs | 2 + .../YANLibDomainErrorMessages.cs | 2 + src/YANLib.Domain/YANLibConsts.cs | 11 +++ .../Controllers/DeveloperController.cs | 2 +- .../Controllers/DeveloperTypeController.cs | 4 +- .../Controllers/EcommerceController.cs | 39 ++++++++++ .../Controllers/ElasticsearchController.cs | 2 +- .../Controllers/IdSnowflakeController.cs | 2 +- .../Controllers/YANJsonController.cs | 2 +- 22 files changed, 269 insertions(+), 11 deletions(-) create mode 100644 src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs create mode 100644 src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs create mode 100644 src/YANLib.Application.Contracts/Services/IEcommerceService.cs create mode 100644 src/YANLib.Application/RemoteService/RemoteService.cs create mode 100644 src/YANLib.Application/Services/EcommerceService.cs create mode 100644 src/YANLib.Application/Validations/EcommerceValidation.cs create mode 100644 src/YANLib.HttpApi/Controllers/EcommerceController.cs diff --git a/host/YANLib.HttpApi.Host/appsettings.Development.json b/host/YANLib.HttpApi.Host/appsettings.Development.json index db951d6..b7c4879 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Development.json +++ b/host/YANLib.HttpApi.Host/appsettings.Development.json @@ -65,8 +65,8 @@ "Password": "admin123" }, "RemoteServices": { - "TestApi": { - "BaseUrl": "http://sample-api.local/" + "EcommerceApi": { + "BaseUrl": "https://ecommerce.yamiannephilim.com/" } }, "Serilog": { diff --git a/host/YANLib.HttpApi.Host/appsettings.Production.json b/host/YANLib.HttpApi.Host/appsettings.Production.json index c285659..36a53e4 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Production.json +++ b/host/YANLib.HttpApi.Host/appsettings.Production.json @@ -65,8 +65,8 @@ "Password": "admin123" }, "RemoteServices": { - "TestApi": { - "BaseUrl": "http://sample-api.local/" + "Ecommerce": { + "BaseUrl": "https://ecommerce.yamiannephilim.com/" } }, "Serilog": { diff --git a/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs b/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs new file mode 100644 index 0000000..6ac4dad --- /dev/null +++ b/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs @@ -0,0 +1,11 @@ +using RestSharp; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace YANLib.RemoteService; + +public interface IRemoteService : IApplicationService +{ + public ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary additionalHeaders = null, string jsonInput = null, Dictionary queryParams = null); +} diff --git a/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs b/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs new file mode 100644 index 0000000..7547bf7 --- /dev/null +++ b/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs @@ -0,0 +1,8 @@ +namespace YANLib.Requests; + +public sealed class EcommerceLoginRequest +{ + public required string Username { get; set; } + + public required string Password { get; set; } +} diff --git a/src/YANLib.Application.Contracts/Services/IEcommerceService.cs b/src/YANLib.Application.Contracts/Services/IEcommerceService.cs new file mode 100644 index 0000000..07f6d86 --- /dev/null +++ b/src/YANLib.Application.Contracts/Services/IEcommerceService.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using YANLib.Requests; + +namespace YANLib.Services; + +public interface IEcommerceService : IApplicationService +{ + public ValueTask GetAccessToken(EcommerceLoginRequest request); + + public ValueTask GetRefreshToken(string accessToken); +} diff --git a/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj b/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj index dce2aaf..f5fccfd 100644 --- a/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj +++ b/src/YANLib.Application.Contracts/YANLib.Application.Contracts.csproj @@ -10,6 +10,7 @@ + diff --git a/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs b/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs index eac4964..6b20290 100644 --- a/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs +++ b/src/YANLib.Application.Redis/Services/Implements/DeveloperTypeRedisService.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Elastic.Apm.StackExchange.Redis; +using Microsoft.Extensions.Logging; using StackExchange.Redis; using Volo.Abp; using YANLib.Application.Redis.ConnectionFactory; @@ -23,6 +24,7 @@ public DeveloperTypeRedisService(ILogger logger, IRed _logger = logger; _connectionFactory = connectionFactory; _connectionMultiplexer = _connectionFactory.Connection(); + _connectionMultiplexer.UseElasticApm(); _database = _connectionMultiplexer.GetDatabase(); } diff --git a/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj b/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj index bf033c7..0e7d474 100644 --- a/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj +++ b/src/YANLib.Application.Redis/YANLib.Application.Redis.csproj @@ -8,6 +8,7 @@ + diff --git a/src/YANLib.Application/RemoteService/RemoteService.cs b/src/YANLib.Application/RemoteService/RemoteService.cs new file mode 100644 index 0000000..c231f0a --- /dev/null +++ b/src/YANLib.Application/RemoteService/RemoteService.cs @@ -0,0 +1,77 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using NUglify.Helpers; +using RestSharp; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Http; +using Volo.Abp.Http.Client; +using YANLib.Core; +using static Newtonsoft.Json.Linq.JObject; +using static RestSharp.ParameterType; +using static System.Net.HttpStatusCode; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.RemoteService; + +public class RemoteService( + ILogger logger, + IOptionsSnapshot remoteServiceOptions +) : YANLibAppService, IRemoteService +{ + private readonly ILogger _logger = logger; + private readonly AbpRemoteServiceOptions _remoteServiceOptions = remoteServiceOptions.Value; + + public async ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary additionalHeaders = null, string jsonInput = null, Dictionary queryParams = null) + { + try + { + var req = new RestRequest(path, method); + + _ = req.AddHeader("Accept", "*/*"); + _ = req.AddHeader("Content-Type", "application/json"); + + if (additionalHeaders.IsNotEmptyAndNull()) + { + additionalHeaders.ForEach(x => req.AddHeader(x.Key, x.Value)); + } + + if (jsonInput.IsNotWhiteSpaceAndNull()) + { + _ = req.AddParameter("application/json", jsonInput, RequestBody); + } + + if (queryParams.IsNotEmptyAndNull()) + { + queryParams.ForEach(x => req.AddParameter(x.Key, x.Value, QueryString)); + } + + var res = await new RestClient(_remoteServiceOptions.RemoteServices.GetConfigurationOrDefaultOrNull(remoteRoot)?.BaseUrl)?.ExecuteAsync(req); + + if (res.StatusCode is OK) + { + return res.Content.Deserialize(); + } + else + { + _logger.LogError("Invoke API: {PathRoot} - {Code} - {Error} - {Content}", $"{remoteRoot}{path}", res.StatusCode, res.ErrorMessage, res.Content); + + throw new AbpRemoteCallException(res.Content.IsWhiteSpaceOrNull() ? new RemoteServiceErrorInfo + { + Code = NOT_FOUND, + Message = res.ErrorException.Message + } : Parse(res.Content)["error"].ToString().Deserialize()) + { + HttpStatusCode = res.StatusCode.ToInt() + }; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "InvokeApiRemoteService-Exception: {PathRoot} - {Method} - {JsonInput} - {QueryParams}", $"{remoteRoot}{path}", method.ToString(), jsonInput, queryParams.Serialize()); + + throw; + } + } +} diff --git a/src/YANLib.Application/Services/EcommerceService.cs b/src/YANLib.Application/Services/EcommerceService.cs new file mode 100644 index 0000000..6e1937b --- /dev/null +++ b/src/YANLib.Application/Services/EcommerceService.cs @@ -0,0 +1,54 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using YANLib.Core; +using YANLib.RemoteService; +using YANLib.Requests; +using static RestSharp.Method; +using static YANLib.YANLibConsts.RemoteService; +using static YANLib.YANLibConsts.RemoteService.Path; + +namespace YANLib.Services; + +public class EcommerceService( + ILogger logger, + IRemoteService remoteService +) : YANLibAppService, IEcommerceService +{ + private readonly ILogger _logger = logger; + private readonly IRemoteService _remoteService = remoteService; + + public async ValueTask GetAccessToken(EcommerceLoginRequest request) + { + var json = request.Serialize(); + + try + { + return await _remoteService.InvokeApi(Ecommerce, ApiLogin, Post, jsonInput: json); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetAccessTokenEcommerceService-Exception: {Request}", json); + + throw; + } + } + + public async ValueTask GetRefreshToken(string accessToken) + { + try + { + return await _remoteService.InvokeApi(Ecommerce, ApiRefresh, Get, new Dictionary + { + { "Authorization", $"Bearer {accessToken}" } + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "GetRefreshTokenEcommerceService-Exception: {AccessToken}", accessToken); + + throw; + } + } +} diff --git a/src/YANLib.Application/Validations/EcommerceValidation.cs b/src/YANLib.Application/Validations/EcommerceValidation.cs new file mode 100644 index 0000000..3a5e1db --- /dev/null +++ b/src/YANLib.Application/Validations/EcommerceValidation.cs @@ -0,0 +1,35 @@ +using FluentValidation; +using System.Collections.Generic; +using System.Linq; +using YANLib.Core; +using YANLib.Requests; +using static YANLib.YANLibDomainErrorCodes; + +namespace YANLib.Validations; + +public sealed class EcommerceValidator : AbstractValidator +{ + public EcommerceValidator() + { + _ = RuleFor(x => x.Username).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_USER_NAME).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST_USER_NAME); + _ = RuleFor(x => x.Password).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST_PWD).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST_PWD); + } +} + +public sealed class EcommerceValidators : AbstractValidator> +{ + public EcommerceValidators() + { + _ = RuleFor(x => x).NotNull().NotEmpty().WithErrorCode(BAD_REQUEST).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleForEach(s => s).SetValidator(new EcommerceValidator()); + _ = RuleFor(x => x).Must(IsNotEmptyAndNull).WithErrorCode(BAD_REQUEST).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST); + _ = RuleFor(x => x).Must(UsernameIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_USER_NAME).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST_USER_NAME); + _ = RuleFor(x => x).Must(PasswordIsNotWhiteSpace).WithErrorCode(BAD_REQUEST_PWD).WithMessage(YANLibDomainErrorMessages.BAD_REQUEST_PWD); + } + + private bool IsNotEmptyAndNull(List requests) => requests.IsNotEmptyAndNull(); + + private bool UsernameIsNotWhiteSpace(List requests) => requests.Select(x => x.Username).AllNotWhiteSpaceAndNull(); + + private bool PasswordIsNotWhiteSpace(List requests) => requests.Select(x => x.Password).AllNotWhiteSpaceAndNull(); +} diff --git a/src/YANLib.Application/YANLib.Application.csproj b/src/YANLib.Application/YANLib.Application.csproj index 676d40e..d3afd09 100644 --- a/src/YANLib.Application/YANLib.Application.csproj +++ b/src/YANLib.Application/YANLib.Application.csproj @@ -22,6 +22,7 @@ + diff --git a/src/YANLib.Domain.Shared/Localization/YANLib/vi.json b/src/YANLib.Domain.Shared/Localization/YANLib/vi.json index 9cad14e..c33d9e4 100644 --- a/src/YANLib.Domain.Shared/Localization/YANLib/vi.json +++ b/src/YANLib.Domain.Shared/Localization/YANLib/vi.json @@ -7,6 +7,8 @@ "YANLib:430": "Mã truyền vào không hợp lệ!", "YANLib:440": "Điểm truyền vào không hợp lệ!", "YANLib:450": "Mã hồ sơ lập trình viên truyền vào không hợp lệ!", + "YANLib:460": "Tên người dùng truyền vào không hợp lệ!", + "YANLib:470": "Mật khẩu truyền vào không hợp lệ!", "YANLib:403": "Lỗi quy tắc!", "YANLib:413": "Mã {Id} đã tồn tại!", "YANLib:423": "Mã định danh {IdCard} đã tồn tại!", diff --git a/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs b/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs index fc97570..6f3bace 100644 --- a/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs +++ b/src/YANLib.Domain.Shared/YANLibDomainErrorCodes.cs @@ -8,6 +8,8 @@ public static class YANLibDomainErrorCodes public const string BAD_REQUEST_ID = "YANLib:430"; public const string BAD_REQUEST_GPA = "YANLib:440"; public const string BAD_REQUEST_DEV_ID = "YANLib:450"; + public const string BAD_REQUEST_USER_NAME = "YANLib:460"; + public const string BAD_REQUEST_PWD = "YANLib:470"; public const string BUSINESS_ERROR = "YANLib:403"; public const string EXIST_ID = "YANLib:413"; diff --git a/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs b/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs index f9459b9..2a9a23f 100644 --- a/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs +++ b/src/YANLib.Domain.Shared/YANLibDomainErrorMessages.cs @@ -8,6 +8,8 @@ public static class YANLibDomainErrorMessages public const string BAD_REQUEST_ID = "Mã truyền vào không hợp lệ!"; public const string BAD_REQUEST_GPA = "Điểm truyền vào không hợp lệ!"; public const string BAD_REQUEST_DEV_ID = "Mã hồ sơ lập trình viên truyền vào không hợp lệ!"; + public const string BAD_REQUEST_USER_NAME = "Tên người dùng truyền vào không hợp lệ!"; + public const string BAD_REQUEST_PWD = "Mật khẩu truyền vào không hợp lệ!"; public const string BUSINESS_ERROR = "Lỗi quy tắc!"; public const string EXIST_ID = "Mã đã tồn tại!"; diff --git a/src/YANLib.Domain/YANLibConsts.cs b/src/YANLib.Domain/YANLibConsts.cs index ac28cbf..8682591 100644 --- a/src/YANLib.Domain/YANLibConsts.cs +++ b/src/YANLib.Domain/YANLibConsts.cs @@ -42,4 +42,15 @@ public readonly struct RedisConstant public static readonly string DeveloperTypeGroup = $"{YanlibPrefix}:{SamplePrefix}:{DeveloperTypePrefix}"; } + + public readonly struct RemoteService + { + public const string Ecommerce = "Ecommerce"; + + public readonly struct Path + { + public const string ApiLogin = "/api/login"; + public const string ApiRefresh = "/api/refresh"; + } + } } diff --git a/src/YANLib.HttpApi/Controllers/DeveloperController.cs b/src/YANLib.HttpApi/Controllers/DeveloperController.cs index aaa1c57..1c84807 100644 --- a/src/YANLib.HttpApi/Controllers/DeveloperController.cs +++ b/src/YANLib.HttpApi/Controllers/DeveloperController.cs @@ -12,7 +12,7 @@ namespace YANLib.Controllers; [RemoteService] [ApiExplorerSettings(GroupName = "sample")] -[Route("api/yanlib/developers")] +[Route("api/developers")] public sealed class DeveloperController(ILogger logger, IDeveloperService service) : YANLibController { private readonly ILogger _logger = logger; diff --git a/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs b/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs index 5d54112..4e56069 100644 --- a/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs +++ b/src/YANLib.HttpApi/Controllers/DeveloperTypeController.cs @@ -12,7 +12,7 @@ namespace YANLib.Controllers; [RemoteService] [ApiExplorerSettings(GroupName = "sample")] -[Route("api/yanlib/developer-types")] +[Route("api/developer-types")] public sealed class DeveloperTypeController(ILogger logger, IDeveloperTypeService service) : YANLibController { private readonly ILogger _logger = logger; @@ -49,7 +49,7 @@ public async ValueTask Update(int code, [Required] DeveloperTypeU return Ok(await _service.Update(code, request)); } - [SwaggerOperation(Summary = "Đồng bộ tất cả định nghĩa Developer Types từ Database sang Redis")] [HttpPost("sync-db-to-redis")] + [SwaggerOperation(Summary = "Đồng bộ tất cả định nghĩa Developer Types từ Database sang Redis")] public async ValueTask SyncDbToRedis() => Ok(await _service.SyncDbToRedis()); } diff --git a/src/YANLib.HttpApi/Controllers/EcommerceController.cs b/src/YANLib.HttpApi/Controllers/EcommerceController.cs new file mode 100644 index 0000000..4ddd458 --- /dev/null +++ b/src/YANLib.HttpApi/Controllers/EcommerceController.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Annotations; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Volo.Abp; +using YANLib.Core; +using YANLib.Requests; +using YANLib.Services; + +namespace YANLib.Controllers; + +[RemoteService] +[ApiExplorerSettings(GroupName = "sample")] +[Route("api/remote/ecommerce")] +public sealed class EcommerceController(ILogger logger, IEcommerceService service) : YANLibController +{ + private readonly ILogger _logger = logger; + private readonly IEcommerceService _service = service; + + [HttpGet("access-token")] + [SwaggerOperation(Summary = "Lấy access token của API login của trang Ecommerce")] + public async ValueTask GetAccessToken([Required] EcommerceLoginRequest request) + { + _logger.LogInformation("GetAccessTokenEcommerceController: {Request}", request.Serialize()); + + return Ok(await _service.GetAccessToken(request)); + } + + [HttpGet("refresh-token")] + + [SwaggerOperation(Summary = "Lấy refresh token của API refresh của trang Ecommerce")] + public async ValueTask GetRefreshToken([Required] string accessToken) + { + _logger.LogInformation("GetRefreshTokenEcommerceController: {AccessToken}", accessToken); + + return Ok(await _service.GetRefreshToken(accessToken)); + } +} diff --git a/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs b/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs index 9c102cc..46df6f9 100644 --- a/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs +++ b/src/YANLib.HttpApi/Controllers/ElasticsearchController.cs @@ -12,7 +12,7 @@ namespace YANLib.Controllers; [RemoteService] [ApiExplorerSettings(GroupName = "sample")] -[Route("api/yanlib/es")] +[Route("api/es")] public sealed class ElasticsearchController(ILogger logger, IDeveloperEsService developerEsService) : YANLibController { private readonly ILogger _logger = logger; diff --git a/src/YANLib.HttpApi/Controllers/IdSnowflakeController.cs b/src/YANLib.HttpApi/Controllers/IdSnowflakeController.cs index 27930c4..92635ce 100644 --- a/src/YANLib.HttpApi/Controllers/IdSnowflakeController.cs +++ b/src/YANLib.HttpApi/Controllers/IdSnowflakeController.cs @@ -9,7 +9,7 @@ namespace YANLib.Controllers; [RemoteService] [ApiExplorerSettings(GroupName = "test")] -[Route("api/yanlib/id-snowflakes")] +[Route("api/id-snowflakes")] public sealed class IdSnowflakeController(ILogger logger) : YANLibController { private readonly ILogger _logger = logger; diff --git a/src/YANLib.HttpApi/Controllers/YANJsonController.cs b/src/YANLib.HttpApi/Controllers/YANJsonController.cs index 55703b1..22df988 100644 --- a/src/YANLib.HttpApi/Controllers/YANJsonController.cs +++ b/src/YANLib.HttpApi/Controllers/YANJsonController.cs @@ -11,7 +11,7 @@ namespace YANLib.Controllers; [RemoteService] [ApiExplorerSettings(GroupName = "test")] -[Route("api/yanlib/json")] +[Route("api/json")] public sealed class YANJsonController(ILogger logger, IYANJsonService service) : YANLibController { private readonly ILogger _logger = logger; From c40768d738c28aba19df6e6426816a191e01f080 Mon Sep 17 00:00:00 2001 From: Yami An Date: Sat, 3 Feb 2024 01:37:35 +0700 Subject: [PATCH 2/3] additional --- README.md | 4 ++-- .../Requests/EcommerceLoginRequest.cs | 6 +++++- src/YANLib.HttpApi/Controllers/EcommerceController.cs | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 98a9f21..be79dac 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,8 @@ var dto = json.Deserialize(); ### NOTE -- Elastic.Apm.NetCoreAll (v.1.24.x and above) is spam logs. -- DotNetCap.CAP (v.7.x.x and above) is MongoDB error. +- Elastic.Apm... (v.1.24.x and above) is spam logs. +- DotNetCap.CAP... (v.7.x.x and above) is MongoDB error. - Do not [Remove Unused References...] in layers: - Host: - Microsoft.EntityFrameworkCore.Tools diff --git a/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs b/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs index 7547bf7..d271c73 100644 --- a/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs +++ b/src/YANLib.Application.Contracts/Requests/EcommerceLoginRequest.cs @@ -1,8 +1,12 @@ -namespace YANLib.Requests; +using System.ComponentModel; + +namespace YANLib.Requests; public sealed class EcommerceLoginRequest { + [DefaultValue("nguyenvana@gmail.com")] public required string Username { get; set; } + [DefaultValue("nguyenvana")] public required string Password { get; set; } } diff --git a/src/YANLib.HttpApi/Controllers/EcommerceController.cs b/src/YANLib.HttpApi/Controllers/EcommerceController.cs index 4ddd458..44d0195 100644 --- a/src/YANLib.HttpApi/Controllers/EcommerceController.cs +++ b/src/YANLib.HttpApi/Controllers/EcommerceController.cs @@ -18,7 +18,7 @@ public sealed class EcommerceController(ILogger logger, IEc private readonly ILogger _logger = logger; private readonly IEcommerceService _service = service; - [HttpGet("access-token")] + [HttpPost("access-token")] [SwaggerOperation(Summary = "Lấy access token của API login của trang Ecommerce")] public async ValueTask GetAccessToken([Required] EcommerceLoginRequest request) { @@ -28,7 +28,6 @@ public async ValueTask GetAccessToken([Required] EcommerceLoginRe } [HttpGet("refresh-token")] - [SwaggerOperation(Summary = "Lấy refresh token của API refresh của trang Ecommerce")] public async ValueTask GetRefreshToken([Required] string accessToken) { From 10aec6a01906e040ff50ed56f9b08b9ebc1a58ad Mon Sep 17 00:00:00 2001 From: Yami An Date: Sat, 3 Feb 2024 08:25:32 +0700 Subject: [PATCH 3/3] remote service --- .../YANLibHttpApiHostModule.cs | 4 +- .../appsettings.Development.json | 2 +- .../appsettings.Production.json | 4 +- .../RemoteService/IRemoteService.cs | 2 +- .../RemoteService/RemoteService.cs | 41 +++++++++++++------ .../Services/EcommerceService.cs | 9 +++- src/YANLib.Domain/YANLibConsts.cs | 6 +-- 7 files changed, 46 insertions(+), 22 deletions(-) diff --git a/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs b/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs index e63125e..a59af59 100644 --- a/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs +++ b/host/YANLib.HttpApi.Host/YANLibHttpApiHostModule.cs @@ -31,7 +31,6 @@ using Volo.Abp.Swashbuckle; using YANLib.Core; using YANLib.EntityFrameworkCore; -using YANLib.Middlewares; using YANLib.Utilities; using static Elastic.Apm.Agent; using static HealthChecks.UI.Client.UIResponseWriter; @@ -230,7 +229,10 @@ public override void OnApplicationInitialization(ApplicationInitializationContex _ = app.UseAuthentication(); _ = app.UseAuthorization(); _ = app.UseSwagger(); + +#if RELEASE _ = app.UseMiddleware(); +#endif _ = app.UseAbpSwaggerUI(c => { diff --git a/host/YANLib.HttpApi.Host/appsettings.Development.json b/host/YANLib.HttpApi.Host/appsettings.Development.json index b7c4879..f96af63 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Development.json +++ b/host/YANLib.HttpApi.Host/appsettings.Development.json @@ -66,7 +66,7 @@ }, "RemoteServices": { "EcommerceApi": { - "BaseUrl": "https://ecommerce.yamiannephilim.com/" + "BaseUrl": "https://ecommerce.yamiannephilim.com/api/" } }, "Serilog": { diff --git a/host/YANLib.HttpApi.Host/appsettings.Production.json b/host/YANLib.HttpApi.Host/appsettings.Production.json index 36a53e4..b13e99d 100644 --- a/host/YANLib.HttpApi.Host/appsettings.Production.json +++ b/host/YANLib.HttpApi.Host/appsettings.Production.json @@ -65,8 +65,8 @@ "Password": "admin123" }, "RemoteServices": { - "Ecommerce": { - "BaseUrl": "https://ecommerce.yamiannephilim.com/" + "EcommerceApi": { + "BaseUrl": "https://ecommerce.yamiannephilim.com/api/" } }, "Serilog": { diff --git a/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs b/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs index 6ac4dad..c00896b 100644 --- a/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs +++ b/src/YANLib.Application.Contracts/RemoteService/IRemoteService.cs @@ -7,5 +7,5 @@ namespace YANLib.RemoteService; public interface IRemoteService : IApplicationService { - public ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary additionalHeaders = null, string jsonInput = null, Dictionary queryParams = null); + public ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary headers = null, string jsonInput = null, Dictionary queryParams = null); } diff --git a/src/YANLib.Application/RemoteService/RemoteService.cs b/src/YANLib.Application/RemoteService/RemoteService.cs index c231f0a..a48d850 100644 --- a/src/YANLib.Application/RemoteService/RemoteService.cs +++ b/src/YANLib.Application/RemoteService/RemoteService.cs @@ -23,18 +23,20 @@ IOptionsSnapshot remoteServiceOptions private readonly ILogger _logger = logger; private readonly AbpRemoteServiceOptions _remoteServiceOptions = remoteServiceOptions.Value; - public async ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary additionalHeaders = null, string jsonInput = null, Dictionary queryParams = null) + public async ValueTask InvokeApi(string remoteRoot, string path, Method method, Dictionary headers = null, string jsonInput = null, Dictionary queryParams = null) { try { var req = new RestRequest(path, method); - _ = req.AddHeader("Accept", "*/*"); - _ = req.AddHeader("Content-Type", "application/json"); - - if (additionalHeaders.IsNotEmptyAndNull()) + if (headers.IsNotEmptyAndNull()) { - additionalHeaders.ForEach(x => req.AddHeader(x.Key, x.Value)); + headers.ForEach(x => req.AddHeader(x.Key, x.Value)); + } + else + { + _ = req.AddHeader("Accept", "*/*"); + _ = req.AddHeader("Content-Type", "application/json"); } if (jsonInput.IsNotWhiteSpaceAndNull()) @@ -57,14 +59,29 @@ public async ValueTask InvokeApi(string remoteRoot, string path, Method me { _logger.LogError("Invoke API: {PathRoot} - {Code} - {Error} - {Content}", $"{remoteRoot}{path}", res.StatusCode, res.ErrorMessage, res.Content); - throw new AbpRemoteCallException(res.Content.IsWhiteSpaceOrNull() ? new RemoteServiceErrorInfo + if (res.Content.IsWhiteSpaceOrNull()) { - Code = NOT_FOUND, - Message = res.ErrorException.Message - } : Parse(res.Content)["error"].ToString().Deserialize()) + throw new AbpRemoteCallException(new RemoteServiceErrorInfo + { + Code = NOT_FOUND, + Message = res.ErrorException.Message + }) + { + HttpStatusCode = res.StatusCode.ToInt() + }; + } + else { - HttpStatusCode = res.StatusCode.ToInt() - }; + var jtoken = Parse(res.Content)["error"]?.ToString(); + + throw new AbpRemoteCallException(jtoken?.Deserialize() ?? new RemoteServiceErrorInfo + { + Message = jtoken + }) + { + HttpStatusCode = res.StatusCode.ToInt() + }; + } } } catch (Exception ex) diff --git a/src/YANLib.Application/Services/EcommerceService.cs b/src/YANLib.Application/Services/EcommerceService.cs index 6e1937b..a050ffc 100644 --- a/src/YANLib.Application/Services/EcommerceService.cs +++ b/src/YANLib.Application/Services/EcommerceService.cs @@ -25,7 +25,12 @@ public async ValueTask GetAccessToken(EcommerceLoginRequest request) try { - return await _remoteService.InvokeApi(Ecommerce, ApiLogin, Post, jsonInput: json); + var hdrs = new Dictionary + { + { "Accept", "*/*" }, + { "Content-Type", "application/x-www-form-urlencoded" } + }; + return await _remoteService.InvokeApi(EcommerceApi, Login, Post, jsonInput: json); } catch (Exception ex) { @@ -39,7 +44,7 @@ public async ValueTask GetRefreshToken(string accessToken) { try { - return await _remoteService.InvokeApi(Ecommerce, ApiRefresh, Get, new Dictionary + return await _remoteService.InvokeApi(EcommerceApi, Refresh, Get, new Dictionary { { "Authorization", $"Bearer {accessToken}" } }); diff --git a/src/YANLib.Domain/YANLibConsts.cs b/src/YANLib.Domain/YANLibConsts.cs index 8682591..35c2fab 100644 --- a/src/YANLib.Domain/YANLibConsts.cs +++ b/src/YANLib.Domain/YANLibConsts.cs @@ -45,12 +45,12 @@ public readonly struct RedisConstant public readonly struct RemoteService { - public const string Ecommerce = "Ecommerce"; + public const string EcommerceApi = "EcommerceApi"; public readonly struct Path { - public const string ApiLogin = "/api/login"; - public const string ApiRefresh = "/api/refresh"; + public const string Login = "login"; + public const string Refresh = "refresh"; } } }