using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; using GB5Shared.Telemetry; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace FrameworkBLL.Promotion { public class PromotionExchangeClient : IPromotionExchangeClient { private readonly IHttpClientFactory _HttpFactory; private readonly IConfiguration _Configuration; private readonly ILogger _Logger; public PromotionExchangeClient( IHttpClientFactory httpFactory, IConfiguration configuration, ILogger logger) { _HttpFactory = httpFactory; _Configuration = configuration; _Logger = logger; } public async Task UploadAsync(byte[] packageBytes, string destinationEnvironmentCode, CancellationToken ct) { try { var http = NewClient(); using var content = new MultipartFormDataContent { { new StringContent(destinationEnvironmentCode), "destinationEnvironmentCode" } }; var fileContent = new ByteArrayContent(packageBytes); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContent, "file", "package.gbpromo"); using var response = await http.PostAsync("PromotionExchange/UploadPackage", content, ct) .ConfigureAwait(false); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadFromJsonAsync(cancellationToken: ct) .ConfigureAwait(false); return body?.packageId; } catch (Exception ex) { GB5Trace.RecordError(ex, "promotion-exchange-upload-failed"); _Logger.LogWarning(ex, "PromotionExchange upload failed for destination {Destination}", destinationEnvironmentCode); return null; } } public async Task> ListPendingAsync(CancellationToken ct) { try { var http = NewClient(); var pending = await http.GetFromJsonAsync>( "PromotionExchange/ListPendingPackages", ct).ConfigureAwait(false); return pending ?? new List(); } catch (Exception ex) { GB5Trace.RecordError(ex, "promotion-exchange-list-pending-failed"); _Logger.LogWarning(ex, "PromotionExchange list-pending failed"); return Array.Empty(); } } public async Task DownloadAsync(int packageId, CancellationToken ct) { try { var http = NewClient(); using var response = await http.GetAsync($"PromotionExchange/DownloadPackage/{packageId}", ct) .ConfigureAwait(false); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsByteArrayAsync(ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.RecordError(ex, "promotion-exchange-download-failed"); _Logger.LogWarning(ex, "PromotionExchange download failed for PackageId {PackageId}", packageId); return null; } } private HttpClient NewClient() { var http = _HttpFactory.CreateClient("promotionexchange"); var baseUrl = _Configuration["PromotionExchange:BaseUrl"] ?? "http://localhost:5330"; http.BaseAddress = new Uri(baseUrl.TrimEnd('/') + "/"); var apiKey = _Configuration["PromotionExchange:ApiKey"] ?? string.Empty; http.DefaultRequestHeaders.Remove("X-Api-Key"); http.DefaultRequestHeaders.Add("X-Api-Key", apiKey); return http; } private sealed class UploadResponse { public int packageId { get; set; } } } }