using System; using System.Text.Json.Serialization; using System.Threading.Tasks; using EmbedIO; namespace Artemis.Core.Services; /// /// Represents a base type for plugin end points to be targeted by the /// public abstract class PluginEndPoint { private readonly PluginsModule _pluginsModule; internal PluginEndPoint(PluginFeature pluginFeature, string name, PluginsModule pluginsModule) { _pluginsModule = pluginsModule; PluginFeature = pluginFeature; Name = name; PluginFeature.Disabled += OnDisabled; } /// /// Gets the name of the end point /// public string Name { get; } /// /// Gets the full URL of the end point /// public string Url => $"{_pluginsModule.ServerUrl?.TrimEnd('/')}{_pluginsModule.BaseRoute}{PluginFeature.Plugin.Guid}/{Name}"; /// /// Gets the plugin the end point is associated with /// [JsonIgnore] public PluginFeature PluginFeature { get; } /// /// Gets the plugin info of the plugin the end point is associated with /// public PluginInfo PluginInfo => PluginFeature.Plugin.Info; /// /// Gets the mime type of the input this end point accepts /// public string? Accepts { get; protected set; } /// /// Gets the mime type of the output this end point returns /// public string? Returns { get; protected set; } /// /// Occurs whenever a request threw an unhandled exception /// public event EventHandler? RequestException; /// /// Occurs whenever a request is about to be processed /// public event EventHandler? ProcessingRequest; /// /// Occurs whenever a request was processed /// public event EventHandler? ProcessedRequest; /// /// Called whenever the end point has to process a request /// /// The HTTP context of the request protected abstract Task ProcessRequest(IHttpContext context); /// /// Invokes the event /// /// The exception that occurred during the request protected virtual void OnRequestException(Exception e) { RequestException?.Invoke(this, new EndpointExceptionEventArgs(e)); } /// /// Invokes the event /// protected virtual void OnProcessingRequest(IHttpContext context) { ProcessingRequest?.Invoke(this, new EndpointRequestEventArgs(context)); } /// /// Invokes the event /// protected virtual void OnProcessedRequest(IHttpContext context) { ProcessedRequest?.Invoke(this, new EndpointRequestEventArgs(context)); } internal async Task InternalProcessRequest(IHttpContext context) { try { OnProcessingRequest(context); await ProcessRequest(context); OnProcessedRequest(context); } catch (Exception e) { OnRequestException(e); throw; } } private void OnDisabled(object? sender, EventArgs e) { PluginFeature.Disabled -= OnDisabled; _pluginsModule.RemovePluginEndPoint(this); } }