113 lines
3.7 KiB
C#
113 lines
3.7 KiB
C#
using System.Net;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Contracts;
|
|
using Contracts.Menu;
|
|
using Contracts.Orders;
|
|
using Contracts.Requests;
|
|
using Contracts.Responses;
|
|
using Domain.Entities;
|
|
|
|
namespace ApiClient.Http;
|
|
|
|
public sealed class HttpSmsClient : ISmsClient, IDisposable
|
|
{
|
|
private readonly HttpClient _httpClient;
|
|
|
|
public HttpSmsClient(HttpSmsClientOptions options)
|
|
{
|
|
_httpClient = new HttpClient { BaseAddress = new Uri(options.BaseUrl) };
|
|
|
|
var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{options.Username}:{options.Password}"));
|
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
|
|
}
|
|
|
|
public async Task<GetMenuApiResponse> GetMenuAsync(bool withPrice = true, CancellationToken cancellationToken = default)
|
|
{
|
|
var request = new GetMenuApiRequest
|
|
{
|
|
CommandParameters = new GetMenuParameters(withPrice),
|
|
};
|
|
|
|
var response = await SendAsync(request, cancellationToken);
|
|
return ToGetMenuResponse(response);
|
|
}
|
|
|
|
public async Task<SendOrderApiResponse> SendOrderAsync(Order order, CancellationToken cancellationToken = default)
|
|
{
|
|
var request = new SendOrderApiRequest
|
|
{
|
|
CommandParameters = new SendOrderParameters
|
|
{
|
|
OrderId = order.Id.ToString(),
|
|
MenuItems = order.Items.ToList(),
|
|
},
|
|
};
|
|
|
|
var response = await SendAsync(request, cancellationToken);
|
|
return ToSendOrderResponse(response);
|
|
}
|
|
|
|
public void Dispose() => _httpClient.Dispose();
|
|
|
|
private async Task<ApiResponse> SendAsync(ApiRequest request, CancellationToken cancellationToken)
|
|
{
|
|
var json = JsonSerializer.Serialize(request, request.GetType(), ApiJsonOptions.Instance);
|
|
using var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
using var httpResponse = await _httpClient.PostAsync("/", content, cancellationToken);
|
|
|
|
if (httpResponse.StatusCode == HttpStatusCode.Unauthorized)
|
|
{
|
|
return new ApiResponse
|
|
{
|
|
Command = request.Command,
|
|
Success = false,
|
|
ErrorMessage = "Требуется аутентификация.",
|
|
};
|
|
}
|
|
|
|
var responseJson = await httpResponse.Content.ReadAsStringAsync(cancellationToken);
|
|
|
|
if (string.IsNullOrWhiteSpace(responseJson))
|
|
{
|
|
return new ApiResponse
|
|
{
|
|
Command = request.Command,
|
|
Success = false,
|
|
ErrorMessage = $"Пустой ответ сервера (HTTP {(int)httpResponse.StatusCode}).",
|
|
};
|
|
}
|
|
|
|
try
|
|
{
|
|
return ApiResponseDeserializer.Deserialize(responseJson);
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
return new ApiResponse
|
|
{
|
|
Command = request.Command,
|
|
Success = false,
|
|
ErrorMessage = $"Некорректный JSON в ответе (HTTP {(int)httpResponse.StatusCode}): {responseJson}",
|
|
};
|
|
}
|
|
}
|
|
|
|
private static GetMenuApiResponse ToGetMenuResponse(ApiResponse response) =>
|
|
response as GetMenuApiResponse ?? new GetMenuApiResponse
|
|
{
|
|
Command = Commands.GetMenu,
|
|
Success = false,
|
|
ErrorMessage = response.ErrorMessage,
|
|
};
|
|
|
|
private static SendOrderApiResponse ToSendOrderResponse(ApiResponse response) =>
|
|
response as SendOrderApiResponse ?? new SendOrderApiResponse
|
|
{
|
|
Command = Commands.SendOrder,
|
|
Success = false,
|
|
ErrorMessage = response.ErrorMessage,
|
|
};
|
|
}
|