From 8ba1aea46a1d521927a2adde873ff2b3ab347c73 Mon Sep 17 00:00:00 2001 From: Sergey Karmanov Date: Fri, 21 Nov 2025 03:56:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BD=D0=B5=D1=81=20httpclient=20?= =?UTF-8?q?=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SfeduSchedule/Jobs/UpdateJWTJob.cs | 3 +- SfeduSchedule/Program.cs | 7 +- SfeduSchedule/Services/ModeusHttpClient.cs | 132 +++++++++++++++++++++ SfeduSchedule/Services/ModeusService.cs | 127 ++++---------------- 4 files changed, 164 insertions(+), 105 deletions(-) create mode 100644 SfeduSchedule/Services/ModeusHttpClient.cs diff --git a/SfeduSchedule/Jobs/UpdateJWTJob.cs b/SfeduSchedule/Jobs/UpdateJWTJob.cs index 8bf15c6..18d497d 100644 --- a/SfeduSchedule/Jobs/UpdateJWTJob.cs +++ b/SfeduSchedule/Jobs/UpdateJWTJob.cs @@ -8,6 +8,7 @@ public class UpdateJwtJob( IConfiguration configuration, ILogger logger, IHttpClientFactory httpClientFactory, + ModeusHttpClient modeusHttpClient, ModeusService modeusService) : IJob { private const int MaxAttempts = 5; // Максимальное число попыток @@ -70,7 +71,7 @@ public class UpdateJwtJob( } configuration["TOKEN"] = body.Jwt; - modeusService.SetToken(body.Jwt); + modeusHttpClient.SetToken(body.Jwt); await File.WriteAllTextAsync(GlobalConsts.JwtFilePath, body.Jwt + "\n" + DateTime.Now.ToString("O"), cts.Token); logger.LogInformation("JWT успешно обновлён"); diff --git a/SfeduSchedule/Program.cs b/SfeduSchedule/Program.cs index e272333..a9d7fb4 100644 --- a/SfeduSchedule/Program.cs +++ b/SfeduSchedule/Program.cs @@ -52,7 +52,7 @@ if (!string.IsNullOrEmpty(tgChatId) && !string.IsNullOrEmpty(tgToken)) options.ChatId = tgChatId; options.AccessToken = tgToken; options.FormatterConfiguration.UseEmoji = true; - options.FormatterConfiguration.ReadableApplicationName = "Sfedu Schedule"; + options.FormatterConfiguration.ReadableApplicationName = "Modeus Schedule Proxy"; options.LogLevel = new Dictionary { { "Default", LogLevel.Error }, @@ -68,8 +68,9 @@ builder.Services.AddHttpClient("modeus", client => { client.BaseAddress = new Uri(configuration["MODEUS_URL"]!); }); -builder.Services.AddSingleton(); -builder.Services.AddHttpClient("authClient"); +builder.Services.AddSingleton(); +builder.Services.AddScoped(); +builder.Services.AddHttpClient("authClient"); builder.Services.AddAuthentication() .AddScheme( diff --git a/SfeduSchedule/Services/ModeusHttpClient.cs b/SfeduSchedule/Services/ModeusHttpClient.cs new file mode 100644 index 0000000..4fa8a4d --- /dev/null +++ b/SfeduSchedule/Services/ModeusHttpClient.cs @@ -0,0 +1,132 @@ +using System.Text; +using System.Text.Json; +using Microsoft.Net.Http.Headers; +using ModeusSchedule.Abstractions; +using ModeusSchedule.Abstractions.DTO; + +namespace SfeduSchedule.Services; + +public class ModeusHttpClient +{ + private readonly HttpClient _httpClient; + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + public ModeusHttpClient(IHttpClientFactory httpClientFactory, + ILogger logger, + IConfiguration configuration) + { + _httpClient = httpClientFactory.CreateClient("modeus"); + _logger = logger; + _configuration = configuration; + SetToken(_configuration["TOKEN"]); // Установка предустановленного токена при инициализации, на случай если нет возможности связи с AUTH сервисом + } + public void SetToken(string? token) + { + if (string.IsNullOrWhiteSpace(token)) { + _logger.LogError("SetToken: Предоставленный токен пустой."); + return; + } + + _httpClient.DefaultRequestHeaders.Remove(HeaderNames.Authorization); + _httpClient.DefaultRequestHeaders.Add(HeaderNames.Authorization, $"Bearer {token}"); + } + + public async Task GetScheduleAsync(ModeusScheduleRequest msr) + { + var request = new HttpRequestMessage(HttpMethod.Post, + $"schedule-calendar-v2/api/calendar/events/search?tz={_configuration["TZ"]!}"); + request.Content = new StringContent(JsonSerializer.Serialize(msr, GlobalConsts.JsonSerializerOptions), + Encoding.UTF8, "application/json"); + var response = await _httpClient.SendAsync(request); + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + _logger.LogError("GetScheduleAsync: Неуспешный статус при получении расписания: {StatusCode}, Request: {msr}", + response.StatusCode, msr); + return null; + } + return await response.Content.ReadAsStringAsync(); + } + + public async Task> GetAttendeesAsync(Guid eventId) + { + var request = new HttpRequestMessage(HttpMethod.Get, + $"schedule-calendar-v2/api/calendar/events/{eventId}/attendees"); + var response = await _httpClient.SendAsync(request); + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + _logger.LogError("GetAttendeesAsync: Неуспешный статус при получении расписания: {StatusCode}, eventId: {eventId}", + response.StatusCode, eventId); + } + List? attendees; + try + { + attendees = Attendees.FromJson(await response.Content.ReadAsStringAsync()); + return attendees; + } + catch (Exception ex) + { + _logger.LogError(ex, "GetAttendeesAsync: Deserialization failed."); + } + + return new List(); + } + + public async Task SearchRoomsAsync(RoomSearchRequest requestDto) + { + var request = new HttpRequestMessage(HttpMethod.Post, "schedule-calendar-v2/api/campus/rooms/search"); + request.Content = + new StringContent(JsonSerializer.Serialize(requestDto, GlobalConsts.JsonSerializerOptions), + Encoding.UTF8, "application/json"); + var response = await _httpClient.SendAsync(request); + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + _logger.LogError("GetScheduleAsync: Неуспешный статус при получении расписания: {StatusCode}, Request: {requestDto}", + response.StatusCode, requestDto); + return null; + } + return await response.Content.ReadAsStringAsync(); + } + + public async Task GetGuidAsync(string fullName) + { + var request = new HttpRequestMessage(HttpMethod.Post, "schedule-calendar-v2/api/people/persons/search"); + request.Content = new StringContent(JsonSerializer.Serialize(new + { + fullName, + sort = "+fullName", + size = 10, + page = 0 + }), Encoding.UTF8, "application/json"); + var response = await _httpClient.SendAsync(request); + + _logger.LogInformation("GetGuidAsync: Ответ получен: {StatusCode}", response.StatusCode); + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + _logger.LogError("GetGuidAsync: Неуспешный статус при получении расписания: {StatusCode}, Name: {fullName}", + response.StatusCode, fullName); + return null; + } + + var json = await response.Content.ReadAsStringAsync(); + + string? personId; + try + { + personId = JsonDocument.Parse(json).RootElement + .GetProperty("_embedded") + .GetProperty("persons")[0] + .GetProperty("id") + .GetString(); + } + catch + { + _logger.LogWarning( + "GetGuidAsync: Не удалось получить идентификатор пользователя, {FullName}, json: {Json}", fullName, + json); + return null; + } + + return personId; + } + +} \ No newline at end of file diff --git a/SfeduSchedule/Services/ModeusService.cs b/SfeduSchedule/Services/ModeusService.cs index 9563a8a..8910d9a 100644 --- a/SfeduSchedule/Services/ModeusService.cs +++ b/SfeduSchedule/Services/ModeusService.cs @@ -1,10 +1,8 @@ -using System.Text; using System.Text.Json; using Ical.Net; using Ical.Net.CalendarComponents; using Ical.Net.DataTypes; using Ical.Net.Serialization; -using Microsoft.Net.Http.Headers; using ModeusSchedule.Abstractions; using ModeusSchedule.Abstractions.DTO; @@ -13,110 +11,18 @@ namespace SfeduSchedule.Services; public class ModeusService { private readonly IConfiguration _configuration; - private readonly HttpClient _httpClient; - private readonly ILogger _logger; - public ModeusService(IHttpClientFactory httpClientFactory, + private readonly ILogger _logger; + private readonly ModeusHttpClient _modeusHttpClient; + + public ModeusService( ILogger logger, - IConfiguration configuration) + IConfiguration configuration, + ModeusHttpClient modeusHttpClient) { - _httpClient = httpClientFactory.CreateClient("modeus"); + _modeusHttpClient = modeusHttpClient; _logger = logger; _configuration = configuration; - SetToken(_configuration["TOKEN"]); // Установка предустановленного токена при инициализации, на случай если нет возможности связи с AUTH сервисом - } - - public void SetToken(string? token) - { - if (string.IsNullOrWhiteSpace(token)) { - _logger.LogError("SetToken: Предоставленный токен пустой."); - return; - } - - _httpClient.DefaultRequestHeaders.Remove(HeaderNames.Authorization); - _httpClient.DefaultRequestHeaders.Add(HeaderNames.Authorization, $"Bearer {token}"); - } - - public async Task GetScheduleAsync(ModeusScheduleRequest msr) - { - var request = new HttpRequestMessage(HttpMethod.Post, - $"schedule-calendar-v2/api/calendar/events/search?tz={_configuration["TZ"]!}"); - request.Content = new StringContent(JsonSerializer.Serialize(msr, GlobalConsts.JsonSerializerOptions), - Encoding.UTF8, "application/json"); - var response = await _httpClient.SendAsync(request); - _logger.LogInformation("GetScheduleAsync: Ответ получен: {StatusCode}", response.StatusCode); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - - public async Task> GetAttendeesAsync(Guid eventId) - { - var request = new HttpRequestMessage(HttpMethod.Get, - $"schedule-calendar-v2/api/calendar/events/{eventId}/attendees"); - var response = await _httpClient.SendAsync(request); - _logger.LogInformation("GetAttendeesAsync: Ответ получен: {StatusCode}", response.StatusCode); - response.EnsureSuccessStatusCode(); - List? attendees; - try - { - attendees = Attendees.FromJson(await response.Content.ReadAsStringAsync()); - return attendees; - } - catch (Exception ex) - { - _logger.LogError(ex, "GetAttendeesAsync: Deserialization failed."); - } - - return new List(); - } - - public async Task SearchRoomsAsync(RoomSearchRequest requestDto) - { - var request = new HttpRequestMessage(HttpMethod.Post, "schedule-calendar-v2/api/campus/rooms/search"); - request.Content = - new StringContent(JsonSerializer.Serialize(requestDto, GlobalConsts.JsonSerializerOptions), - Encoding.UTF8, "application/json"); - var response = await _httpClient.SendAsync(request); - _logger.LogInformation("SearchRoomsAsync: Ответ получен: {StatusCode}", response.StatusCode); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - - public async Task GetGuidAsync(string fullName) - { - var request = new HttpRequestMessage(HttpMethod.Post, "schedule-calendar-v2/api/people/persons/search"); - request.Content = new StringContent(JsonSerializer.Serialize(new - { - fullName, - sort = "+fullName", - size = 10, - page = 0 - }), Encoding.UTF8, "application/json"); - var response = await _httpClient.SendAsync(request); - - _logger.LogInformation("GetGuidAsync: Ответ получен: {StatusCode}", response.StatusCode); - response.EnsureSuccessStatusCode(); - - var json = await response.Content.ReadAsStringAsync(); - - string? personId; - try - { - personId = JsonDocument.Parse(json).RootElement - .GetProperty("_embedded") - .GetProperty("persons")[0] - .GetProperty("id") - .GetString(); - } - catch - { - _logger.LogWarning( - "GetGuidAsync: Не удалось получить идентификатор пользователя, {FullName}, json: {Json}", fullName, - json); - return null; - } - - return personId; } public async Task GetScheduleJsonAsync(ModeusScheduleRequest msr) @@ -287,4 +193,23 @@ public class ModeusService serializedCalendar?.Length ?? 0); return serializedCalendar; } + + #region Проксирование методов из ModeusHttpClient + + public async Task SearchRoomsAsync(RoomSearchRequest request) + { + return await _modeusHttpClient.SearchRoomsAsync(request); + } + + public async Task GetScheduleAsync(ModeusScheduleRequest msr) + { + return await _modeusHttpClient.GetScheduleAsync(msr); + } + + public async Task GetGuidAsync(string fullname) + { + return await _modeusHttpClient.GetGuidAsync(fullname); + } + + #endregion } \ No newline at end of file