using C4IT.DataHistoryProvider.Base.Modules.Agent.DTOs; using C4IT.FASD.Base; using C4IT.FASD.Communication.Agent; using C4IT.HTTP; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using static C4IT.Logging.cLogManager; namespace C4IT.DataHistoryProvider.Base.Modules.Agent { internal class AgentApiHandler : cHttpApiBase { private readonly Uri _baseUrl; private const string _agentLoginPath = "connect/token"; private readonly cAgentApiConfiguration _agentConfig; public AgentApiHandler(cAgentApiConfiguration agentConfig) : base("Agent ID tenant", $"{agentConfig.ApiUrl}/{agentConfig.LogonUrl}") { _agentConfig = agentConfig; _baseUrl = new Uri(_agentConfig.LogonUrl); AlwaysReturnContent = true; } private protected override async Task privLogonAsync(cOAuthLogonInfo logonInfo) { try { var postData = new List>() { new KeyValuePair("grant_type", "client_credentials"), new KeyValuePair("client_id", logonInfo.ClientID), new KeyValuePair("client_secret", logonInfo.ClientSecret) }; var formData = new FormUrlEncodedContent(postData); var request = new HttpRequestMessage(HttpMethod.Post, new Uri(_baseUrl, _agentLoginPath)) { Content = formData }; using (var httpClient = new HttpClient()) { var response = await httpClient.SendAsync(request); if (response.StatusCode != HttpStatusCode.OK) { var responseMessage = await response.Content.ReadAsStreamAsync(); LogEntry($"F4SD Agent Logon failed. StatusCode: {response.StatusCode}"); LogEntry($"F4SD Agent Logon failed. Response: {responseMessage}"); return false; } string responseContent = await response.Content.ReadAsStringAsync(); var logonResult = JsonConvert.DeserializeObject(responseContent); if (logonResult.TokenType.Equals("Bearer", StringComparison.OrdinalIgnoreCase) == false) { LogEntry("F4SD Agent Access token is not of type 'Bearer'."); return false; } cAgentApiLogonInfo.Instance = logonResult; AccessToken = logonResult.AccessToken; TokenExpiresIn = DateTime.UtcNow + TimeSpan.FromSeconds(logonResult.SecondsTillTokenExpires * RelogonFactor); IsOnline = true; } return true; } catch (Exception ex) { LogException(ex); return false; } } internal async Task Request(string url, eHttpMethod httpMethod = eHttpMethod.get, object bodyData = null, CancellationToken token = default) where T : AgentApiResult { await LogonAsync(new cOAuthLogonInfo() { ClientID = _agentConfig.ClientId, ClientSecret = _agentConfig.ClientSecret, Tenant = "F4SD Agent" }); Uri agentUrl = new Uri(_baseUrl, url); dynamic requestResult = await privRequestAsync(agentUrl.ToString(), httpMethod, bodyData, token: token); // todo handle not successfull status requestResult.ToObject(); string serialized = JsonConvert.SerializeObject(requestResult); // todo find better approach for casting the dynamic T deserialized = JsonConvert.DeserializeObject(serialized); return deserialized; } internal async Task Request(string url, eHttpMethod httpMethod = eHttpMethod.get, object bodyData = null) => await privRequestAsync(url, httpMethod, bodyData); } }