OneConversorTemplate/UpperFirstLetter/Services/TextConversionApiService.cs
2025-06-08 18:00:23 -03:00

200 lines
7.3 KiB
C#

using Polly;
using Polly.Extensions.Http;
using SentenceConverterModule.Models;
using SentenceConverterModule.Services.Contracts;
using System.Text;
using System.Text.Json;
namespace SentenceConverterModule.Services
{
public class TextConversionApiService : ITextConversionApiService
{
private readonly HttpClient _httpClient;
private readonly ILogger<TextConversionApiService> _logger;
private readonly IAsyncPolicy<HttpResponseMessage> _retryPolicy;
private readonly string _baseUrl;
public TextConversionApiService(
HttpClient httpClient,
ILogger<TextConversionApiService> logger,
IConfiguration configuration)
{
_httpClient = httpClient;
_logger = logger;
_baseUrl = configuration.GetValue<string>("TextConversionApi:BaseUrl") ?? "https://localhost:7071";
// Configurar política de retry com Polly para HttpClient
_retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => !msg.IsSuccessStatusCode)
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
onRetry: (outcome, timespan, retryCount, context) =>
{
_logger.LogWarning("Tentativa {RetryCount} de chamada à API após {Delay}ms. Status: {StatusCode}",
retryCount, timespan.TotalMilliseconds, outcome.Result?.StatusCode);
});
// Configurar timeout
_httpClient.Timeout = TimeSpan.FromSeconds(30);
}
public async Task<string> ConvertToSentenceCaseAsync(string text)
{
try
{
var request = new { Text = text };
var response = await CallApiAsync("/api/text-conversion/sentence-case", request);
return response.ConvertedText;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao converter texto para sentence case via API");
throw;
}
}
public async Task<string> ConvertToUpperCaseAsync(string text)
{
try
{
var request = new { Text = text };
var response = await CallApiAsync("/api/text-conversion/upper-case", request);
return response.ConvertedText;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao converter texto para maiúsculas via API");
throw;
}
}
public async Task<string> ConvertToLowerCaseAsync(string text)
{
try
{
var request = new { Text = text };
var response = await CallApiAsync("/api/text-conversion/lower-case", request);
return response.ConvertedText;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao converter texto para minúsculas via API");
throw;
}
}
public async Task<bool> IsHealthyAsync()
{
try
{
var response = await _retryPolicy.ExecuteAsync(async () =>
{
return await _httpClient.GetAsync($"{_baseUrl}/api/text-conversion/health");
});
return response.IsSuccessStatusCode;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao verificar saúde da API de conversão de texto");
return false;
}
}
private async Task<TextConversionApiResponse> CallApiAsync(string endpoint, object request)
{
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _retryPolicy.ExecuteAsync(async () =>
{
return await _httpClient.PostAsync($"{_baseUrl}{endpoint}", content);
});
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
throw new HttpRequestException($"API call failed with status {response.StatusCode}: {errorContent}");
}
var responseContent = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<TextConversionApiResponse>(responseContent, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
if (result == null || !result.Success)
{
throw new InvalidOperationException($"API returned unsuccessful response: {result?.ErrorMessage}");
}
return result;
}
}
public class TextConversionApiResponse
{
public bool Success { get; set; }
public string OriginalText { get; set; } = string.Empty;
public string ConvertedText { get; set; } = string.Empty;
public DateTime ProcessedAt { get; set; }
public string? ErrorMessage { get; set; }
public Dictionary<string, object>? Metadata { get; set; }
}
// Novo serviço que substitui o UpperLowerConversorService usando a API
//public class ApiBasedSentenceConverterService : BaseConverterService
//{
// private readonly ITextConversionApiService _apiService;
// public override string ConverterType => "text-case-sentence";
// public override string ConverterName => "Maiúsculas para minúsculas";
// public ApiBasedSentenceConverterService(
// ILogger<ApiBasedSentenceConverterService> logger,
// IConfiguration configuration,
// ITextConversionApiService apiService)
// : base(logger, configuration)
// {
// _apiService = apiService;
// }
// public override async Task<ConversionResult> ConvertAsync(ConversionRequest request)
// {
// try
// {
// var resultado = await _apiService.ConvertToSentenceCaseAsync(request.TextInput);
// return new ConversionResult(true, OutputText: resultado);
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "Erro na conversão via API");
// return new ConversionResult(false, ErrorMessage: "Erro ao processar via API");
// }
// }
// public override ConverterConfiguration GetConfiguration(string language)
// {
// var texts = GetLocalizedTexts(language);
// texts["ConverterTitle"] = language switch
// {
// "en" => "Sentence Case Convert",
// "es" => "Convertir a Mayúscula Inicial",
// _ => "Converter para primeira maiúscula"
// };
// return new ConverterConfiguration
// {
// ConverterType = "text",
// OutputType = "text",
// HasAdvancedOptions = false,
// AllowShare = true,
// LocalizedTexts = texts
// };
// }
//}
}