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; }