using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; namespace Webserver.WebAPI { public class OpenApiHelpers { private const string masterResourceName = "openapi.master.yaml"; private const string masterDocName = "openapi.yaml"; private const string masterDocRefLineBegin = " - $ref: "; private const string masterDocRefLineEnd = "#/paths"; private readonly Dictionary specs = new CaseInsensitiveStringDictionary (); public OpenApiHelpers () { loadMainSpec (); Web.ServerInitialized += _ => { buildMainSpecRefs (); }; } private void loadMainSpec () { Assembly apiAssembly = GetType ().Assembly; string specText = ResourceHelpers.GetManifestResourceText (apiAssembly, masterResourceName, true); if (specText == null) { Log.Warning ($"[Web] Failed loading main OpenAPI spec from assembly '{Path.GetFileName (apiAssembly.Location)}'"); return; } specs.Add (masterDocName, specText); Log.Out ($"[Web] Loaded main OpenAPI spec"); } private void buildMainSpecRefs () { if (!TryGetOpenApiSpec (null, out string mainSpec)) { return; } StringBuilder sb = new StringBuilder (mainSpec); foreach ((string apiSpecName, _) in specs) { if (apiSpecName.Equals (masterDocName)) { continue; } sb.AppendLine ($"{masterDocRefLineBegin}./{apiSpecName}{masterDocRefLineEnd}"); } specs[masterDocName] = sb.ToString (); Log.Out ("[Web] OpenAPI preparation done"); } public void LoadOpenApiSpec (AbsWebAPI _api) { Assembly apiAssembly = _api.GetType ().Assembly; string apiName = _api.Name; string apiSpecName = $"{apiName}.openapi.yaml"; string specText = ResourceHelpers.GetManifestResourceText (apiAssembly, apiSpecName, true); if (specText == null) { return; } Log.Out ($"[Web] Loaded OpenAPI spec for '{apiName}'"); specs.Add (apiSpecName, specText); } public bool TryGetOpenApiSpec (string _name, out string _specText) { if (string.IsNullOrEmpty (_name)) { _name = masterDocName; } return specs.TryGetValue (_name, out _specText); } } }