diff options
author | vnugent <public@vaughnnugent.com> | 2023-04-08 16:09:51 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-04-08 16:09:51 -0400 |
commit | 228e1b59a2fc24c2e4ce57aa8171a13a1a18c199 (patch) | |
tree | 4088332a1670e3fc718694da73fdc22a83c06945 /lib/Plugins.Essentials.ServiceStack | |
parent | cf45636b6216d1b2beaec83bb129a1927f24f608 (diff) |
Minor updates and API changes
Diffstat (limited to 'lib/Plugins.Essentials.ServiceStack')
3 files changed, 100 insertions, 34 deletions
diff --git a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStack.cs b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStack.cs index 45282b3..ae0c522 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStack.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStack.cs @@ -39,7 +39,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// </summary> public sealed class HttpServiceStack : VnDisposeable { - private readonly LinkedList<HttpServer> _servers; + private readonly LinkedList<IHttpServer> _servers; private readonly ServiceDomain _serviceDomain; private CancellationTokenSource? _cts; @@ -48,7 +48,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// <summary> /// A collection of all loaded servers /// </summary> - public IReadOnlyCollection<HttpServer> Servers => _servers; + public IReadOnlyCollection<IHttpServer> Servers => _servers; /// <summary> /// The service domain's plugin controller @@ -60,7 +60,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// generate servers to listen for services exposed by the /// specified host context /// </summary> - internal HttpServiceStack(LinkedList<HttpServer> servers, ServiceDomain serviceDomain) + internal HttpServiceStack(LinkedList<IHttpServer> servers, ServiceDomain serviceDomain) { _servers = servers; _serviceDomain = serviceDomain; diff --git a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs index 0b75031..25b6d5f 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/HttpServiceStackBuilder.cs @@ -23,10 +23,11 @@ */ using System; -using System.Linq; +using System.Threading.Tasks; using System.Collections.Generic; using VNLib.Net.Http; +using VNLib.Utils.Logging; namespace VNLib.Plugins.Essentials.ServiceStack { @@ -36,58 +37,123 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// </summary> public sealed class HttpServiceStackBuilder { - private readonly LinkedList<HttpServer> _servers; - /// <summary> - /// The built <see cref="HttpServiceStack"/> + /// Initializes a new <see cref="HttpServiceStack"/> that will + /// generate servers to listen for services exposed by the + /// specified host context /// </summary> - public HttpServiceStack ServiceStack { get; } + public HttpServiceStackBuilder() + {} + + private Action<ICollection<IServiceHost>>? _hostBuilder; + private Func<ServiceGroup, IHttpServer>? _getServers; /// <summary> - /// Gets the underlying <see cref="ServiceDomain"/> + /// Uses the supplied callback to get a collection of virtual hosts + /// to build the current domain with /// </summary> - public ServiceDomain ServiceDomain { get; } + /// <param name="hostBuilder">The callback method to build virtual hosts</param> + /// <returns>A value that indicates if any virtual hosts were successfully loaded</returns> + public HttpServiceStackBuilder WithDomainBuilder(Action<ICollection<IServiceHost>> hostBuilder) + { + _hostBuilder = hostBuilder; + return this; + } /// <summary> - /// Initializes a new <see cref="HttpServiceStack"/> that will - /// generate servers to listen for services exposed by the - /// specified host context + /// Spcifies a callback function that builds <see cref="IHttpServer"/> instances from the hosts /// </summary> - public HttpServiceStackBuilder() + /// <param name="getServers">A callback method that gets the http server implementation for the service group</param> + public HttpServiceStackBuilder WithHttp(Func<ServiceGroup, IHttpServer> getServers) { - ServiceDomain = new(); - _servers = new(); - ServiceStack = new(_servers, ServiceDomain); + _getServers = getServers; + return this; } /// <summary> - /// Builds all http servers from + /// Builds the new <see cref="HttpServiceStack"/> from the configured callbacks, WITHOUT loading plugins /// </summary> - /// <param name="config">The http server configuration to user for servers</param> - /// <param name="getTransports">A callback method that gets the transport provider for the given host group</param> - public void BuildServers(in HttpConfig config, Func<ServiceGroup, ITransportProvider> getTransports) + /// <returns>The newly constructed <see cref="HttpServiceStack"/> that may be used to manage your http services</returns> + /// <exception cref="ArgumentNullException"></exception> + public HttpServiceStack Build() { - //enumerate hosts groups - foreach (ServiceGroup hosts in ServiceDomain.ServiceGroups) + _ = _hostBuilder ?? throw new ArgumentNullException("WithDomainBuilder", "You have not configured a service domain configuration callback"); + _ = _getServers ?? throw new ArgumentNullException("WithHttp", "You have not configured a IHttpServer configuration callback"); + + //Inint the service domain + ServiceDomain sd = new(); + try { - //get transport for provider - ITransportProvider transport = getTransports.Invoke(hosts); + if (!sd.BuildDomain(_hostBuilder)) + { + throw new ArgumentException("Failed to configure the service domain, you must expose at least one service host"); + } + + LinkedList<IHttpServer> servers = new(); - //Create new server - HttpServer server = new(config, transport, hosts.Hosts.Select(static h => h.Processor as IWebRoot)); + //enumerate hosts groups + foreach (ServiceGroup hosts in sd.ServiceGroups) + { + //Create new server + IHttpServer server = _getServers.Invoke(hosts); - //Add server to internal list - _servers.AddLast(server); + //Add server to internal list + servers.AddLast(server); + } + + //Return the service stack + return new HttpServiceStack(servers, sd); + } + catch + { + sd.Dispose(); + throw; } } /// <summary> - /// Releases any resources that may be held by the <see cref="ServiceDomain"/> - /// incase of an error + /// Builds the new <see cref="HttpServiceStack"/> from configured callbacks, AND loads your plugin environment + /// asynchronously /// </summary> - public void ReleaseOnError() + /// <returns>The newly constructed <see cref="HttpServiceStack"/> that may be used to manage your http services</returns> + /// <exception cref="ArgumentNullException"></exception> + public async Task<HttpServiceStack> BuildAsync(PluginLoadConfiguration config, ILogProvider appLog) { - ServiceStack.Dispose(); + _ = _hostBuilder ?? throw new ArgumentNullException("WithDomainBuilder", "You have not configured a service domain configuration callback"); + _ = _getServers ?? throw new ArgumentNullException("WithHttp", "You have not configured a IHttpServer configuration callback"); + + //Inint the service domain + ServiceDomain sd = new(); + try + { + if (!sd.BuildDomain(_hostBuilder)) + { + throw new ArgumentException("Failed to configure the service domain, you must expose at least one service host"); + } + + //Load plugins async + await sd.PluginManager.LoadPluginsAsync(config, appLog); + + LinkedList<IHttpServer> servers = new(); + + //enumerate hosts groups + foreach (ServiceGroup hosts in sd.ServiceGroups) + { + //Create new server + IHttpServer server = _getServers.Invoke(hosts); + + //Add server to internal list + servers.AddLast(server); + } + + //Return the service stack + return new HttpServiceStack(servers, sd); + } + catch + { + sd.Dispose(); + throw; + } } } } diff --git a/lib/Plugins.Essentials.ServiceStack/src/PluginLoadConfiguration.cs b/lib/Plugins.Essentials.ServiceStack/src/PluginLoadConfiguration.cs index 4974e71..73cb201 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/PluginLoadConfiguration.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/PluginLoadConfiguration.cs @@ -51,7 +51,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack /// The optional host configuration file to merge with plugin config /// to pass to the loading plugin. /// </summary> - public readonly JsonDocument? HostConfig { get; init; } + public readonly JsonElement? HostConfig { get; init; } /// <summary> /// Passed to the underlying <see cref="RuntimePluginLoader"/> |