From 36ace4125d2dd9a2603dd61b0c851adfc365cf26 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 9 Dec 2024 14:45:35 +0500 Subject: [PATCH 1/6] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B1=D1=80=D0=B8=D0=BA=D1=83=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20Persistance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Clients/Base/BaseClient.cs | 62 ++++++++++ Persistence.Client/Clients/ISetpointClient.cs | 30 ----- .../Clients/ITechMessagesClient.cs | 31 ----- .../Clients/Interfaces/ISetpointClient.cs | 59 ++++++++++ .../Clients/Interfaces/ITechMessagesClient.cs | 57 +++++++++ .../Clients/Interfaces/ITimeSeriesClient.cs | 44 +++++++ .../Interfaces/ITimestampedSetClient.cs | 56 +++++++++ .../Interfaces/Refit/IRefitSetpointClient.cs | 30 +++++ .../Refit/IRefitTechMessagesClient.cs | 31 +++++ .../Refit/IRefitTimeSeriesClient.cs} | 14 +-- .../Refit/IRefitTimestampedSetClient.cs} | 14 +-- Persistence.Client/Clients/SetpointClient.cs | 63 ++++++++++ .../Clients/TechMessagesClient.cs | 65 +++++++++++ .../Clients/TimeSeriesClient.cs | 48 ++++++++ .../Clients/TimestampedSetClient.cs | 56 +++++++++ .../CustomExceptions/AcceptableException.cs | 10 ++ .../CustomExceptions/BadGatewayException.cs | 10 ++ .../CustomExceptions/ForbiddenException.cs | 10 ++ .../InternalServerException.cs | 10 ++ .../CustomExceptions/LockedException.cs | 10 ++ .../ServiceUnavailableException.cs | 10 ++ .../TooManyRequestsException.cs | 10 ++ Persistence.Client/Helpers/ApiTokenHelper.cs | 5 + .../Helpers/ExceptionsHelper.cs | 33 ++++++ Persistence.Client/Persistence.Client.csproj | 4 - .../PersistenceClientFactory.cs | 71 ++++++++++- .../Controllers/SetpointControllerTest.cs | 87 ++++++-------- .../Controllers/TechMessagesControllerTest.cs | 89 +++++++------- .../TimeSeriesBaseControllerTest.cs | 36 +++--- .../TimestampedSetControllerTest.cs | 110 ++++++++---------- .../WebAppFactoryFixture.cs | 4 +- Persistence/Factories/IAuthTokenFactory.cs | 13 +++ 32 files changed, 917 insertions(+), 265 deletions(-) create mode 100644 Persistence.Client/Clients/Base/BaseClient.cs delete mode 100644 Persistence.Client/Clients/ISetpointClient.cs delete mode 100644 Persistence.Client/Clients/ITechMessagesClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/ISetpointClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs rename Persistence.Client/Clients/{ITimeSeriesClient.cs => Interfaces/Refit/IRefitTimeSeriesClient.cs} (54%) rename Persistence.Client/Clients/{ITimestampedSetClient.cs => Interfaces/Refit/IRefitTimestampedSetClient.cs} (89%) create mode 100644 Persistence.Client/Clients/SetpointClient.cs create mode 100644 Persistence.Client/Clients/TechMessagesClient.cs create mode 100644 Persistence.Client/Clients/TimeSeriesClient.cs create mode 100644 Persistence.Client/Clients/TimestampedSetClient.cs create mode 100644 Persistence.Client/CustomExceptions/AcceptableException.cs create mode 100644 Persistence.Client/CustomExceptions/BadGatewayException.cs create mode 100644 Persistence.Client/CustomExceptions/ForbiddenException.cs create mode 100644 Persistence.Client/CustomExceptions/InternalServerException.cs create mode 100644 Persistence.Client/CustomExceptions/LockedException.cs create mode 100644 Persistence.Client/CustomExceptions/ServiceUnavailableException.cs create mode 100644 Persistence.Client/CustomExceptions/TooManyRequestsException.cs create mode 100644 Persistence.Client/Helpers/ExceptionsHelper.cs create mode 100644 Persistence/Factories/IAuthTokenFactory.cs diff --git a/Persistence.Client/Clients/Base/BaseClient.cs b/Persistence.Client/Clients/Base/BaseClient.cs new file mode 100644 index 0000000..bca6f6a --- /dev/null +++ b/Persistence.Client/Clients/Base/BaseClient.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Helpers; +using Refit; + +namespace Persistence.Client.Clients.Base; +public class BaseClient +{ + private readonly ILogger logger; + + public BaseClient(ILogger logger) + { + this.logger = logger; + } + + public async Task ExecuteGetResponse(Func>> getMethod, CancellationToken token) + { + var response = await getMethod.Invoke().WaitAsync(token); + + if (response.IsSuccessful) + { + return response.Content; + } + + var exception = response.GetPersistenceException(); + + logger.LogError(exception.Message); + + throw exception; + } + + public async Task ExecutePostResponse(Func> postMethod, CancellationToken token) + { + var response = await postMethod.Invoke().WaitAsync(token); + + if (response.IsSuccessful) + { + return; + } + + var exception = response.GetPersistenceException(); + + logger.LogError(exception.Message); + + throw exception; + } + + public async Task ExecutePostResponse(Func>> postMethod, CancellationToken token) + { + var response = await postMethod.Invoke().WaitAsync(token); + + if (response.IsSuccessful) + { + return response.Content; + } + + var exception = response.GetPersistenceException(); + + logger.LogError(exception.Message); + + throw exception; + } +} diff --git a/Persistence.Client/Clients/ISetpointClient.cs b/Persistence.Client/Clients/ISetpointClient.cs deleted file mode 100644 index 0b81ffa..0000000 --- a/Persistence.Client/Clients/ISetpointClient.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Persistence.Models; -using Refit; - -namespace Persistence.Client.Clients; - -/// -/// Интерфейс клиента для работы с уставками -/// -public interface ISetpointClient -{ - private const string BaseRoute = "/api/setpoint"; - - [Get($"{BaseRoute}/current")] - Task>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable setpointKeys); - - [Get($"{BaseRoute}/history")] - Task>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable setpointKeys, [Query] DateTimeOffset historyMoment); - - [Get($"{BaseRoute}/log")] - Task>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable setpointKeys); - - [Get($"{BaseRoute}/range")] - Task> GetDatesRangeAsync(CancellationToken token); - - [Get($"{BaseRoute}/part")] - Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); - - [Post($"{BaseRoute}/")] - Task Add(Guid setpointKey, object newValue); -} diff --git a/Persistence.Client/Clients/ITechMessagesClient.cs b/Persistence.Client/Clients/ITechMessagesClient.cs deleted file mode 100644 index 878c6cf..0000000 --- a/Persistence.Client/Clients/ITechMessagesClient.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Persistence.Models; -using Refit; - -namespace Persistence.Client.Clients -{ - /// - /// Интерфейс клиента для хранения технологических сообщений - /// - public interface ITechMessagesClient - { - private const string BaseRoute = "/api/techMessages"; - - [Get($"{BaseRoute}")] - Task>> GetPage([Query] RequestDto request, CancellationToken token); - - [Post($"{BaseRoute}")] - Task> AddRange([Body] IEnumerable dtos, CancellationToken token); - - [Get($"{BaseRoute}/systems")] - Task>> GetSystems(CancellationToken token); - - [Get($"{BaseRoute}/range")] - Task> GetDatesRangeAsync(CancellationToken token); - - [Get($"{BaseRoute}/part")] - Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); - - [Get($"{BaseRoute}/statistics")] - Task>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token); - } -} diff --git a/Persistence.Client/Clients/Interfaces/ISetpointClient.cs b/Persistence.Client/Clients/Interfaces/ISetpointClient.cs new file mode 100644 index 0000000..19c5902 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/ISetpointClient.cs @@ -0,0 +1,59 @@ +using Persistence.Models; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с уставками +/// +public interface ISetpointClient +{ + /// + /// Добавить уставку + /// + /// + /// + /// + /// + Task Add(Guid setpointKey, object newValue, CancellationToken token); + + /// + /// Получить актуальные значения уставок + /// + /// + /// + /// + Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token); + + /// + /// Получить диапазон дат, для которых есть данные в репозитории + /// + /// + /// + Task GetDatesRangeAsync(CancellationToken token); + + /// + /// Получить значения уставок за определенный момент времени + /// + /// + /// + /// + /// + Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token); + + /// + /// Получить историю изменений значений уставок + /// + /// + /// + /// + Task>> GetLog(IEnumerable setpointKeys, CancellationToken token); + + /// + /// Получить порцию записей, начиная с заданной даты + /// + /// + /// + /// + /// + Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); +} \ No newline at end of file diff --git a/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs b/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs new file mode 100644 index 0000000..8da559c --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs @@ -0,0 +1,57 @@ +using Persistence.Models; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с технологическими сообщениями +/// +public interface ITechMessagesClient +{ + /// + /// Добавить новые технологические сообщения + /// + /// + /// + /// + Task AddRange(IEnumerable dtos, CancellationToken token); + + /// + /// Получить диапазон дат, для которых есть данные в репозитории + /// + /// + /// + Task GetDatesRangeAsync(CancellationToken token); + + /// + /// Получить список технологических сообщений в виде страницы + /// + /// + /// + /// + Task> GetPage(RequestDto request, CancellationToken token); + + /// + /// Получить порцию записей, начиная с заданной даты + /// + /// + /// + /// + /// + Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); + + /// + /// Получить статистику по системам + /// + /// + /// + /// + /// + Task> GetStatistics(string autoDrillingSystem, int categoryId, CancellationToken token); + + /// + /// Получить список всех систем + /// + /// + /// + Task> GetSystems(CancellationToken token); +} \ No newline at end of file diff --git a/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs b/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs new file mode 100644 index 0000000..d6dd199 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs @@ -0,0 +1,44 @@ +using Persistence.Models; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с временными данными +/// +/// +public interface ITimeSeriesClient where TDto : class, new() +{ + /// + /// Добавление записей + /// + /// + /// + /// + Task AddRange(IEnumerable dtos, CancellationToken token); + + /// + /// Получить список объектов, удовлетворяющий диапазону дат + /// + /// + /// + /// + /// + Task> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); + + /// + /// Получить диапазон дат, для которых есть данные в репозитории + /// + /// + /// + Task GetDatesRange(CancellationToken token); + + /// + /// Получить список объектов с прореживанием, удовлетворяющий диапазону дат + /// + /// + /// + /// + /// + /// + Task> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default); +} \ No newline at end of file diff --git a/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs b/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs new file mode 100644 index 0000000..ee0ca6e --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs @@ -0,0 +1,56 @@ +using Persistence.Models; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с данными с отметкой времени +/// +public interface ITimestampedSetClient +{ + /// + /// Записать новые данные + /// + /// + /// + /// + /// + Task AddRange(Guid idDiscriminator, IEnumerable sets, CancellationToken token); + + /// + /// Количество записей по указанному набору в БД. Для пагинации + /// + /// + /// + /// + Task Count(Guid idDiscriminator, CancellationToken token); + + /// + /// Получение данных с фильтрацией. Значение фильтра null - отключен + /// + /// + /// + /// + /// + /// + /// + /// + Task> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token); + + /// + /// Диапазон дат за которые есть данные + /// + /// + /// + /// + Task GetDatesRange(Guid idDiscriminator, CancellationToken token); + + /// + /// + /// + /// + /// + /// + /// + /// + Task> GetLast(Guid idDiscriminator, IEnumerable? columnNames, int take, CancellationToken token); +} \ No newline at end of file diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs new file mode 100644 index 0000000..97baaba --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs @@ -0,0 +1,30 @@ +using Persistence.Models; +using Refit; + +namespace Persistence.Client.Clients.Interfaces.Refit; + +/// +/// Интерфейс клиента для работы с уставками +/// +public interface IRefitSetpointClient +{ + private const string BaseRoute = "/api/setpoint"; + + [Get($"{BaseRoute}/current")] + Task>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable setpointKeys, CancellationToken token); + + [Get($"{BaseRoute}/history")] + Task>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable setpointKeys, [Query] DateTimeOffset historyMoment, CancellationToken token); + + [Get($"{BaseRoute}/log")] + Task>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable setpointKeys, CancellationToken token); + + [Get($"{BaseRoute}/range")] + Task> GetDatesRangeAsync(CancellationToken token); + + [Get($"{BaseRoute}/part")] + Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); + + [Post($"{BaseRoute}/")] + Task Add(Guid setpointKey, object newValue, CancellationToken token); +} diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs new file mode 100644 index 0000000..68968a1 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs @@ -0,0 +1,31 @@ +using Persistence.Models; +using Refit; + +namespace Persistence.Client.Clients.Interfaces.Refit +{ + /// + /// Интерфейс клиента для хранения технологических сообщений + /// + public interface IRefitTechMessagesClient + { + private const string BaseRoute = "/api/techMessages"; + + [Get($"{BaseRoute}")] + Task>> GetPage([Query] RequestDto request, CancellationToken token); + + [Post($"{BaseRoute}")] + Task> AddRange([Body] IEnumerable dtos, CancellationToken token); + + [Get($"{BaseRoute}/systems")] + Task>> GetSystems(CancellationToken token); + + [Get($"{BaseRoute}/range")] + Task> GetDatesRangeAsync(CancellationToken token); + + [Get($"{BaseRoute}/part")] + Task>> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token); + + [Get($"{BaseRoute}/statistics")] + Task>> GetStatistics([Query] string autoDrillingSystem, [Query] int categoryId, CancellationToken token); + } +} diff --git a/Persistence.Client/Clients/ITimeSeriesClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs similarity index 54% rename from Persistence.Client/Clients/ITimeSeriesClient.cs rename to Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs index 8e97836..06a1266 100644 --- a/Persistence.Client/Clients/ITimeSeriesClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs @@ -1,21 +1,21 @@ using Persistence.Models; using Refit; -namespace Persistence.Client.Clients; -public interface ITimeSeriesClient +namespace Persistence.Client.Clients.Interfaces.Refit; +public interface IRefitTimeSeriesClient where TDto : class, new() { private const string BaseRoute = "/api/dataSaub"; [Post($"{BaseRoute}")] - Task> AddRange(IEnumerable dtos); + Task> AddRange(IEnumerable dtos, CancellationToken token); [Get($"{BaseRoute}")] - Task>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd); + Task>> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); [Get($"{BaseRoute}/resampled")] - Task>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024); - + Task>> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default); + [Get($"{BaseRoute}/datesRange")] - Task> GetDatesRange(); + Task> GetDatesRange(CancellationToken token); } diff --git a/Persistence.Client/Clients/ITimestampedSetClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs similarity index 89% rename from Persistence.Client/Clients/ITimestampedSetClient.cs rename to Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs index bbff603..b379725 100644 --- a/Persistence.Client/Clients/ITimestampedSetClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs @@ -1,7 +1,7 @@ using Persistence.Models; using Refit; -namespace Persistence.Client.Clients; +namespace Persistence.Client.Clients.Interfaces.Refit; /// /// Клиент для работы с репозиторием для хранения разных наборов данных рядов. @@ -9,7 +9,7 @@ namespace Persistence.Client.Clients; /// idDiscriminator формируют клиенты и только им известно что они обозначают. /// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено. /// -public interface ITimestampedSetClient +public interface IRefitTimestampedSetClient { private const string baseUrl = "/api/TimestampedSet/{idDiscriminator}"; @@ -20,7 +20,7 @@ public interface ITimestampedSetClient /// /// [Post(baseUrl)] - Task> AddRange(Guid idDiscriminator, IEnumerable sets); + Task> AddRange(Guid idDiscriminator, IEnumerable sets, CancellationToken token); /// /// Получение данных с фильтрацией. Значение фильтра null - отключен @@ -32,7 +32,7 @@ public interface ITimestampedSetClient /// /// [Get(baseUrl)] - Task>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable? columnNames, int skip, int take); + Task>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable? columnNames, int skip, int take, CancellationToken token); /// /// Получить последние данные @@ -42,7 +42,7 @@ public interface ITimestampedSetClient /// /// [Get($"{baseUrl}/last")] - Task>> GetLast(Guid idDiscriminator, [Query] IEnumerable? columnNames, int take); + Task>> GetLast(Guid idDiscriminator, [Query] IEnumerable? columnNames, int take, CancellationToken token); /// /// Количество записей по указанному набору в БД. Для пагинации. @@ -50,7 +50,7 @@ public interface ITimestampedSetClient /// Дискриминатор (идентификатор) набора /// [Get($"{baseUrl}/count")] - Task> Count(Guid idDiscriminator); + Task> Count(Guid idDiscriminator, CancellationToken token); /// /// Диапазон дат за которые есть данные @@ -58,5 +58,5 @@ public interface ITimestampedSetClient /// Дискриминатор (идентификатор) набора /// [Get($"{baseUrl}/datesRange")] - Task> GetDatesRange(Guid idDiscriminator); + Task> GetDatesRange(Guid idDiscriminator, CancellationToken token); } diff --git a/Persistence.Client/Clients/SetpointClient.cs b/Persistence.Client/Clients/SetpointClient.cs new file mode 100644 index 0000000..91e10e2 --- /dev/null +++ b/Persistence.Client/Clients/SetpointClient.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients.Interfaces.Refit; +using Persistence.Models; + +namespace Persistence.Client.Clients; + +public class SetpointClient : BaseClient, ISetpointClient +{ + private readonly IRefitSetpointClient refitSetpointClient; + + public SetpointClient(IRefitSetpointClient refitSetpointClient, ILogger logger) : base(logger) + { + this.refitSetpointClient = refitSetpointClient; + } + + public async Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitSetpointClient.GetCurrent(setpointKeys, token), token); + + return result; + } + + public async Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitSetpointClient.GetHistory(setpointKeys, historyMoment, token), token); + + return result; + } + + public async Task>> GetLog(IEnumerable setpointKeys, CancellationToken token) + { + var result = await ExecuteGetResponse>>( + async () => await refitSetpointClient.GetLog(setpointKeys, token), token); + + return result; + } + + public async Task GetDatesRangeAsync(CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitSetpointClient.GetDatesRangeAsync(token), token); + + return result; + } + + public async Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitSetpointClient.GetPart(dateBegin, take, token), token); + + return result; + } + + public async Task Add(Guid setpointKey, object newValue, CancellationToken token) + { + await ExecutePostResponse( + async () => await refitSetpointClient.Add(setpointKey, newValue, token), token); + } +} diff --git a/Persistence.Client/Clients/TechMessagesClient.cs b/Persistence.Client/Clients/TechMessagesClient.cs new file mode 100644 index 0000000..2a7b0e0 --- /dev/null +++ b/Persistence.Client/Clients/TechMessagesClient.cs @@ -0,0 +1,65 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients.Interfaces.Refit; +using Persistence.Models; + +namespace Persistence.Client.Clients; + +public class TechMessagesClient : BaseClient, ITechMessagesClient +{ + private readonly IRefitTechMessagesClient refitTechMessagesClient; + + public TechMessagesClient(IRefitTechMessagesClient refitTechMessagesClient, ILogger logger) : base(logger) + { + this.refitTechMessagesClient = refitTechMessagesClient; + } + + public async Task> GetPage(RequestDto request, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTechMessagesClient.GetPage(request, token), token); + + return result; + } + + public async Task AddRange(IEnumerable dtos, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitTechMessagesClient.AddRange(dtos, token), token); + + return result; + } + + public async Task> GetSystems(CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTechMessagesClient.GetSystems(token), token); + + return result; + } + + public async Task GetDatesRangeAsync(CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitTechMessagesClient.GetDatesRangeAsync(token), token); + + return result; + } + + public async Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTechMessagesClient.GetPart(dateBegin, take, token), token); + + return result; + } + + public async Task> GetStatistics(string autoDrillingSystem, int categoryId, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTechMessagesClient.GetStatistics(autoDrillingSystem, categoryId, token), token); + + return result; + } +} diff --git a/Persistence.Client/Clients/TimeSeriesClient.cs b/Persistence.Client/Clients/TimeSeriesClient.cs new file mode 100644 index 0000000..0b49c81 --- /dev/null +++ b/Persistence.Client/Clients/TimeSeriesClient.cs @@ -0,0 +1,48 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients.Interfaces.Refit; +using Persistence.Models; + +namespace Persistence.Client.Clients; +public class TimeSeriesClient : BaseClient, ITimeSeriesClient where TDto : class, new() +{ + private readonly IRefitTimeSeriesClient timeSeriesClient; + + public TimeSeriesClient(IRefitTimeSeriesClient refitTechMessagesClient, ILogger logger) : base(logger) + { + this.timeSeriesClient = refitTechMessagesClient; + } + + public async Task AddRange(IEnumerable dtos, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await timeSeriesClient.AddRange(dtos, token), token); + + return result; + } + + public async Task> Get(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await timeSeriesClient.Get(dateBegin, dateEnd, token), token); + + return result; + } + + public async Task> GetResampledData(DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default) + { + var result = await ExecuteGetResponse>( + async () => await timeSeriesClient.GetResampledData(dateBegin, intervalSec, approxPointsCount, token), token); + + return result; + } + + public async Task GetDatesRange(CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await timeSeriesClient.GetDatesRange(token), token); + + return result; + } +} diff --git a/Persistence.Client/Clients/TimestampedSetClient.cs b/Persistence.Client/Clients/TimestampedSetClient.cs new file mode 100644 index 0000000..2e23682 --- /dev/null +++ b/Persistence.Client/Clients/TimestampedSetClient.cs @@ -0,0 +1,56 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients.Interfaces.Refit; +using Persistence.Models; + +namespace Persistence.Client.Clients; +public class TimestampedSetClient : BaseClient, ITimestampedSetClient +{ + private readonly IRefitTimestampedSetClient refitTimestampedSetClient; + + public TimestampedSetClient(IRefitTimestampedSetClient refitTimestampedSetClient, ILogger logger) : base(logger) + { + this.refitTimestampedSetClient = refitTimestampedSetClient; + } + + public async Task AddRange(Guid idDiscriminator, IEnumerable sets, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitTimestampedSetClient.AddRange(idDiscriminator, sets, token), token); + + return result; + } + + public async Task> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTimestampedSetClient.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token), token); + + return result; + } + + public async Task> GetLast(Guid idDiscriminator, IEnumerable? columnNames, int take, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitTimestampedSetClient.GetLast(idDiscriminator, columnNames, take, token), token); + + return result; + } + + public async Task Count(Guid idDiscriminator, CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitTimestampedSetClient.Count(idDiscriminator, token), token); + + return result; + } + + public async Task GetDatesRange(Guid idDiscriminator, CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitTimestampedSetClient.GetDatesRange(idDiscriminator, token), token); + + return result; + } +} diff --git a/Persistence.Client/CustomExceptions/AcceptableException.cs b/Persistence.Client/CustomExceptions/AcceptableException.cs new file mode 100644 index 0000000..0bdea54 --- /dev/null +++ b/Persistence.Client/CustomExceptions/AcceptableException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Not Acceptable (406) +/// +public class AcceptableException : Exception +{ + public AcceptableException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/BadGatewayException.cs b/Persistence.Client/CustomExceptions/BadGatewayException.cs new file mode 100644 index 0000000..2730140 --- /dev/null +++ b/Persistence.Client/CustomExceptions/BadGatewayException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Bad gateway (502) +/// +public class BadGatewayException : Exception +{ + public BadGatewayException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/ForbiddenException.cs b/Persistence.Client/CustomExceptions/ForbiddenException.cs new file mode 100644 index 0000000..bfd9e7d --- /dev/null +++ b/Persistence.Client/CustomExceptions/ForbiddenException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Forbidden (403) +/// +public class ForbiddenException : Exception +{ + public ForbiddenException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/InternalServerException.cs b/Persistence.Client/CustomExceptions/InternalServerException.cs new file mode 100644 index 0000000..6e8265b --- /dev/null +++ b/Persistence.Client/CustomExceptions/InternalServerException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Internal Server Error (500) +/// +public class InternalServerException : Exception +{ + public InternalServerException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/LockedException.cs b/Persistence.Client/CustomExceptions/LockedException.cs new file mode 100644 index 0000000..c24dca4 --- /dev/null +++ b/Persistence.Client/CustomExceptions/LockedException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Locked (423) +/// +public class LockedException : Exception +{ + public LockedException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/ServiceUnavailableException.cs b/Persistence.Client/CustomExceptions/ServiceUnavailableException.cs new file mode 100644 index 0000000..3929d42 --- /dev/null +++ b/Persistence.Client/CustomExceptions/ServiceUnavailableException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Service Unavailable Error (503) +/// +public class ServiceUnavailableException : Exception +{ + public ServiceUnavailableException(string message) + : base(message) { } +} diff --git a/Persistence.Client/CustomExceptions/TooManyRequestsException.cs b/Persistence.Client/CustomExceptions/TooManyRequestsException.cs new file mode 100644 index 0000000..d28f642 --- /dev/null +++ b/Persistence.Client/CustomExceptions/TooManyRequestsException.cs @@ -0,0 +1,10 @@ +namespace Persistence.Client.CustomExceptions; + +/// +/// Too Many Requests (429) +/// +public class TooManyRequestsException : Exception +{ + public TooManyRequestsException(string message) + : base(message) { } +} diff --git a/Persistence.Client/Helpers/ApiTokenHelper.cs b/Persistence.Client/Helpers/ApiTokenHelper.cs index 5eed66e..de163a9 100644 --- a/Persistence.Client/Helpers/ApiTokenHelper.cs +++ b/Persistence.Client/Helpers/ApiTokenHelper.cs @@ -27,6 +27,11 @@ public static class ApiTokenHelper httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken); } + public static void Authorize(this HttpClient httpClient, string jwtToken) + { + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken); + } + private static string CreateDefaultJwtToken(this AuthUser authUser) { var nameIdetifier = Guid.NewGuid().ToString(); diff --git a/Persistence.Client/Helpers/ExceptionsHelper.cs b/Persistence.Client/Helpers/ExceptionsHelper.cs new file mode 100644 index 0000000..8c349ba --- /dev/null +++ b/Persistence.Client/Helpers/ExceptionsHelper.cs @@ -0,0 +1,33 @@ +using System.ComponentModel.DataAnnotations; +using Persistence.Client.CustomExceptions; +using Refit; + +namespace Persistence.Client.Helpers; +public static class ExceptionsHelper +{ + private static readonly Dictionary ExceptionsDictionary = new Dictionary() + { + { System.Net.HttpStatusCode.BadRequest, new ValidationException("Ошибка валидации, формата или маршрутизации запроса") }, + { System.Net.HttpStatusCode.Unauthorized, new UnauthorizedAccessException("Ошибка авторизации, клиент должен аутентифицировать себя, чтобы получить запрошенный ответ") }, + { System.Net.HttpStatusCode.Forbidden, new ForbiddenException("Клиент известен серверу, но он неавторизован") }, + { System.Net.HttpStatusCode.NotFound, new EntryPointNotFoundException("Сервер не может найти запрошенный ресурс") }, + { System.Net.HttpStatusCode.MethodNotAllowed, new MethodAccessException("Обращение запрещено") }, + { System.Net.HttpStatusCode.NotAcceptable, new AcceptableException("После выполнения согласования контента не найдено содержимого, соответствующего заданным критериям") }, + { System.Net.HttpStatusCode.RequestTimeout, new TimeoutException("Время ожидания истекло") }, + { System.Net.HttpStatusCode.Locked, new LockedException("Запрашиваемый ресурс заблокирован") }, + { System.Net.HttpStatusCode.TooManyRequests, new TooManyRequestsException("Пользователь отправил слишком много запросов в определённый промежуток времени") }, + { System.Net.HttpStatusCode.InternalServerError, new InternalServerException("На сервере произошла ошибка, в результате которой он не может успешно обработать запрос") }, + { System.Net.HttpStatusCode.NotImplemented, new NotImplementedException("Метод запроса не поддерживается сервером") }, + { System.Net.HttpStatusCode.BadGateway, new BadGatewayException("В процессе обработки запроса полуен недопустимый ответ от целевого сервера") }, + { System.Net.HttpStatusCode.ServiceUnavailable, new ServiceUnavailableException("В процессе обработки запроса полуен недопустимый ответ от целевого сервера") }, + { System.Net.HttpStatusCode.GatewayTimeout, new TimeoutException("Время ожидания целевого сервера истекло") } + }; + + public static Exception GetPersistenceException(this IApiResponse response) + { + var exception = ExceptionsDictionary + .FirstOrDefault(e => e.Key == response.StatusCode).Value ?? new Exception("Неопознанная ошибка"); + + return exception; + } +} diff --git a/Persistence.Client/Persistence.Client.csproj b/Persistence.Client/Persistence.Client.csproj index d699df7..72aa381 100644 --- a/Persistence.Client/Persistence.Client.csproj +++ b/Persistence.Client/Persistence.Client.csproj @@ -18,8 +18,4 @@ - - - - diff --git a/Persistence.Client/PersistenceClientFactory.cs b/Persistence.Client/PersistenceClientFactory.cs index e84327d..26fb09d 100644 --- a/Persistence.Client/PersistenceClientFactory.cs +++ b/Persistence.Client/PersistenceClientFactory.cs @@ -1,7 +1,12 @@ using System.Text.Json; using Microsoft.Extensions.Configuration; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients; using Persistence.Client.Helpers; using Refit; +using Persistence.Factories; +using Persistence.Client.Clients.Interfaces.Refit; +using Microsoft.Extensions.Logging; namespace Persistence.Client { @@ -16,17 +21,75 @@ namespace Persistence.Client PropertyNameCaseInsensitive = true }; private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions)); + private readonly ILogger logger; private HttpClient httpClient; - public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IConfiguration configuration) + public PersistenceClientFactory(IHttpClientFactory httpClientFactory, ILogger logger, IConfiguration configuration) { - this.httpClient = httpClientFactory.CreateClient(); + this.logger = logger; + + httpClient = httpClientFactory.CreateClient(); httpClient.Authorize(configuration); } - public T GetClient() + public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IAuthTokenFactory authTokenFactory, ILogger logger, IConfiguration configuration) { - return RestService.For(httpClient, RefitSettings); + this.logger = logger; + + httpClient = httpClientFactory.CreateClient(); + + var token = authTokenFactory.GetToken(); + httpClient.Authorize(token); + } + + /// + /// Получить клиент для работы с уставками + /// + /// + public ISetpointClient GetSetpointClient() + { + var restClient = RestService.For(httpClient, RefitSettings); + var client = new SetpointClient(restClient, logger); + + return client; + } + + /// + /// Получить клиент для работы с технологическими сообщениями + /// + /// + public ITechMessagesClient GetTechMessagesClient() + { + var restClient = RestService.For(httpClient, RefitSettings); + var client = new TechMessagesClient(restClient, logger); + + return client; + } + + /// + /// Получить клиент для работы с временными данными + /// + /// + /// + public ITimeSeriesClient GetTimeSeriesClient() + where TDto : class, new() + { + var restClient = RestService.For>(httpClient, RefitSettings); + var client = new TimeSeriesClient(restClient, logger); + + return client; + } + + /// + /// Получить клиент для работы с данными с отметкой времени + /// + /// + public ITimestampedSetClient GetTimestampedSetClient() + { + var restClient = RestService.For(httpClient, RefitSettings); + var client = new TimestampedSetClient(restClient, logger); + + return client; } } } diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs index 2c455a0..c52b530 100644 --- a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -1,8 +1,6 @@ -using System.Net; -using Microsoft.AspNetCore.Mvc.TagHelpers.Cache; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Persistence.Client; -using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Database.Model; using Xunit; @@ -22,7 +20,7 @@ namespace Persistence.IntegrationTests.Controllers var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - setpointClient = persistenceClientFactory.GetClient(); + setpointClient = persistenceClientFactory.GetSetpointClient(); } [Fact] @@ -36,12 +34,11 @@ namespace Persistence.IntegrationTests.Controllers }; //act - var response = await setpointClient.GetCurrent(setpointKeys); + var response = await setpointClient.GetCurrent(setpointKeys, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -51,13 +48,12 @@ namespace Persistence.IntegrationTests.Controllers var setpointKey = await Add(); //act - var response = await setpointClient.GetCurrent([setpointKey]); + var response = await setpointClient.GetCurrent([setpointKey], new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); - Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key); + Assert.NotNull(response); + Assert.NotEmpty(response); + Assert.Equal(setpointKey, response.FirstOrDefault()?.Key); } [Fact] @@ -72,12 +68,11 @@ namespace Persistence.IntegrationTests.Controllers var historyMoment = DateTimeOffset.UtcNow; //act - var response = await setpointClient.GetHistory(setpointKeys, historyMoment); + var response = await setpointClient.GetHistory(setpointKeys, historyMoment, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -89,13 +84,12 @@ namespace Persistence.IntegrationTests.Controllers historyMoment = historyMoment.AddDays(1); //act - var response = await setpointClient.GetHistory([setpointKey], historyMoment); + var response = await setpointClient.GetHistory([setpointKey], historyMoment, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); - Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key); + Assert.NotNull(response); + Assert.NotEmpty(response); + Assert.Equal(setpointKey, response.FirstOrDefault()?.Key); } [Fact] @@ -109,12 +103,11 @@ namespace Persistence.IntegrationTests.Controllers }; //act - var response = await setpointClient.GetLog(setpointKeys); + var response = await setpointClient.GetLog(setpointKeys, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -124,13 +117,12 @@ namespace Persistence.IntegrationTests.Controllers var setpointKey = await Add(); //act - var response = await setpointClient.GetLog([setpointKey]); + var response = await setpointClient.GetLog([setpointKey], new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); - Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key); + Assert.NotNull(response); + Assert.NotEmpty(response); + Assert.Equal(setpointKey, response.FirstOrDefault().Key); } [Fact] @@ -143,10 +135,9 @@ namespace Persistence.IntegrationTests.Controllers var response = await setpointClient.GetDatesRangeAsync(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Equal(DateTimeOffset.MinValue, response.Content!.From); - Assert.Equal(DateTimeOffset.MaxValue, response.Content!.To); + Assert.NotNull(response); + Assert.Equal(DateTimeOffset.MinValue, response!.From); + Assert.Equal(DateTimeOffset.MaxValue, response!.To); } [Fact] @@ -165,17 +156,16 @@ namespace Persistence.IntegrationTests.Controllers var response = await setpointClient.GetDatesRangeAsync(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); + Assert.NotNull(response); - var expectedValue = part.Content! + var expectedValue = part! .FirstOrDefault()!.Created .ToString("dd.MM.yyyy-HH:mm:ss"); - var actualValueFrom = response.Content.From + var actualValueFrom = response.From .ToString("dd.MM.yyyy-HH:mm:ss"); Assert.Equal(expectedValue, actualValueFrom); - var actualValueTo = response.Content.To + var actualValueTo = response.To .ToString("dd.MM.yyyy-HH:mm:ss"); Assert.Equal(expectedValue, actualValueTo); } @@ -191,9 +181,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -208,9 +197,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await setpointClient.GetPart(dateBegin, take, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); + Assert.NotNull(response); + Assert.NotEmpty(response); } [Fact] @@ -230,10 +218,7 @@ namespace Persistence.IntegrationTests.Controllers }; //act - var response = await setpointClient.Add(setpointKey, setpointValue); - - //assert - Assert.Equal(HttpStatusCode.Created, response.StatusCode); + await setpointClient.Add(setpointKey, setpointValue, new CancellationToken()); return setpointKey; } diff --git a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs index 1f194ad..6fdae61 100644 --- a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs @@ -1,8 +1,7 @@ -using System.Net; -using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Persistence.Client; -using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Database.Entity; using Persistence.Models; using Xunit; @@ -20,7 +19,7 @@ namespace Persistence.IntegrationTests.Controllers var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - techMessagesClient = persistenceClientFactory.GetClient(); + techMessagesClient = persistenceClientFactory.GetTechMessagesClient(); memoryCache = scope.ServiceProvider.GetRequiredService(); } @@ -43,11 +42,10 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetPage(requestDto, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content.Items); - Assert.Equal(requestDto.Skip, response.Content.Skip); - Assert.Equal(requestDto.Take, response.Content.Take); + Assert.NotNull(response); + Assert.Empty(response.Items); + Assert.Equal(requestDto.Skip, response.Skip); + Assert.Equal(requestDto.Take, response.Take); } [Fact] @@ -67,9 +65,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetPage(requestDto, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Equal(dtosCount, response.Content.Count); + Assert.NotNull(response); + Assert.Equal(dtosCount, response.Count); } [Fact] @@ -82,6 +79,7 @@ namespace Persistence.IntegrationTests.Controllers public async Task InsertRange_returns_BadRequest() { //arrange + var exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса"; var dtos = new List() { new TechMessageDto() @@ -96,11 +94,16 @@ namespace Persistence.IntegrationTests.Controllers } }; - //act - var response = await techMessagesClient.AddRange(dtos, new CancellationToken()); - - //assert - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + try + { + //act + var response = await techMessagesClient.AddRange(dtos, new CancellationToken()); + } + catch (Exception ex) + { + //assert + Assert.Equal(exceptionMessage, ex.Message); + } } [Fact] @@ -115,9 +118,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetSystems(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -134,9 +136,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetSystems(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - string?[]? content = response.Content?.ToArray(); + Assert.NotNull(response); + string?[]? content = response?.ToArray(); Assert.Equal(systems, content); } @@ -155,9 +156,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -173,9 +173,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var categories = response.Content + Assert.NotNull(response); + var categories = response .FirstOrDefault()?.Categories .FirstOrDefault(e => e.Key == 0).Value; Assert.Equal(filteredDtos.Count(), categories); @@ -184,14 +183,18 @@ namespace Persistence.IntegrationTests.Controllers [Fact] public async Task GetDatesRange_returns_success() { + //arrange + memoryCache.Remove(SystemCacheKey); + dbContext.CleanupDbSet(); + dbContext.CleanupDbSet(); + //act var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - //Assert.Equal(DateTimeOffset.MinValue, response.Content?.From); - //Assert.Equal(DateTimeOffset.MaxValue, response.Content?.To); + Assert.NotNull(response); + Assert.Equal(DateTimeOffset.MinValue, response?.From); + Assert.Equal(DateTimeOffset.MaxValue, response?.To); } [Fact] @@ -204,10 +207,9 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetDatesRangeAsync(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotNull(response.Content?.From); - Assert.NotNull(response.Content?.To); + Assert.NotNull(response); + Assert.NotNull(response?.From); + Assert.NotNull(response?.To); } [Fact] @@ -221,9 +223,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -238,9 +239,8 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.GetPart(dateBegin, take, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); + Assert.NotNull(response); + Assert.NotEmpty(response); } private async Task> InsertRange() @@ -279,8 +279,7 @@ namespace Persistence.IntegrationTests.Controllers var response = await techMessagesClient.AddRange(dtos, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.Created, response.StatusCode); - Assert.Equal(dtos.Count, response.Content); + Assert.Equal(dtos.Count, response); return dtos; } diff --git a/Persistence.IntegrationTests/Controllers/TimeSeriesBaseControllerTest.cs b/Persistence.IntegrationTests/Controllers/TimeSeriesBaseControllerTest.cs index 08bb11e..ca9536f 100644 --- a/Persistence.IntegrationTests/Controllers/TimeSeriesBaseControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/TimeSeriesBaseControllerTest.cs @@ -2,7 +2,7 @@ using System.Net; using Mapster; using Microsoft.Extensions.DependencyInjection; using Persistence.Client; -using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Database.Model; using Xunit; @@ -21,7 +21,7 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - timeSeriesClient = persistenceClientFactory.GetClient>(); + timeSeriesClient = persistenceClientFactory.GetTimeSeriesClient(); } public async Task InsertRangeSuccess(TDto dto) @@ -30,11 +30,10 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat var expected = dto.Adapt(); //act - var response = await timeSeriesClient.AddRange(new TDto[] { expected }); + var response = await timeSeriesClient.AddRange(new TDto[] { expected }, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(1, response.Content); + Assert.Equal(1, response); } public async Task GetSuccess(DateTimeOffset beginDate, DateTimeOffset endDate, TEntity entity) @@ -46,12 +45,11 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat dbContext.SaveChanges(); - var response = await timeSeriesClient.Get(beginDate, endDate); + var response = await timeSeriesClient.Get(beginDate, endDate, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Single(response.Content); + Assert.NotNull(response); + Assert.Single(response); } public async Task GetDatesRangeSuccess(TEntity entity) @@ -68,13 +66,12 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat dbContext.SaveChanges(); - var response = await timeSeriesClient.GetDatesRange(); + var response = await timeSeriesClient.GetDatesRange(new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); + Assert.NotNull(response); - var datesRangeActual = (response.Content.To - response.Content.From).Days; + var datesRangeActual = (response.To - response.From).Days; Assert.Equal(datesRangeExpected, datesRangeActual); } @@ -98,11 +95,10 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat dbContext.SaveChanges(); - var response = await timeSeriesClient.GetResampledData(entity.Date.AddMinutes(-1), differenceBetweenStartAndEndDays * 24 * 60 * 60 + 60, approxPointsCount); + var response = await timeSeriesClient.GetResampledData(entity.Date.AddMinutes(-1), differenceBetweenStartAndEndDays * 24 * 60 * 60 + 60, approxPointsCount, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); + Assert.NotNull(response); var ratio = entities.Count() / approxPointsCount; if (ratio > 1) @@ -111,15 +107,11 @@ public abstract class TimeSeriesBaseControllerTest : BaseIntegrat .Where((_, index) => index % ratio == 0) .Count(); - Assert.Equal(expectedResampledCount, response.Content.Count()); + Assert.Equal(expectedResampledCount, response.Count()); } else { - Assert.Equal(entities.Count(), response.Content.Count()); + Assert.Equal(entities.Count(), response.Count()); } - - } - - } diff --git a/Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs b/Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs index 3fc7dff..2d52a49 100644 --- a/Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Persistence.Client; -using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Models; using Xunit; @@ -14,7 +14,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - client = persistenceClientFactory.GetClient(); + client = persistenceClientFactory.GetTimestampedSetClient(); } [Fact] @@ -25,11 +25,10 @@ public class TimestampedSetControllerTest : BaseIntegrationTest IEnumerable testSets = Generate(10, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); // act - var response = await client.AddRange(idDiscriminator, testSets); + var response = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.Equal(testSets.Count(), response.Content); + Assert.Equal(testSets.Count(), response); } [Fact] @@ -39,16 +38,14 @@ public class TimestampedSetControllerTest : BaseIntegrationTest Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); // act - var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue); + var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(count, items.Count()); + Assert.NotNull(response); + Assert.Equal(count, response.Count()); } [Fact] @@ -58,26 +55,24 @@ public class TimestampedSetControllerTest : BaseIntegrationTest Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); string[] props = ["A"]; // act - var response = await client.Get(idDiscriminator, null, props, 0, int.MaxValue); + var response = await client.Get(idDiscriminator, null, props, 0, int.MaxValue, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(count, items.Count()); - foreach ( var item in items ) - { - Assert.Single(item.Set); - var kv = item.Set.First(); - Assert.Equal("A", kv.Key); - } - } + Assert.NotNull(response); + Assert.Equal(count, response.Count()); + foreach ( var item in response ) + { + Assert.Single(item.Set); + var kv = item.Set.First(); + Assert.Equal("A", kv.Key); + } + } - [Fact] + [Fact] public async Task Get_geDate() { // arrange @@ -86,21 +81,19 @@ public class TimestampedSetControllerTest : BaseIntegrationTest var dateMin = DateTimeOffset.Now; var dateMax = DateTimeOffset.Now.AddSeconds(count); IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue); var geDate = tail.First().Timestamp; var tolerance = TimeSpan.FromSeconds(1); var expectedCount = tail.Count(); // act - var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue); + var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(expectedCount, items.Count()); - var minDate = items.Min(t => t.Timestamp); + Assert.NotNull(response); + Assert.Equal(expectedCount, response.Count()); + var minDate = response.Min(t => t.Timestamp); Assert.Equal(geDate, geDate, tolerance); } @@ -111,21 +104,19 @@ public class TimestampedSetControllerTest : BaseIntegrationTest Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); var expectedCount = count / 2; // act - var response = await client.Get(idDiscriminator, null, null, 2, expectedCount); + var response = await client.Get(idDiscriminator, null, null, 2, expectedCount, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(expectedCount, items.Count()); - } + Assert.NotNull(response); + Assert.Equal(expectedCount, response.Count()); + } - [Fact] + [Fact] public async Task Get_with_big_skip_take() { // arrange @@ -133,16 +124,14 @@ public class TimestampedSetControllerTest : BaseIntegrationTest var expectedCount = 1; int count = 10 + expectedCount; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); // act - var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count); + var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(expectedCount, items.Count()); + Assert.NotNull(response); + Assert.Equal(expectedCount, response.Count()); } [Fact] @@ -152,17 +141,15 @@ public class TimestampedSetControllerTest : BaseIntegrationTest Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); var expectedCount = 8; // act - var response = await client.GetLast(idDiscriminator, null, expectedCount); + var response = await client.GetLast(idDiscriminator, null, expectedCount, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var items = response.Content!; - Assert.Equal(expectedCount, items.Count()); + Assert.NotNull(response); + Assert.Equal(expectedCount, response.Count()); } [Fact] @@ -174,18 +161,16 @@ public class TimestampedSetControllerTest : BaseIntegrationTest var dateMin = DateTimeOffset.Now; var dateMax = DateTimeOffset.Now.AddSeconds(count-1); IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); var tolerance = TimeSpan.FromSeconds(1); // act - var response = await client.GetDatesRange(idDiscriminator); + var response = await client.GetDatesRange(idDiscriminator, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - var range = response.Content!; - Assert.Equal(dateMin, range.From, tolerance); - Assert.Equal(dateMax, range.To, tolerance); + Assert.NotNull(response); + Assert.Equal(dateMin, response.From, tolerance); + Assert.Equal(dateMax, response.To, tolerance); } [Fact] @@ -195,14 +180,13 @@ public class TimestampedSetControllerTest : BaseIntegrationTest Guid idDiscriminator = Guid.NewGuid(); int count = 144; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); - var insertResponse = await client.AddRange(idDiscriminator, testSets); + var insertResponse = await client.AddRange(idDiscriminator, testSets, new CancellationToken()); // act - var response = await client.Count(idDiscriminator); + var response = await client.Count(idDiscriminator, new CancellationToken()); // assert - Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); - Assert.Equal(count, response.Content); + Assert.Equal(count, response); } private static IEnumerable Generate(int n, DateTimeOffset from) diff --git a/Persistence.IntegrationTests/WebAppFactoryFixture.cs b/Persistence.IntegrationTests/WebAppFactoryFixture.cs index 7b12362..1410b04 100644 --- a/Persistence.IntegrationTests/WebAppFactoryFixture.cs +++ b/Persistence.IntegrationTests/WebAppFactoryFixture.cs @@ -4,8 +4,8 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; using Persistence.API; -using Persistence.Database; using Persistence.Client; using Persistence.Database.Model; using Persistence.Database.Postgres; @@ -34,6 +34,8 @@ public class WebAppFactoryFixture : WebApplicationFactory services.AddDbContext(options => options.UseNpgsql(connectionString)); + services.AddLogging(builder => builder.AddConsole()); + services.RemoveAll(); services.AddSingleton(provider => { diff --git a/Persistence/Factories/IAuthTokenFactory.cs b/Persistence/Factories/IAuthTokenFactory.cs new file mode 100644 index 0000000..2b12095 --- /dev/null +++ b/Persistence/Factories/IAuthTokenFactory.cs @@ -0,0 +1,13 @@ +namespace Persistence.Factories; + +/// +/// Фабрика токенов аутентификации +/// +public interface IAuthTokenFactory +{ + /// + /// Получить токен + /// + /// + public string GetToken(); +} From 237ff192f100bce428f3d72310e84f8e9206dab8 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 9 Dec 2024 17:11:39 +0500 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BB=D1=8F=20Persistence.Client=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B8=D1=82=D1=8C=20NuGet?= =?UTF-8?q?=20+=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20readm?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Persistence.Client.csproj | 36 ++++++++++++++++ Persistence.Client/Readme.md | 45 ++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 Persistence.Client/Readme.md diff --git a/Persistence.Client/Persistence.Client.csproj b/Persistence.Client/Persistence.Client.csproj index 72aa381..b764e7a 100644 --- a/Persistence.Client/Persistence.Client.csproj +++ b/Persistence.Client/Persistence.Client.csproj @@ -4,8 +4,44 @@ net8.0 enable enable + + + True + + Persistence.Client + + 1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)) + + 1.0.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)) + + Persistence.Client + + + Digital Drilling + + Digital Drilling + + Пакет для получения клиентов для работы с Persistence сервисом + + + https://git.ddrilling.ru/on.nemtina/persistence.git + + git + + true + + snupkg + + C:\Projects\Nuget + + + Readme.md + + + + diff --git a/Persistence.Client/Readme.md b/Persistence.Client/Readme.md new file mode 100644 index 0000000..76e862a --- /dev/null +++ b/Persistence.Client/Readme.md @@ -0,0 +1,45 @@ +# Persistence Client Nuget Readme +## Краткое описание Persistence сервиса +Persistence сервис отвечает за работу с хранимыми данными +в рамках совокупности различных систем. + +## Описание пакета +Данный пакет предоставляет возможность взаимодействия с +Persistence сервисом посредством обращения к конкретному +клиенту, ответсвенному за работу с одной из областей сервиса. + +## Список предоставляемых клиентов +- `ISetpointClient` - Клиент для работы с уставками +- `ITechMessagesClient` - Клиент для работы с технологическими сообщениями +- `ITimeSeriesClient` - Клиент для работы с временными данными +- `ITimestampedSetClient` - Клиент для работы с данными с отметкой времени + +## Использование +Для получения того или иного Persistence - клиента нужно +обращаться к фабрике Persistence клиентов - `PersistenceClientFactory`. Для этого требуется: +1. Добавить в проект фабрику HTTP - клиентов `IHttpClientFactory`. +
Она должна предоставлять HTTP - клиента через метод `GetClient()`. +>В том случае, если фабрика клиентов предоставляет не авторизованного клиента - +необходимо добавить в проект фабрику токенов аутентификации `IAuthTokenFactory` с методом `GetToken()`, +возвращающем токен в виде строки (без префикса `Bearer`). + +2. Добавить логирование `ILoger` +3. Внедрить зависимость в проект `services.AddSingleton();` - пример. +4. Обратиться к фабрике Persistence - клиентов и получить требуемого клиента. + +## xunit тестирование +При написании интеграционных тестов с ипользованием Persistence - клиентов +Http - клиент не обязан быть авторизован через передачу токена в `PersistenceClientFactory`. +Для осуществления тестовой авторизации достаточно добавить в `appsettings.Tests.json`. +При этом возможна авторизация через `KeyCloak`. +```json +"NeedUseKeyCloak": false, + "AuthUser": { + "username": "myuser", + "password": 12345, + "clientId": "webapi", + "grantType": "password" + }, + "KeycloakGetTokenUrl": "http://192.168.0.10:8321/realms/Persistence/protocol/openid-connect/token" +``` + From b6c75e381659c53809150e8c35b14fe51772f953 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Tue, 10 Dec 2024 13:55:01 +0500 Subject: [PATCH 3/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D0=B8=D1=81=D1=8F=D0=BC=D0=B8=20ChangeLog.=20?= =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Clients/Base/BaseClient.cs | 4 +- Persistence.Client/Clients/ChangeLogClient.cs | 102 +++++++++++++++++ .../Clients/IChangeLogClient.cs | 106 ------------------ .../Clients/Interfaces/IChangeLogClient.cs | 98 ++++++++++++++++ .../Clients/Interfaces/ISetpointClient.cs | 2 +- .../Clients/Interfaces/ITechMessagesClient.cs | 5 +- .../Clients/Interfaces/ITimeSeriesClient.cs | 2 +- .../Interfaces/ITimestampedSetClient.cs | 7 +- .../Interfaces/Refit/IRefitChangeLogClient.cs | 46 ++++++++ .../Interfaces/Refit/IRefitSetpointClient.cs | 5 +- .../Refit/IRefitTechMessagesClient.cs | 8 +- .../Refit/IRefitTimeSeriesClient.cs | 4 +- .../Refit/IRefitTimestampedSetClient.cs | 40 +------ Persistence.Client/Clients/SetpointClient.cs | 7 +- .../Clients/TechMessagesClient.cs | 10 +- .../Clients/TimeSeriesClient.cs | 7 +- .../Clients/TimestampedSetClient.cs | 7 +- .../PersistenceClientFactory.cs | 33 +++++- Persistence.Client/Readme.md | 1 + .../Controllers/ChangeLogControllerTest.cs | 92 +++++++-------- .../Controllers/TechMessagesControllerTest.cs | 4 +- 21 files changed, 360 insertions(+), 230 deletions(-) create mode 100644 Persistence.Client/Clients/ChangeLogClient.cs delete mode 100644 Persistence.Client/Clients/IChangeLogClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/IChangeLogClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs diff --git a/Persistence.Client/Clients/Base/BaseClient.cs b/Persistence.Client/Clients/Base/BaseClient.cs index bca6f6a..2332cbd 100644 --- a/Persistence.Client/Clients/Base/BaseClient.cs +++ b/Persistence.Client/Clients/Base/BaseClient.cs @@ -3,11 +3,11 @@ using Persistence.Client.Helpers; using Refit; namespace Persistence.Client.Clients.Base; -public class BaseClient +public abstract class BaseClient { private readonly ILogger logger; - public BaseClient(ILogger logger) + public BaseClient(ILogger logger) { this.logger = logger; } diff --git a/Persistence.Client/Clients/ChangeLogClient.cs b/Persistence.Client/Clients/ChangeLogClient.cs new file mode 100644 index 0000000..00aee71 --- /dev/null +++ b/Persistence.Client/Clients/ChangeLogClient.cs @@ -0,0 +1,102 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Models; +using Persistence.Models.Requests; + +namespace Persistence.Client.Clients; +public class ChangeLogClient : BaseClient, IChangeLogClient +{ + private readonly Interfaces.Refit.IRefitChangeLogClient refitChangeLogClient; + + public ChangeLogClient(Interfaces.Refit.IRefitChangeLogClient refitChangeLogClient, ILogger logger) : base(logger) + { + this.refitChangeLogClient = refitChangeLogClient; + } + + public async Task ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitChangeLogClient.ClearAndAddRange(idDiscriminator, dtos, token), token); + + return result; + } + + public async Task> GetByDate(Guid idDiscriminator, DateTimeOffset moment, + SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitChangeLogClient.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, token), token); + + return result; + } + + public async Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitChangeLogClient.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token), token); + + return result; + } + + public async Task Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.Add(idDiscriminator, dto, token), token); + + return result; + } + + public async Task AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.AddRange(idDiscriminator, dtos, token), token); + + return result; + } + + public async Task Update(DataWithWellDepthAndSectionDto dto, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.Update(dto, token), token); + + return result; + } + + public async Task UpdateRange(IEnumerable dtos, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.UpdateRange(dtos, token), token); + + return result; + } + + public async Task Delete(Guid id, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.Delete(id, token), token); + + return result; + } + + public async Task DeleteRange(IEnumerable ids, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitChangeLogClient.DeleteRange(ids, token), token); + + return result; + } + + public async Task GetDatesRange(Guid idDiscriminator, CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitChangeLogClient.GetDatesRange(idDiscriminator, token), token); + + return result; + } + + public void Dispose() + { + refitChangeLogClient.Dispose(); + } +} diff --git a/Persistence.Client/Clients/IChangeLogClient.cs b/Persistence.Client/Clients/IChangeLogClient.cs deleted file mode 100644 index 06bbc4d..0000000 --- a/Persistence.Client/Clients/IChangeLogClient.cs +++ /dev/null @@ -1,106 +0,0 @@ -using Persistence.Models; -using Persistence.Models.Requests; -using Refit; - -namespace Persistence.Client.Clients; - -/// -/// Интерфейс для тестирования API, предназначенного для работы с записями ChangeLod -/// -public interface IChangeLogClient -{ - private const string BaseRoute = "/api/ChangeLog"; - - /// - /// Импорт с заменой: удаление старых строк и добавление новых - /// - /// - /// - /// - [Post($"{BaseRoute}/replace/{{idDiscriminator}}")] - Task> ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos); - - /// - /// Получение актуальных данных на определенную дату (с пагинацией) - /// - /// - /// - /// параметры запроса фильтрации - /// параметры запроса пагинации - /// - [Get($"{BaseRoute}/moment/{{idDiscriminator}}")] - Task>> GetByDate( - Guid idDiscriminator, - DateTimeOffset moment, - [Query] SectionPartRequest filterRequest, - [Query] PaginationRequest paginationRequest); - - /// - /// Получение исторических данных за определенный период времени - /// - /// - /// - /// - /// - [Get($"{BaseRoute}/history/{{idDiscriminator}}")] - Task>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd); - - /// - /// Добавить одну запись - /// - /// - /// - /// - [Post($"{BaseRoute}/{{idDiscriminator}}")] - Task> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto); - - /// - /// Добавить несколько записей - /// - /// - /// - /// - [Post($"{BaseRoute}/range/{{idDiscriminator}}")] - Task> AddRange(Guid idDiscriminator, IEnumerable dtos); - - /// - /// Обновить одну запись - /// - /// - /// - [Put($"{BaseRoute}")] - Task> Update(DataWithWellDepthAndSectionDto dto); - - /// - /// Обновить несколько записей - /// - /// - /// - [Put($"{BaseRoute}/range")] - Task> UpdateRange(IEnumerable dtos); - - /// - /// Удалить одну запись - /// - /// - /// - [Delete($"{BaseRoute}")] - Task> Delete(Guid id); - - /// - /// Удалить несколько записей - /// - /// - /// - [Delete($"{BaseRoute}/range")] - Task> DeleteRange([Body] IEnumerable ids); - - /// - /// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени) - /// - /// - /// - [Get($"{BaseRoute}/datesRange/{{idDiscriminator}}")] - Task> GetDatesRange(Guid idDiscriminator); - -} diff --git a/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs b/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs new file mode 100644 index 0000000..0d24585 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs @@ -0,0 +1,98 @@ +using Persistence.Models; +using Persistence.Models.Requests; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с записями ChangeLog +/// +public interface IChangeLogClient : IDisposable +{ + /// + /// Добавить одну запись + /// + /// + /// + /// + /// + Task Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); + + /// + /// Добавить несколько записей + /// + /// + /// + /// + /// + Task AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + + /// + /// Импорт с заменой: удаление старых строк и добавление новых + /// + /// + /// + /// + /// + Task ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + + /// + /// Удалить одну запись + /// + /// + /// + /// + Task Delete(Guid id, CancellationToken token); + + /// + /// Удалить несколько записей + /// + /// + /// + /// + Task DeleteRange(IEnumerable ids, CancellationToken token); + + /// + /// Получение актуальных данных на определенную дату (с пагинацией) + /// + /// + /// + /// + /// + /// + /// + Task> GetByDate(Guid idDiscriminator, DateTimeOffset moment, SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token); + + /// + /// Получение исторических данных за определенный период времени + /// + /// + /// + /// + /// + /// + Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); + + /// + /// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени) + /// + /// + /// + /// + Task GetDatesRange(Guid idDiscriminator, CancellationToken token); + + /// + /// Обновить одну запись + /// + /// + /// + /// + Task Update(DataWithWellDepthAndSectionDto dto, CancellationToken token); + + /// + /// Обновить несколько записей + /// + /// + /// + /// + Task UpdateRange(IEnumerable dtos, CancellationToken token); +} \ No newline at end of file diff --git a/Persistence.Client/Clients/Interfaces/ISetpointClient.cs b/Persistence.Client/Clients/Interfaces/ISetpointClient.cs index 19c5902..295ab87 100644 --- a/Persistence.Client/Clients/Interfaces/ISetpointClient.cs +++ b/Persistence.Client/Clients/Interfaces/ISetpointClient.cs @@ -5,7 +5,7 @@ namespace Persistence.Client.Clients.Interfaces; /// /// Клиент для работы с уставками /// -public interface ISetpointClient +public interface ISetpointClient : IDisposable { /// /// Добавить уставку diff --git a/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs b/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs index 8da559c..bbf635c 100644 --- a/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs +++ b/Persistence.Client/Clients/Interfaces/ITechMessagesClient.cs @@ -1,11 +1,12 @@ using Persistence.Models; +using Persistence.Models.Requests; namespace Persistence.Client.Clients.Interfaces; /// /// Клиент для работы с технологическими сообщениями /// -public interface ITechMessagesClient +public interface ITechMessagesClient : IDisposable { /// /// Добавить новые технологические сообщения @@ -28,7 +29,7 @@ public interface ITechMessagesClient /// /// /// - Task> GetPage(RequestDto request, CancellationToken token); + Task> GetPage(PaginationRequest request, CancellationToken token); /// /// Получить порцию записей, начиная с заданной даты diff --git a/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs b/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs index d6dd199..316c0c9 100644 --- a/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs +++ b/Persistence.Client/Clients/Interfaces/ITimeSeriesClient.cs @@ -6,7 +6,7 @@ namespace Persistence.Client.Clients.Interfaces; /// Клиент для работы с временными данными /// /// -public interface ITimeSeriesClient where TDto : class, new() +public interface ITimeSeriesClient : IDisposable where TDto : class, new() { /// /// Добавление записей diff --git a/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs b/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs index ee0ca6e..21fd222 100644 --- a/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs +++ b/Persistence.Client/Clients/Interfaces/ITimestampedSetClient.cs @@ -3,9 +3,12 @@ namespace Persistence.Client.Clients.Interfaces; /// -/// Клиент для работы с данными с отметкой времени +/// Клиент для работы с репозиторием для хранения разных наборов данных рядов. +/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest. +/// idDiscriminator формируют клиенты и только им известно что они обозначают. +/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено. /// -public interface ITimestampedSetClient +public interface ITimestampedSetClient : IDisposable { /// /// Записать новые данные diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs new file mode 100644 index 0000000..8408d7e --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs @@ -0,0 +1,46 @@ +using Persistence.Models; +using Persistence.Models.Requests; +using Refit; + +namespace Persistence.Client.Clients.Interfaces.Refit; + +public interface IRefitChangeLogClient : IDisposable +{ + private const string BaseRoute = "/api/ChangeLog"; + + [Post($"{BaseRoute}/replace/{{idDiscriminator}}")] + Task> ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + + [Get($"{BaseRoute}/moment/{{idDiscriminator}}")] + Task>> GetByDate( + Guid idDiscriminator, + DateTimeOffset moment, + [Query] SectionPartRequest filterRequest, + [Query] PaginationRequest paginationRequest, + CancellationToken token); + + [Get($"{BaseRoute}/history/{{idDiscriminator}}")] + Task>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); + + [Post($"{BaseRoute}/{{idDiscriminator}}")] + Task> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); + + [Post($"{BaseRoute}/range/{{idDiscriminator}}")] + Task> AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + + [Put($"{BaseRoute}")] + Task> Update(DataWithWellDepthAndSectionDto dto, CancellationToken token); + + [Put($"{BaseRoute}/range")] + Task> UpdateRange(IEnumerable dtos, CancellationToken token); + + [Delete($"{BaseRoute}")] + Task> Delete(Guid id, CancellationToken token); + + [Delete($"{BaseRoute}/range")] + Task> DeleteRange([Body] IEnumerable ids, CancellationToken token); + + [Get($"{BaseRoute}/datesRange/{{idDiscriminator}}")] + Task> GetDatesRange(Guid idDiscriminator, CancellationToken token); + +} diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs index 97baaba..69a2719 100644 --- a/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitSetpointClient.cs @@ -3,10 +3,7 @@ using Refit; namespace Persistence.Client.Clients.Interfaces.Refit; -/// -/// Интерфейс клиента для работы с уставками -/// -public interface IRefitSetpointClient +public interface IRefitSetpointClient : IDisposable { private const string BaseRoute = "/api/setpoint"; diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs index 68968a1..64cb49e 100644 --- a/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTechMessagesClient.cs @@ -1,17 +1,15 @@ using Persistence.Models; +using Persistence.Models.Requests; using Refit; namespace Persistence.Client.Clients.Interfaces.Refit { - /// - /// Интерфейс клиента для хранения технологических сообщений - /// - public interface IRefitTechMessagesClient + public interface IRefitTechMessagesClient : IDisposable { private const string BaseRoute = "/api/techMessages"; [Get($"{BaseRoute}")] - Task>> GetPage([Query] RequestDto request, CancellationToken token); + Task>> GetPage([Query] PaginationRequest request, CancellationToken token); [Post($"{BaseRoute}")] Task> AddRange([Body] IEnumerable dtos, CancellationToken token); diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs index 06a1266..3deae09 100644 --- a/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimeSeriesClient.cs @@ -2,8 +2,8 @@ using Refit; namespace Persistence.Client.Clients.Interfaces.Refit; -public interface IRefitTimeSeriesClient - where TDto : class, new() +public interface IRefitTimeSeriesClient : IDisposable + where TDto : class, new() { private const string BaseRoute = "/api/dataSaub"; diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs index b379725..8caeb61 100644 --- a/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedSetClient.cs @@ -3,60 +3,22 @@ using Refit; namespace Persistence.Client.Clients.Interfaces.Refit; -/// -/// Клиент для работы с репозиторием для хранения разных наборов данных рядов. -/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest. -/// idDiscriminator формируют клиенты и только им известно что они обозначают. -/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено. -/// -public interface IRefitTimestampedSetClient +public interface IRefitTimestampedSetClient : IDisposable { private const string baseUrl = "/api/TimestampedSet/{idDiscriminator}"; - /// - /// Добавление новых данных - /// - /// Дискриминатор (идентификатор) набора - /// - /// [Post(baseUrl)] Task> AddRange(Guid idDiscriminator, IEnumerable sets, CancellationToken token); - /// - /// Получение данных с фильтрацией. Значение фильтра null - отключен - /// - /// Дискриминатор (идентификатор) набора - /// Фильтр позднее даты - /// Фильтр свойств набора. Можно запросить только некоторые свойства из набора - /// - /// - /// [Get(baseUrl)] Task>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable? columnNames, int skip, int take, CancellationToken token); - /// - /// Получить последние данные - /// - /// Дискриминатор (идентификатор) набора - /// Фильтр свойств набора. Можно запросить только некоторые свойства из набора - /// - /// [Get($"{baseUrl}/last")] Task>> GetLast(Guid idDiscriminator, [Query] IEnumerable? columnNames, int take, CancellationToken token); - /// - /// Количество записей по указанному набору в БД. Для пагинации. - /// - /// Дискриминатор (идентификатор) набора - /// [Get($"{baseUrl}/count")] Task> Count(Guid idDiscriminator, CancellationToken token); - /// - /// Диапазон дат за которые есть данные - /// - /// Дискриминатор (идентификатор) набора - /// [Get($"{baseUrl}/datesRange")] Task> GetDatesRange(Guid idDiscriminator, CancellationToken token); } diff --git a/Persistence.Client/Clients/SetpointClient.cs b/Persistence.Client/Clients/SetpointClient.cs index 91e10e2..b1df4b4 100644 --- a/Persistence.Client/Clients/SetpointClient.cs +++ b/Persistence.Client/Clients/SetpointClient.cs @@ -10,7 +10,7 @@ public class SetpointClient : BaseClient, ISetpointClient { private readonly IRefitSetpointClient refitSetpointClient; - public SetpointClient(IRefitSetpointClient refitSetpointClient, ILogger logger) : base(logger) + public SetpointClient(IRefitSetpointClient refitSetpointClient, ILogger logger) : base(logger) { this.refitSetpointClient = refitSetpointClient; } @@ -60,4 +60,9 @@ public class SetpointClient : BaseClient, ISetpointClient await ExecutePostResponse( async () => await refitSetpointClient.Add(setpointKey, newValue, token), token); } + + public void Dispose() + { + refitSetpointClient.Dispose(); + } } diff --git a/Persistence.Client/Clients/TechMessagesClient.cs b/Persistence.Client/Clients/TechMessagesClient.cs index 2a7b0e0..c1000b1 100644 --- a/Persistence.Client/Clients/TechMessagesClient.cs +++ b/Persistence.Client/Clients/TechMessagesClient.cs @@ -3,6 +3,7 @@ using Persistence.Client.Clients.Base; using Persistence.Client.Clients.Interfaces; using Persistence.Client.Clients.Interfaces.Refit; using Persistence.Models; +using Persistence.Models.Requests; namespace Persistence.Client.Clients; @@ -10,12 +11,12 @@ public class TechMessagesClient : BaseClient, ITechMessagesClient { private readonly IRefitTechMessagesClient refitTechMessagesClient; - public TechMessagesClient(IRefitTechMessagesClient refitTechMessagesClient, ILogger logger) : base(logger) + public TechMessagesClient(IRefitTechMessagesClient refitTechMessagesClient, ILogger logger) : base(logger) { this.refitTechMessagesClient = refitTechMessagesClient; } - public async Task> GetPage(RequestDto request, CancellationToken token) + public async Task> GetPage(PaginationRequest request, CancellationToken token) { var result = await ExecuteGetResponse>( async () => await refitTechMessagesClient.GetPage(request, token), token); @@ -62,4 +63,9 @@ public class TechMessagesClient : BaseClient, ITechMessagesClient return result; } + + public void Dispose() + { + refitTechMessagesClient.Dispose(); + } } diff --git a/Persistence.Client/Clients/TimeSeriesClient.cs b/Persistence.Client/Clients/TimeSeriesClient.cs index 0b49c81..a3fba7d 100644 --- a/Persistence.Client/Clients/TimeSeriesClient.cs +++ b/Persistence.Client/Clients/TimeSeriesClient.cs @@ -9,7 +9,7 @@ public class TimeSeriesClient : BaseClient, ITimeSeriesClient where { private readonly IRefitTimeSeriesClient timeSeriesClient; - public TimeSeriesClient(IRefitTimeSeriesClient refitTechMessagesClient, ILogger logger) : base(logger) + public TimeSeriesClient(IRefitTimeSeriesClient refitTechMessagesClient, ILogger> logger) : base(logger) { this.timeSeriesClient = refitTechMessagesClient; } @@ -45,4 +45,9 @@ public class TimeSeriesClient : BaseClient, ITimeSeriesClient where return result; } + + public void Dispose() + { + timeSeriesClient.Dispose(); + } } diff --git a/Persistence.Client/Clients/TimestampedSetClient.cs b/Persistence.Client/Clients/TimestampedSetClient.cs index 2e23682..4d40d8b 100644 --- a/Persistence.Client/Clients/TimestampedSetClient.cs +++ b/Persistence.Client/Clients/TimestampedSetClient.cs @@ -9,7 +9,7 @@ public class TimestampedSetClient : BaseClient, ITimestampedSetClient { private readonly IRefitTimestampedSetClient refitTimestampedSetClient; - public TimestampedSetClient(IRefitTimestampedSetClient refitTimestampedSetClient, ILogger logger) : base(logger) + public TimestampedSetClient(IRefitTimestampedSetClient refitTimestampedSetClient, ILogger logger) : base(logger) { this.refitTimestampedSetClient = refitTimestampedSetClient; } @@ -53,4 +53,9 @@ public class TimestampedSetClient : BaseClient, ITimestampedSetClient return result; } + + public void Dispose() + { + refitTimestampedSetClient.Dispose(); + } } diff --git a/Persistence.Client/PersistenceClientFactory.cs b/Persistence.Client/PersistenceClientFactory.cs index 26fb09d..bfaf6fa 100644 --- a/Persistence.Client/PersistenceClientFactory.cs +++ b/Persistence.Client/PersistenceClientFactory.cs @@ -7,6 +7,7 @@ using Refit; using Persistence.Factories; using Persistence.Client.Clients.Interfaces.Refit; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; namespace Persistence.Client { @@ -21,20 +22,20 @@ namespace Persistence.Client PropertyNameCaseInsensitive = true }; private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions)); - private readonly ILogger logger; + private readonly IServiceProvider provider; private HttpClient httpClient; - public PersistenceClientFactory(IHttpClientFactory httpClientFactory, ILogger logger, IConfiguration configuration) + public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IServiceProvider provider, IConfiguration configuration) { - this.logger = logger; + this.provider = provider; httpClient = httpClientFactory.CreateClient(); httpClient.Authorize(configuration); } - public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IAuthTokenFactory authTokenFactory, ILogger logger, IConfiguration configuration) + public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IAuthTokenFactory authTokenFactory, IServiceProvider provider, IConfiguration configuration) { - this.logger = logger; + this.provider = provider; httpClient = httpClientFactory.CreateClient(); @@ -48,6 +49,8 @@ namespace Persistence.Client /// public ISetpointClient GetSetpointClient() { + var logger = provider.GetRequiredService>(); + var restClient = RestService.For(httpClient, RefitSettings); var client = new SetpointClient(restClient, logger); @@ -60,6 +63,8 @@ namespace Persistence.Client /// public ITechMessagesClient GetTechMessagesClient() { + var logger = provider.GetRequiredService>(); + var restClient = RestService.For(httpClient, RefitSettings); var client = new TechMessagesClient(restClient, logger); @@ -74,6 +79,8 @@ namespace Persistence.Client public ITimeSeriesClient GetTimeSeriesClient() where TDto : class, new() { + var logger = provider.GetRequiredService>>(); + var restClient = RestService.For>(httpClient, RefitSettings); var client = new TimeSeriesClient(restClient, logger); @@ -86,10 +93,26 @@ namespace Persistence.Client /// public ITimestampedSetClient GetTimestampedSetClient() { + var logger = provider.GetRequiredService>(); + var restClient = RestService.For(httpClient, RefitSettings); var client = new TimestampedSetClient(restClient, logger); return client; } + + /// + /// Получить клиент для работы с записями ChangeLog + /// + /// + public IChangeLogClient GetChangeLogClient() + { + var logger = provider.GetRequiredService>(); + + var restClient = RestService.For(httpClient, RefitSettings); + var client = new ChangeLogClient(restClient, logger); + + return client; + } } } diff --git a/Persistence.Client/Readme.md b/Persistence.Client/Readme.md index 76e862a..2733b7c 100644 --- a/Persistence.Client/Readme.md +++ b/Persistence.Client/Readme.md @@ -13,6 +13,7 @@ Persistence сервисом посредством обращения к кон - `ITechMessagesClient` - Клиент для работы с технологическими сообщениями - `ITimeSeriesClient` - Клиент для работы с временными данными - `ITimestampedSetClient` - Клиент для работы с данными с отметкой времени +- `IChangeLogClient` - Клиент для работы с записями ChangeLog ## Использование Для получения того или иного Persistence - клиента нужно diff --git a/Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs b/Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs index 8c3b422..5af0122 100644 --- a/Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs @@ -2,11 +2,10 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Persistence.Client; -using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Database.Model; using Persistence.Models; using Persistence.Models.Requests; -using System.Net; using Xunit; namespace Persistence.IntegrationTests.Controllers; @@ -20,7 +19,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - client = persistenceClientFactory.GetClient(); + client = persistenceClientFactory.GetChangeLogClient(); } [Fact] @@ -31,11 +30,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest var dtos = Generate(2, DateTimeOffset.UtcNow); // act - var result = await client.ClearAndAddRange(idDiscriminator, dtos); + var result = await client.ClearAndAddRange(idDiscriminator, dtos, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(2, result.Content); + Assert.Equal(2, result); } [Fact] @@ -48,11 +46,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest var dtos = createdResult.Item2.Select(e => e.Adapt()); // act - var result = await client.ClearAndAddRange(idDiscriminator, dtos); + var result = await client.ClearAndAddRange(idDiscriminator, dtos, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(insertedCount*2, result.Content); + Assert.Equal(insertedCount*2, result); } [Fact] @@ -65,11 +62,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest var dto = dtos.FirstOrDefault()!; // act - var result = await client.Add(idDiscriminator, dto); + var result = await client.Add(idDiscriminator, dto, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.Created, result.StatusCode); - Assert.Equal(count, result.Content); + Assert.Equal(count, result); } [Fact] @@ -81,11 +77,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest var dtos = Generate(count, DateTimeOffset.UtcNow); // act - var result = await client.AddRange(idDiscriminator, dtos); + var result = await client.AddRange(idDiscriminator, dtos, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.Created, result.StatusCode); - Assert.Equal(count, result.Content); + Assert.Equal(count, result); } [Fact] @@ -95,8 +90,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest var idDiscriminator = Guid.NewGuid(); var dtos = Generate(1, DateTimeOffset.UtcNow); var dto = dtos.FirstOrDefault()!; - var result = await client.Add(idDiscriminator, dto); - Assert.Equal(HttpStatusCode.Created, result.StatusCode); + var result = await client.Add(idDiscriminator, dto, new CancellationToken()); var entity = dbContext.ChangeLog .Where(x => x.IdDiscriminator == idDiscriminator) @@ -105,27 +99,23 @@ public class ChangeLogControllerTest : BaseIntegrationTest dto.DepthEnd = dto.DepthEnd + 10; // act - result = await client.Update(dto); + result = await client.Update(dto, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(2, result.Content); + Assert.Equal(2, result); var dateBegin = DateTimeOffset.UtcNow.AddDays(-1); var dateEnd = DateTimeOffset.UtcNow.AddDays(1); - var changeLogResult = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd); - Assert.Equal(HttpStatusCode.OK, changeLogResult.StatusCode); - Assert.NotNull(changeLogResult.Content); + var changeLogResult = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, new CancellationToken()); + Assert.NotNull(changeLogResult); - var changeLogDtos = changeLogResult.Content; - - var obsoleteDto = changeLogDtos - .Where(e => e.Obsolete.HasValue) + var obsoleteDto = changeLogResult + .Where(e => e.Obsolete.HasValue) .FirstOrDefault(); - var activeDto = changeLogDtos - .Where(e => !e.Obsolete.HasValue) + var activeDto = changeLogResult + .Where(e => !e.Obsolete.HasValue) .FirstOrDefault(); if (obsoleteDto == null || activeDto == null) @@ -158,11 +148,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest }).ToArray(); // act - var result = await client.UpdateRange(dtos); + var result = await client.UpdateRange(dtos, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(count * 2, result.Content); + Assert.Equal(count * 2, result); } [Fact] @@ -176,11 +165,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest dbContext.SaveChanges(); // act - var result = await client.Delete(entity.Id); + var result = await client.Delete(entity.Id, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(1, result.Content); + Assert.Equal(1, result); } [Fact] @@ -195,11 +183,10 @@ public class ChangeLogControllerTest : BaseIntegrationTest // act var ids = entities.Select(e => e.Id); - var result = await client.DeleteRange(ids); + var result = await client.DeleteRange(ids, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(count, result.Content); + Assert.Equal(count, result); } [Fact] @@ -211,21 +198,20 @@ public class ChangeLogControllerTest : BaseIntegrationTest var entities = changeLogItems.Item2.OrderBy(e => e.Creation); // act - var result = await client.GetDatesRange(idDiscriminator); + var result = await client.GetDatesRange(idDiscriminator, new CancellationToken()); // assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.NotNull(result.Content); + Assert.NotNull(result); var minDate = entities.First().Creation; var maxDate = entities.Last().Creation; var expectedMinDate = minDate.ToUniversalTime().ToString(); - var actualMinDate = result.Content.From.ToUniversalTime().ToString(); + var actualMinDate = result.From.ToUniversalTime().ToString(); Assert.Equal(expectedMinDate, actualMinDate); var expectedMaxDate = maxDate.ToUniversalTime().ToString(); - var actualMaxDate = result.Content.To.ToUniversalTime().ToString(); + var actualMaxDate = result.To.ToUniversalTime().ToString(); Assert.Equal(expectedMaxDate, actualMaxDate); } @@ -244,7 +230,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest var ids = entities.Select(e => e.Id); var idsToDelete = ids.Skip(2); - var deletedCount = await client.DeleteRange(idsToDelete); + var deletedCount = await client.DeleteRange(idsToDelete, new CancellationToken()); var filterRequest = new SectionPartRequest() { @@ -260,16 +246,15 @@ public class ChangeLogControllerTest : BaseIntegrationTest }; var moment = DateTimeOffset.UtcNow.AddDays(16); - var result = await client.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest); + var result = await client.GetByDate(idDiscriminator, moment, filterRequest, paginationRequest, new CancellationToken()); - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.NotNull(result.Content); + Assert.NotNull(result); var restEntities = entities.Where(e => !idsToDelete.Contains(e.Id)); - Assert.Equal(restEntities.Count(), result.Content.Count); + Assert.Equal(restEntities.Count(), result.Count); var actualIds = restEntities.Select(e => e.Id); - var expectedIds = result.Content.Items.Select(e => e.Id); + var expectedIds = result.Items.Select(e => e.Id); Assert.Equivalent(expectedIds, actualIds); } @@ -297,17 +282,16 @@ public class ChangeLogControllerTest : BaseIntegrationTest entity.DepthEnd = entity.DepthEnd + 10; } var dtos = entities.Select(e => e.Adapt()).ToArray(); - await client.UpdateRange(dtos); + await client.UpdateRange(dtos, new CancellationToken()); //act var dateBegin = DateTimeOffset.UtcNow.AddDays(daysBeforeNowFilter); var dateEnd = DateTimeOffset.UtcNow.AddDays(daysAfterNowFilter); - var result = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd); + var result = await client.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, new CancellationToken()); //assert - Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.NotNull(result.Content); - Assert.Equal(changeLogCount, result.Content.Count()); + Assert.NotNull(result); + Assert.Equal(changeLogCount, result.Count()); } diff --git a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs index caa3861..e3219cc 100644 --- a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs @@ -32,7 +32,7 @@ namespace Persistence.IntegrationTests.Controllers dbContext.CleanupDbSet(); dbContext.CleanupDbSet(); - var PaginationRequest = new PaginationRequest() + var requestDto = new PaginationRequest() { Skip = 1, Take = 2, @@ -40,7 +40,7 @@ namespace Persistence.IntegrationTests.Controllers }; //act - var response = await techMessagesClient.GetPage(PaginationRequest, new CancellationToken()); + var response = await techMessagesClient.GetPage(requestDto, new CancellationToken()); //assert Assert.NotNull(response); From ba833050d3eecef9290131e27fc08eda3797a78b Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Wed, 11 Dec 2024 11:25:57 +0500 Subject: [PATCH 4/6] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=B8=D1=81=D0=BA=D1=80=D0=B8=D0=BC=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC?= =?UTF-8?q?=D1=8B=20=D0=BA=20=D1=82=D0=B8=D0=BF=D1=83=20int=20=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B5=20ChangeLog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Clients/ChangeLogClient.cs | 12 ++++++------ .../Clients/Interfaces/IChangeLogClient.cs | 12 ++++++------ .../Interfaces/Refit/IRefitChangeLogClient.cs | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Persistence.Client/Clients/ChangeLogClient.cs b/Persistence.Client/Clients/ChangeLogClient.cs index 00aee71..9cca749 100644 --- a/Persistence.Client/Clients/ChangeLogClient.cs +++ b/Persistence.Client/Clients/ChangeLogClient.cs @@ -14,7 +14,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient this.refitChangeLogClient = refitChangeLogClient; } - public async Task ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token) + public async Task ClearAndAddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token) { var result = await ExecuteGetResponse( async () => await refitChangeLogClient.ClearAndAddRange(idDiscriminator, dtos, token), token); @@ -22,7 +22,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient return result; } - public async Task> GetByDate(Guid idDiscriminator, DateTimeOffset moment, + public async Task> GetByDate(int idDiscriminator, DateTimeOffset moment, SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token) { var result = await ExecuteGetResponse>( @@ -31,7 +31,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient return result; } - public async Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) + public async Task> GetChangeLogForInterval(int idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) { var result = await ExecuteGetResponse>( async () => await refitChangeLogClient.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token), token); @@ -39,7 +39,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient return result; } - public async Task Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token) + public async Task Add(int idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token) { var result = await ExecutePostResponse( async () => await refitChangeLogClient.Add(idDiscriminator, dto, token), token); @@ -47,7 +47,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient return result; } - public async Task AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token) + public async Task AddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token) { var result = await ExecutePostResponse( async () => await refitChangeLogClient.AddRange(idDiscriminator, dtos, token), token); @@ -87,7 +87,7 @@ public class ChangeLogClient : BaseClient, IChangeLogClient return result; } - public async Task GetDatesRange(Guid idDiscriminator, CancellationToken token) + public async Task GetDatesRange(int idDiscriminator, CancellationToken token) { var result = await ExecuteGetResponse( async () => await refitChangeLogClient.GetDatesRange(idDiscriminator, token), token); diff --git a/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs b/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs index 0d24585..501f763 100644 --- a/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs +++ b/Persistence.Client/Clients/Interfaces/IChangeLogClient.cs @@ -15,7 +15,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); + Task Add(int idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); /// /// Добавить несколько записей @@ -24,7 +24,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + Task AddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token); /// /// Импорт с заменой: удаление старых строк и добавление новых @@ -33,7 +33,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + Task ClearAndAddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token); /// /// Удалить одну запись @@ -60,7 +60,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task> GetByDate(Guid idDiscriminator, DateTimeOffset moment, SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token); + Task> GetByDate(int idDiscriminator, DateTimeOffset moment, SectionPartRequest filterRequest, PaginationRequest paginationRequest, CancellationToken token); /// /// Получение исторических данных за определенный период времени @@ -70,7 +70,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); + Task> GetChangeLogForInterval(int idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); /// /// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени) @@ -78,7 +78,7 @@ public interface IChangeLogClient : IDisposable /// /// /// - Task GetDatesRange(Guid idDiscriminator, CancellationToken token); + Task GetDatesRange(int idDiscriminator, CancellationToken token); /// /// Обновить одну запись diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs index 8408d7e..a6ab9f6 100644 --- a/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitChangeLogClient.cs @@ -9,24 +9,24 @@ public interface IRefitChangeLogClient : IDisposable private const string BaseRoute = "/api/ChangeLog"; [Post($"{BaseRoute}/replace/{{idDiscriminator}}")] - Task> ClearAndAddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + Task> ClearAndAddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token); [Get($"{BaseRoute}/moment/{{idDiscriminator}}")] Task>> GetByDate( - Guid idDiscriminator, + int idDiscriminator, DateTimeOffset moment, [Query] SectionPartRequest filterRequest, [Query] PaginationRequest paginationRequest, CancellationToken token); [Get($"{BaseRoute}/history/{{idDiscriminator}}")] - Task>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); + Task>> GetChangeLogForInterval(int idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); [Post($"{BaseRoute}/{{idDiscriminator}}")] - Task> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); + Task> Add(int idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token); [Post($"{BaseRoute}/range/{{idDiscriminator}}")] - Task> AddRange(Guid idDiscriminator, IEnumerable dtos, CancellationToken token); + Task> AddRange(int idDiscriminator, IEnumerable dtos, CancellationToken token); [Put($"{BaseRoute}")] Task> Update(DataWithWellDepthAndSectionDto dto, CancellationToken token); @@ -41,6 +41,6 @@ public interface IRefitChangeLogClient : IDisposable Task> DeleteRange([Body] IEnumerable ids, CancellationToken token); [Get($"{BaseRoute}/datesRange/{{idDiscriminator}}")] - Task> GetDatesRange(Guid idDiscriminator, CancellationToken token); + Task> GetDatesRange(int idDiscriminator, CancellationToken token); } From 0208936a00f9f14283edf8aa5aa7f45c706e7c73 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Wed, 11 Dec 2024 11:29:50 +0500 Subject: [PATCH 5/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D0=B0=D0=BC=D0=B8=20?= =?UTF-8?q?Wits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Clients/IWitsDataClient.cs | 21 ------- .../Clients/Interfaces/IWitsDataClient.cs | 47 +++++++++++++++ .../Interfaces/Refit/IRefitWitsDataClient.cs | 21 +++++++ Persistence.Client/Clients/WitsDataClient.cs | 53 +++++++++++++++++ .../PersistenceClientFactory.cs | 14 +++++ Persistence.Client/Readme.md | 5 +- .../Controllers/TechMessagesControllerTest.cs | 17 ++++-- .../Controllers/WitsDataControllerTest.cs | 59 +++++++++---------- 8 files changed, 178 insertions(+), 59 deletions(-) delete mode 100644 Persistence.Client/Clients/IWitsDataClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/IWitsDataClient.cs create mode 100644 Persistence.Client/Clients/Interfaces/Refit/IRefitWitsDataClient.cs create mode 100644 Persistence.Client/Clients/WitsDataClient.cs diff --git a/Persistence.Client/Clients/IWitsDataClient.cs b/Persistence.Client/Clients/IWitsDataClient.cs deleted file mode 100644 index 108a4d7..0000000 --- a/Persistence.Client/Clients/IWitsDataClient.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Persistence.Models; -using Refit; - -namespace Persistence.Client.Clients; -public interface IWitsDataClient -{ - private const string BaseRoute = "/api/witsData"; - - [Get($"{BaseRoute}/{{discriminatorId}}/graph")] - Task>> GetValuesForGraph(int discriminatorId, [Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int approxPointsCount, CancellationToken token); - - [Post($"{BaseRoute}/")] - Task> AddRange(IEnumerable dtos, CancellationToken token); - - [Get($"{BaseRoute}/{{discriminatorId}}/part")] - Task>> GetPart(int discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default); - - [Get($"{BaseRoute}/{{discriminatorId}}/datesRange")] - Task> GetDatesRangeAsync(int discriminatorId, CancellationToken token); -} diff --git a/Persistence.Client/Clients/Interfaces/IWitsDataClient.cs b/Persistence.Client/Clients/Interfaces/IWitsDataClient.cs new file mode 100644 index 0000000..e42b5a6 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/IWitsDataClient.cs @@ -0,0 +1,47 @@ +using Persistence.Models; +using Refit; + +namespace Persistence.Client.Clients.Interfaces; + +/// +/// Клиент для работы с параметрами Wits +/// +public interface IWitsDataClient : IDisposable +{ + /// + /// Получить набор параметров (Wits) для построения графика + /// + /// + /// + /// + /// + /// + /// + Task> GetValuesForGraph(int discriminatorId, [Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int approxPointsCount, CancellationToken token); + + /// + /// Сохранить набор параметров (Wits) + /// + /// + /// + /// + Task AddRange(IEnumerable dtos, CancellationToken token); + + /// + /// Получить порцию записей, начиная с заданной даты + /// + /// + /// + /// + /// + /// + Task> GetPart(int discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default); + + /// + /// Получить диапазон дат, для которых есть данные в репозитории + /// + /// + /// + /// + Task GetDatesRangeAsync(int discriminatorId, CancellationToken token); +} diff --git a/Persistence.Client/Clients/Interfaces/Refit/IRefitWitsDataClient.cs b/Persistence.Client/Clients/Interfaces/Refit/IRefitWitsDataClient.cs new file mode 100644 index 0000000..ac7b523 --- /dev/null +++ b/Persistence.Client/Clients/Interfaces/Refit/IRefitWitsDataClient.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Mvc; +using Persistence.Models; +using Refit; + +namespace Persistence.Client.Clients.Interfaces.Refit; +public interface IRefitWitsDataClient : IDisposable +{ + private const string BaseRoute = "/api/witsData"; + + [Get($"{BaseRoute}/{{discriminatorId}}/graph")] + Task>> GetValuesForGraph(int discriminatorId, [Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int approxPointsCount, CancellationToken token); + + [Post($"{BaseRoute}/")] + Task> AddRange(IEnumerable dtos, CancellationToken token); + + [Get($"{BaseRoute}/{{discriminatorId}}/part")] + Task>> GetPart(int discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default); + + [Get($"{BaseRoute}/{{discriminatorId}}/datesRange")] + Task> GetDatesRangeAsync(int discriminatorId, CancellationToken token); +} diff --git a/Persistence.Client/Clients/WitsDataClient.cs b/Persistence.Client/Clients/WitsDataClient.cs new file mode 100644 index 0000000..9aeabdf --- /dev/null +++ b/Persistence.Client/Clients/WitsDataClient.cs @@ -0,0 +1,53 @@ +using Microsoft.Extensions.Logging; +using Persistence.Client.Clients.Base; +using Persistence.Client.Clients.Interfaces; +using Persistence.Client.Clients.Interfaces.Refit; +using Persistence.Models; + +namespace Persistence.Client.Clients; +public class WitsDataClient : BaseClient, IWitsDataClient +{ + private readonly IRefitWitsDataClient refitWitsDataClient; + + public WitsDataClient(IRefitWitsDataClient refitWitsDataClient, ILogger logger) : base(logger) + { + this.refitWitsDataClient = refitWitsDataClient; + } + + public async Task AddRange(IEnumerable dtos, CancellationToken token) + { + var result = await ExecutePostResponse( + async () => await refitWitsDataClient.AddRange(dtos, token), token); + + return result; + } + + public async Task GetDatesRangeAsync(int discriminatorId, CancellationToken token) + { + var result = await ExecuteGetResponse( + async () => await refitWitsDataClient.GetDatesRangeAsync(discriminatorId, token), token); + + return result; + } + + public async Task> GetPart(int discriminatorId, DateTimeOffset dateBegin, int take = 86400, CancellationToken token = default) + { + var result = await ExecuteGetResponse>( + async () => await refitWitsDataClient.GetPart(discriminatorId, dateBegin, take, token), token); + + return result; + } + + public async Task> GetValuesForGraph(int discriminatorId, DateTimeOffset dateFrom, DateTimeOffset dateTo, int approxPointsCount, CancellationToken token) + { + var result = await ExecuteGetResponse>( + async () => await refitWitsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointsCount, token), token); + + return result; + } + + public void Dispose() + { + refitWitsDataClient.Dispose(); + } +} diff --git a/Persistence.Client/PersistenceClientFactory.cs b/Persistence.Client/PersistenceClientFactory.cs index bfaf6fa..c77ac04 100644 --- a/Persistence.Client/PersistenceClientFactory.cs +++ b/Persistence.Client/PersistenceClientFactory.cs @@ -114,5 +114,19 @@ namespace Persistence.Client return client; } + + /// + /// Получить клиент для работы c параметрами Wits + /// + /// + public IWitsDataClient GetWitsDataClient() + { + var logger = provider.GetRequiredService>(); + + var restClient = RestService.For(httpClient, RefitSettings); + var client = new WitsDataClient(restClient, logger); + + return client; + } } } diff --git a/Persistence.Client/Readme.md b/Persistence.Client/Readme.md index 2733b7c..e9f4024 100644 --- a/Persistence.Client/Readme.md +++ b/Persistence.Client/Readme.md @@ -14,6 +14,7 @@ Persistence сервисом посредством обращения к кон - `ITimeSeriesClient` - Клиент для работы с временными данными - `ITimestampedSetClient` - Клиент для работы с данными с отметкой времени - `IChangeLogClient` - Клиент для работы с записями ChangeLog +- `IWitsDataClient` - Клиент для работы с параметрами Wits ## Использование Для получения того или иного Persistence - клиента нужно @@ -31,8 +32,7 @@ Persistence сервисом посредством обращения к кон ## xunit тестирование При написании интеграционных тестов с ипользованием Persistence - клиентов Http - клиент не обязан быть авторизован через передачу токена в `PersistenceClientFactory`. -Для осуществления тестовой авторизации достаточно добавить в `appsettings.Tests.json`. -При этом возможна авторизация через `KeyCloak`. +Для осуществления тестовой авторизации достаточно добавить в `appsettings.Tests.json` : ```json "NeedUseKeyCloak": false, "AuthUser": { @@ -43,4 +43,5 @@ Http - клиент не обязан быть авторизован через }, "KeycloakGetTokenUrl": "http://192.168.0.10:8321/realms/Persistence/protocol/openid-connect/token" ``` +При этом возможна авторизация через `KeyCloak`. diff --git a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs index b72a38c..3501f87 100644 --- a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs @@ -80,7 +80,7 @@ namespace Persistence.IntegrationTests.Controllers public async Task InsertRange_returns_BadRequest() { //arrange - var exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса"; + const string exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса"; var dtos = new List() { new TechMessageDto() @@ -95,11 +95,16 @@ namespace Persistence.IntegrationTests.Controllers } }; - //act - var response = await techMessagesClient.AddRange(dtos, new CancellationToken()); - - //assert - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + try + { + //act + var response = await techMessagesClient.AddRange(dtos, new CancellationToken()); + } + catch (Exception ex) + { + //assert + Assert.Equal(exceptionMessage, ex.Message); + } } [Fact] diff --git a/Persistence.IntegrationTests/Controllers/WitsDataControllerTest.cs b/Persistence.IntegrationTests/Controllers/WitsDataControllerTest.cs index 9ecae04..32e3c83 100644 --- a/Persistence.IntegrationTests/Controllers/WitsDataControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/WitsDataControllerTest.cs @@ -1,7 +1,7 @@ -using System.Net; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Persistence.Client; using Persistence.Client.Clients; +using Persistence.Client.Clients.Interfaces; using Persistence.Database.Entity; using Persistence.Models; using Xunit; @@ -17,7 +17,7 @@ public class WitsDataControllerTest : BaseIntegrationTest var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); - witsDataClient = persistenceClientFactory.GetClient(); + witsDataClient = persistenceClientFactory.GetWitsDataClient(); } [Fact] @@ -32,8 +32,7 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); + Assert.NotNull(response); } [Fact] @@ -50,9 +49,8 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -80,9 +78,8 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Empty(response.Content); + Assert.NotNull(response); + Assert.Empty(response); } [Fact] @@ -98,14 +95,13 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetDatesRangeAsync(discriminatorId, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); + Assert.NotNull(response); var expectedDateFrom = dtos .Select(e => e.Timestamped) .Min() .ToString("dd.MM.yyyy-HH:mm:ss"); - var actualDateFrom = response.Content.From.DateTime + var actualDateFrom = response.From.DateTime .ToString("dd.MM.yyyy-HH:mm:ss"); Assert.Equal(expectedDateFrom, actualDateFrom); @@ -113,7 +109,7 @@ public class WitsDataControllerTest : BaseIntegrationTest .Select(e => e.Timestamped) .Max() .ToString("dd.MM.yyyy-HH:mm:ss"); - var actualDateTo = response.Content.To.DateTime + var actualDateTo = response.To.DateTime .ToString("dd.MM.yyyy-HH:mm:ss"); Assert.Equal(expectedDateTo, actualDateTo); } @@ -133,13 +129,12 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetPart(discriminatorId, dateBegin, take, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.NotEmpty(response.Content); - Assert.Equal(take, response.Content.Count()); + Assert.NotNull(response); + Assert.NotEmpty(response); + Assert.Equal(take, response.Count()); var expectedDto = dtos.FirstOrDefault(); - var actualDto = response.Content.FirstOrDefault(); + var actualDto = response.FirstOrDefault(); Assert.Equal(expectedDto?.DiscriminatorId, actualDto?.DiscriminatorId); var expectedValueDto = expectedDto?.Values.FirstOrDefault(); @@ -164,15 +159,15 @@ public class WitsDataControllerTest : BaseIntegrationTest var response = await witsDataClient.GetValuesForGraph(discriminatorId, dateFrom, dateTo, approxPointCount, CancellationToken.None); //assert - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(response.Content); - Assert.Equal(approxPointCount, response.Content.Count()); + Assert.NotNull(response); + Assert.Equal(approxPointCount, response.Count()); } [Fact] public async Task AddRange_returns_BadRequest() { //arrange + const string exceptionMessage = "Ошибка валидации, формата или маршрутизации запроса"; var dtos = new List() { new WitsDataDto() @@ -191,11 +186,16 @@ public class WitsDataControllerTest : BaseIntegrationTest } }; - //act - var response = await witsDataClient.AddRange(dtos, CancellationToken.None); - - //assert - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + try + { + //act + var response = await witsDataClient.AddRange(dtos, CancellationToken.None); + } + catch (Exception ex) + { + //assert + Assert.Equal(exceptionMessage, ex.Message); + } } private async Task> AddRange(int countToCreate = 10) @@ -226,8 +226,7 @@ public class WitsDataControllerTest : BaseIntegrationTest //assert var count = dtos.SelectMany(e => e.Values).Count(); - Assert.Equal(HttpStatusCode.Created, response.StatusCode); - Assert.Equal(count, response.Content); + Assert.Equal(count, response); return dtos; } From 7f377fc14b7e55647798d4b5f7074487d4cf36cb Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Thu, 12 Dec 2024 11:56:20 +0500 Subject: [PATCH 6/6] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D1=83=20=D0=BF=D0=BE=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Persistence.Client/Helpers/ExceptionsHelper.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Persistence.Client/Helpers/ExceptionsHelper.cs b/Persistence.Client/Helpers/ExceptionsHelper.cs index 8c349ba..0e3a31a 100644 --- a/Persistence.Client/Helpers/ExceptionsHelper.cs +++ b/Persistence.Client/Helpers/ExceptionsHelper.cs @@ -25,9 +25,11 @@ public static class ExceptionsHelper public static Exception GetPersistenceException(this IApiResponse response) { - var exception = ExceptionsDictionary - .FirstOrDefault(e => e.Key == response.StatusCode).Value ?? new Exception("Неопознанная ошибка"); + ExceptionsDictionary + .TryGetValue(response.StatusCode, out var exception); - return exception; + var result = exception ?? new Exception("Неопознанная ошибка"); + + return result; } }