Add event-driven quick action dispatch

This commit is contained in:
Drechsler, Meik
2026-07-22 11:57:32 +02:00
parent fb45f1c42b
commit 9bd3896ba0
20 changed files with 591 additions and 139 deletions

View File

@@ -5,8 +5,8 @@ namespace F4SD.ActionConnector.Models
{
public sealed class ActionContext
{
public TriggerEvent TriggerEvent { get; set; }
public bool AwaitResult { get; set; }
public PayloadBase Payload { get; set; }
public TriggerEvent TriggerEvent { get; internal set; }
public bool AwaitResult { get; internal set; }
public PayloadBase Payload { get; internal set; }
}
}

View File

@@ -8,31 +8,31 @@ namespace F4SD.ActionConnector.Models
{
public abstract class ActionDefinitionBase
{
public string Id { get; set; }
public string Id { get; internal set; }
public abstract ActionType Type { get; }
public bool AwaitResult { get; set; }
public bool IsEnabled { get; set; }
public string Description { get; set; }
public bool AwaitResult { get; internal set; }
public bool IsEnabled { get; internal set; }
public string Description { get; internal set; }
public bool IsValid { get; private protected set; }
protected ActionDefinitionBase(XmlElement xNode, cXmlParser parser)
{
try
{
Id = cXmlParser.GetStringFromXmlAttribute(xNode, "Id");
AwaitResult = cXmlParser.GetBoolFromXmlAttribute(xNode, "AwaitResult");
IsEnabled = cXmlParser.GetBoolFromXmlAttribute(xNode, "IsEnabled");
XmlNode descriptionNode = xNode.SelectSingleNode("Description");
if (descriptionNode != null)
Description = cXmlParser.GetInnerTextFromXmlElement(descriptionNode);
IsValid = true;
}
catch (Exception ex)
{
LogException(ex);
}
{
try
{
Id = cXmlParser.GetStringFromXmlAttribute(xNode, "Id");
AwaitResult = cXmlParser.GetBoolFromXmlAttribute(xNode, "AwaitResult");
IsEnabled = cXmlParser.GetBoolFromXmlAttribute(xNode, "IsEnabled");
XmlNode descriptionNode = xNode.SelectSingleNode("Description");
if (descriptionNode != null)
Description = cXmlParser.GetInnerTextFromXmlElement(descriptionNode);
IsValid = true;
}
catch (Exception ex)
{
LogException(ex);
}
}
}
}

View File

@@ -5,29 +5,29 @@ namespace F4SD.ActionConnector.Models
{
public sealed class ActionResult
{
public string ActionId { get; set; }
public ActionResultStatus Status { get; set; }
public string ActionId { get; private set; }
public ActionResultStatus Status { get; private set; }
/// <summary>
/// HTTP status code for HttpCall actions; null for other types.
/// </summary>
public int? HttpStatusCode { get; set; }
public int? HttpStatusCode { get; private set; }
/// <summary>
/// Raw response body (HttpCall) or serialized output (QuickAction).
/// </summary>
public string RawResponse { get; set; }
public string RawResponse { get; private set; }
/// <summary>
/// Named fields extracted from the response via jsonPath mappings.
/// Populated when DisplayInCockpit is true.
/// </summary>
public IDictionary<string, string> MappedFields { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string> MappedFields { get; private set; } = new Dictionary<string, string>();
/// <summary>
/// Human-readable error message; set when Status is Failure.
/// </summary>
public string ErrorMessage { get; set; }
public string ErrorMessage { get; private set; }
public static ActionResult Ok(string actionId, string rawResponse = null)
=> new ActionResult { ActionId = actionId, Status = ActionResultStatus.Success, RawResponse = rawResponse };

View File

@@ -3,17 +3,16 @@ using F4SD.ActionConnector.Enumerations;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace F4SD.ActionConnector.Models
{
internal class ExternalCommunicationConfiguration
public class ExternalCommunicationConfiguration
{
private const string FileNameConfig = "F4SD-ExternalCommunication-Configuration.xml";
private const string FileNameConfigSchema = "F4SD-ExternalCommunication-Configuration.xsd";
private const string ConfigRootElement = "F4SD-ExternalCommunication-Configuration";
public const string ConfigRootElement = "F4SD-ExternalCommunication-Configuration";
public IDictionary<TriggerEvent, Trigger> Triggers { get; } = new Dictionary<TriggerEvent, Trigger>();
@@ -43,7 +42,7 @@ namespace F4SD.ActionConnector.Models
{
Trigger trigger = new Trigger(triggerNodeElement, parser);
if (trigger is null || !Triggers.ContainsKey(trigger.Event))
if (trigger is null || !trigger.IsValid || Triggers.ContainsKey(trigger.Event))
continue;
Triggers.Add(trigger.Event, trigger);

View File

@@ -11,20 +11,20 @@ namespace F4SD.ActionConnector.Models
{
public override ActionType Type => ActionType.HttpCall;
public string Url { get; set; }
public HttpMethod Method { get; set; } = HttpMethod.Post;
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
public string Body { get; set; }
public string Url { get; internal set; }
public HttpMethod Method { get; internal set; } = HttpMethod.Post;
public TimeSpan Timeout { get; internal set; } = TimeSpan.FromSeconds(30);
public IDictionary<string, string> Headers { get; internal set; } = new Dictionary<string, string>();
public string Body { get; internal set; }
/// <summary>
/// jsonPath expressions keyed by field name, used to extract values from the response.
/// </summary>
public IDictionary<string, string> MappedFieldJsonPaths { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string> MappedFieldJsonPaths { get; internal set; } = new Dictionary<string, string>();
internal HttpCallDefinition(XmlElement xNode, cXmlParser parser) : base(xNode, parser)
{
{
}
}
}

View File

@@ -1,27 +1,27 @@
using C4IT.XML;
using F4SD.ActionConnector.Enumerations;
using System;
using System.Collections.Generic;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace F4SD.ActionConnector.Models
{
public sealed class QuickActionDefinition : ActionDefinitionBase
{
private const string ParametersNodeName = "Parameters";
private const string ParameterNodeName = "Parameter";
public override ActionType Type => ActionType.QuickAction;
/// <summary>
/// Reference to the Quick Action to invoke, e.g. "Protocol case in JIRA".
/// </summary>
public string QuickActionRef { get; set; }
public IDictionary<string, string> Parameters { get; private set; } = new Dictionary<string, string>();
internal QuickActionDefinition(XmlElement xNode, cXmlParser parser) : base(xNode, parser)
using C4IT.XML;
using F4SD.ActionConnector.Enumerations;
using System;
using System.Collections.Generic;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace F4SD.ActionConnector.Models
{
public sealed class QuickActionDefinition : ActionDefinitionBase
{
private const string ParametersNodeName = "Parameters";
private const string ParameterNodeName = "Parameter";
public override ActionType Type => ActionType.QuickAction;
/// <summary>
/// Reference to the Quick Action to invoke, e.g. "Protocol case in JIRA".
/// </summary>
public string QuickActionRef { get; internal set; }
public IDictionary<string, string> Parameters { get; private set; } = new Dictionary<string, string>();
internal QuickActionDefinition(XmlElement xNode, cXmlParser parser) : base(xNode, parser)
{
try
{
@@ -81,7 +81,7 @@ namespace F4SD.ActionConnector.Models
{
try
{
string parameterName = cXmlParser.GetStringFromXmlAttribute(parameterNode, "name");
string parameterName = cXmlParser.GetStringFromXmlAttribute(parameterNode, "Name");
string parameterVariable = cXmlParser.GetInnerTextFromXmlElement(parameterNode);
if (string.IsNullOrEmpty(parameterName) || string.IsNullOrEmpty(parameterVariable))
@@ -102,4 +102,4 @@ namespace F4SD.ActionConnector.Models
}
}
}
}
}

View File

@@ -8,7 +8,7 @@ using static C4IT.Logging.cLogManager;
namespace F4SD.ActionConnector.Models
{
internal class Trigger
public class Trigger
{
public TriggerEvent Event { get; set; }
@@ -23,7 +23,7 @@ namespace F4SD.ActionConnector.Models
{
try
{
Event = cXmlParser.GetEnumFromAttribute(xNode, "action", TriggerEvent.Unknown);
Event = cXmlParser.GetEnumFromAttribute(xNode, "event", TriggerEvent.Unknown);
XmlNode actionsNode = xNode.SelectSingleNode(ActionsNodeName);
@@ -56,7 +56,7 @@ namespace F4SD.ActionConnector.Models
{
try
{
ActionType type = cXmlParser.GetEnumFromAttribute(actionNode, "type", ActionType.Unknown);
ActionType type = cXmlParser.GetEnumFromAttribute(actionNode, "Type", ActionType.Unknown);
ActionDefinitionBase actionDefinition = null;