Prepare Data History Provider 2.7 integration update

- modularize Citrix and agent integrations and add remote desktop endpoints
- extend ticket overview, ticket links, token validation, and staged relation handling
- update configuration, licensing, project, signing, and publish artifacts
This commit is contained in:
Meik
2026-07-20 09:31:52 +02:00
parent a3357e2a36
commit ccc48c521a
62 changed files with 5267 additions and 2521 deletions

View File

@@ -0,0 +1,95 @@
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<bool> privLogonAsync(cOAuthLogonInfo logonInfo)
{
try
{
var postData = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", logonInfo.ClientID),
new KeyValuePair<string, string>("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<cAgentApiLogonInfo>(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<T> Request<T>(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<T>();
string serialized = JsonConvert.SerializeObject(requestResult); // todo find better approach for casting the dynamic
T deserialized = JsonConvert.DeserializeObject<T>(serialized);
return deserialized;
}
internal async Task Request(string url, eHttpMethod httpMethod = eHttpMethod.get, object bodyData = null)
=> await privRequestAsync(url, httpMethod, bodyData);
}
}