KoogleV4/GameData/ApiClient.cs

378 lines
14 KiB
C#

using GameData.Helper;
using GameData.Model;
using GameData.Repository;
using GameModel.Settings;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace GameData
{
public sealed class ApiClient : IDisposable
{
private class WrapperArray<T>
{
public T[] Data { get; set; }
}
private class WrapperSingle<T>
{
public T Data { get; set; }
}
private readonly HttpClient client;
private readonly ILogger<ApiClient> _logger;
private readonly AppSettings _appSettings;
private readonly string Api;
public ApiClient(AppSettings appSettings, ILogger<ApiClient> logger)
{
_logger = logger;
_appSettings = appSettings;
client = new HttpClient
{
Timeout = TimeSpan.FromMinutes(1)
};
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders
.Authorization = new AuthenticationHeaderValue("Bearer", _appSettings.ApiToken);
//client.DefaultRequestHeaders.Add("Api-AppInfo", "KrahApp;" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
Api = _appSettings.ApiBaseUrl;
if (!Api.EndsWith("/"))
{
Api += "/";
}
}
public void Dispose()
{
client.Dispose();
}
public string UrlEncode(string s)
{
return HttpUtility.UrlEncode(s);
}
private string GetFullUrl(string url)
{
if (url[0].Equals('/'))
{
url = url.Remove(0, 1);
}
url = Api + url;
return url;
}
private HttpRequestMessage GetHttpRequestMessage(HttpMethod method, string serviceUrl, object payload = null)
{
StringContent content = null;
if (payload != null)
{
var payloadString = LowercaseJsonSerializer.SerializeObject(payload);
content = new StringContent(payloadString, Encoding.UTF8, "application/json");
}
var url = serviceUrl;
if (!serviceUrl.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
{
url = GetFullUrl(serviceUrl);
}
var res = new HttpRequestMessage
{
Content = content,
Method = method,
RequestUri = new Uri(url),
};
//res.Headers.Add("Authorization: Bearer", _apiKey);
return res;
}
public async Task<bool> DownloadFile(string serviceUrl, string targetFile)
{
var res = false;
try
{
var request = GetHttpRequestMessage(HttpMethod.Get, serviceUrl);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Accept", "application/octet-stream");
request.Headers.Add("Accept", "file/download");
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using (var responseStream = await response.Content.ReadAsStreamAsync())
{
using (var fileStream = new FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
{
await responseStream.CopyToAsync(fileStream);
res = true;
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error downloading from service '{service}' with code '{statuscode}' - Result: '{result}', TargetFile: '{payload}'", serviceUrl, response.StatusCode, errorResult, targetFile);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at DownloadFile");
}
return res;
}
/// <summary>
/// Create an item
/// https://docs.directus.io/reference/items.html#create-an-item
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="payload"></param>
/// <param name="serviceUrl"></param>
/// <param name="suppressExceptions"></param>
/// <returns></returns>
public async Task<T> Post<T>(object payload, string serviceUrl, bool suppressExceptions = false)
{
T res = default;
try
{
var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Post, serviceUrl, payload));
if (response.IsSuccessStatusCode)
{
using (var responseStream = response.Content.ReadAsStream())
{
using (var streamReader = new StreamReader(responseStream))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
var wrapper = serializer.Deserialize<WrapperSingle<T>>(jsonTextReader);
res = wrapper.Data;
}
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error posting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at post");
if (!suppressExceptions)
{
throw ex;
}
}
return res;
}
public async Task<T> Delete<T>(object payload, string serviceUrl, bool suppressExceptions = true)
{
T res = default;
try
{
var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Delete, serviceUrl, payload));
if (response.IsSuccessStatusCode)
{
using (var responseStream = await response.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(responseStream))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
res = serializer.Deserialize<T>(jsonTextReader);
}
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error deleting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at Delete");
if (!suppressExceptions)
{
throw ex;
}
}
return res;
}
public async Task<T[]> Get<T>(string serviceUrl, bool suppressExceptions = false)
{
WrapperArray<T> res = default;
try
{
_logger.LogDebug($"calling service url {serviceUrl}");
var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Get, serviceUrl));
if (response.IsSuccessStatusCode)
{
using (var responseStream = response.Content.ReadAsStream())
{
using (var streamReader = new StreamReader(responseStream))
{
string content;
if (typeof(T).Equals(typeof(string)))
{
content = streamReader.ReadToEnd();
res = (WrapperArray<T>)Convert.ChangeType(content, typeof(T));
}
else
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
res = serializer.Deserialize<WrapperArray<T>>(jsonTextReader);
}
}
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error getting from service '{service}' with code '{statuscode}' - Result: '{result}'", serviceUrl, response.StatusCode, errorResult);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at Get");
if (!suppressExceptions)
{
throw ex;
}
}
return res.Data;
}
public async Task<T> GetSingle<T>(string serviceUrl, bool suppressExceptions = false)
{
WrapperSingle<T> res = default;
try
{
_logger.LogDebug($"calling service url {serviceUrl}");
var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Get, serviceUrl));
if (response.IsSuccessStatusCode)
{
using (var responseStream = response.Content.ReadAsStream())
{
using (var streamReader = new StreamReader(responseStream))
{
string content;
if (typeof(T).Equals(typeof(string)))
{
content = streamReader.ReadToEnd();
res = (WrapperSingle<T>)Convert.ChangeType(content, typeof(T));
}
else
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
res = serializer.Deserialize<WrapperSingle<T>>(jsonTextReader);
}
}
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error getting from service '{service}' with code '{statuscode}' - Result: '{result}'", serviceUrl, response.StatusCode, errorResult);
return await Task.FromResult<T>(default(T));
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at Get");
if (!suppressExceptions)
{
throw ex;
}
}
return res.Data;
}
internal async Task Put<T>(object payload, string serviceUrl, bool suppressExceptions = false)
{
T res = default;
try
{
var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Post, serviceUrl, payload));
if (response.IsSuccessStatusCode)
{
using (var responseStream = response.Content.ReadAsStream())
{
using (var streamReader = new StreamReader(responseStream))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
var wrapper = serializer.Deserialize<WrapperSingle<T>>(jsonTextReader);
res = wrapper.Data;
}
}
}
}
else
{
var errorResult = await response.Content.ReadAsStringAsync();
_logger.LogError("error posting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
}
}
catch (Exception ex)
{
_logger.LogError(ex, "error at post");
if (!suppressExceptions)
{
throw ex;
}
}
}
}
}