From 705e750419262a1328035fa2344263a179ebf61c Mon Sep 17 00:00:00 2001 From: jdevito Date: Mon, 30 Jan 2023 17:17:12 -0600 Subject: [PATCH] fix: resolved issue with default handlers, removed debug statements that were not accessed; fix: updated default handler, reportversions handler, devlist handler --- PepperDashEssentials/ControlSystem.cs | 2 + .../PepperDash_Essentials_Core.csproj | 1 + .../Web/EssemtialsWebApi.cs | 82 +++++++++++-- .../RequestHandlers/DefaultRequestHandler.cs | 112 ++++++++++++++++++ .../RequestHandlers/DevListRequestHandler.cs | 39 +++++- .../ReportVersionsRequestHandler.cs | 33 +++++- 6 files changed, 254 insertions(+), 15 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 1ab3b28e..736a250f 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -13,6 +13,7 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Fusion; +using PepperDash.Essentials.Core.Web; using PepperDash.Essentials.Devices.Common; using PepperDash.Essentials.DM; using PepperDash.Essentials.Fusion; @@ -353,6 +354,7 @@ namespace PepperDash.Essentials // Build the processor wrapper class DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); + DeviceManager.AddDevice(new EssemtialsWebApi("essentialsWebApi","Essentials Web API")); // Add global System Monitor device if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index fb861df6..077bdac9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -198,6 +198,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs index e069e7a6..f708d011 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs @@ -1,6 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.WebScripting; +using Crestron.SimplSharpPro.Diagnostics; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Core.Web; using PepperDash.Essentials.Core.Web.RequestHandlers; @@ -11,11 +16,17 @@ namespace PepperDash.Essentials.Core.Web { private readonly WebApiServer _server; - private const string DefaultBasePath = "/api"; + /// + /// http(s)://{ipaddress}/cws/{basePath} + /// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath} + /// + private readonly string _defaultBasePath = + CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? string.Format("/app{0:00}/api", InitialParametersClass.ApplicationNumber) : "/api"; + // TODO [ ] Reset debug levels to proper value Trace = 0, Info = 1, Verbose = 2 private const int DebugTrace = 0; - private const int DebugInfo = 1; - private const int DebugVerbose = 2; + private const int DebugInfo = 0; + private const int DebugVerbose = 0; /// /// CWS base path @@ -30,6 +41,16 @@ namespace PepperDash.Essentials.Core.Web get { return _server.IsRegistered; } } + /// + /// Constructor + /// + /// + /// + public EssemtialsWebApi(string key, string name) + : this(key, name, null) + { + } + /// /// Constructor /// @@ -41,7 +62,10 @@ namespace PepperDash.Essentials.Core.Web { Key = key; - BasePath = string.IsNullOrEmpty(config.BasePath) ? DefaultBasePath : config.BasePath; + if (config == null) + BasePath = _defaultBasePath; + else + BasePath = string.IsNullOrEmpty(config.BasePath) ? _defaultBasePath : config.BasePath; _server = new WebApiServer(Key, Name, BasePath); } @@ -116,9 +140,10 @@ namespace PepperDash.Essentials.Core.Web } }; - foreach (var route in routes) + foreach (var route in routes.Where(route => route != null)) { - _server.AddRoute(route); + var r = route; + _server.AddRoute(r); } return base.CustomActivate(); @@ -145,17 +170,56 @@ namespace PepperDash.Essentials.Core.Web if (response.Contains("OFF")) return; var is4Series = eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4); - Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials CWS on {0} Appliance", is4Series ? "4-series" : "3-series"); + Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials Web API on {0} Appliance", is4Series ? "4-series" : "3-series"); _server.Start(); + GetPaths(); + return; } // Automatically start CWS when running on a server (Linux OS, Virtual Control) - Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials CWS on Virtual Control Server"); + Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials Web API on Virtual Control Server"); _server.Start(); } + + /// + /// Print the available pahts + /// + /// + /// http(s)://{ipaddress}/cws/{basePath} + /// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath} + /// + public void GetPaths() + { + Debug.Console(DebugTrace, this, "{0}", new String('-', 50)); + + var currentIp = CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0); + + var hostname = CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0); + + var path = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server + ? string.Format("http(s)://{0}/virtualcontrol/rooms/{1}/cws{2}", hostname, InitialParametersClass.RoomId, BasePath) + : string.Format("http(s)://{0}/cws{1}", currentIp, BasePath); + + Debug.Console(DebugTrace, this, "Server:{0}", path); + + var routeCollection = _server.GetRouteCollection(); + if (routeCollection == null) + { + Debug.Console(DebugTrace, this, "Server route collection is null"); + return; + } + Debug.Console(DebugTrace, this, "Configured Routes:"); + foreach (var route in routeCollection) + { + Debug.Console(DebugTrace, this, "{0}: {1}/{2}", route.Name, path, route.Url); + } + Debug.Console(DebugTrace, this, "{0}", new String('-', 50)); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs new file mode 100644 index 00000000..2cd55d4d --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs @@ -0,0 +1,112 @@ +using Crestron.SimplSharp.WebScripting; +using PepperDash.Core.Web.RequestHandlers; + +namespace PepperDash.Essentials.Core.Web.RequestHandlers +{ + public class DefaultRequestHandler : WebApiBaseRequestHandler + { + private const string Key = "DefaultRequestHandler"; + private const uint Trace = 0; + private const uint Info = 1; + private const uint Verbose = 2; + + /// + /// Handles CONNECT method requests + /// + /// + protected override void HandleConnect(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles DELETE method requests + /// + /// + protected override void HandleDelete(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles GET method requests + /// + /// + protected override void HandleGet(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles HEAD method requests + /// + /// + protected override void HandleHead(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles OPTIONS method requests + /// + /// + protected override void HandleOptions(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles PATCH method requests + /// + /// + protected override void HandlePatch(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles POST method requests + /// + /// + protected override void HandlePost(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles PUT method requests + /// + /// + protected override void HandlePut(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + + /// + /// Handles TRACE method requests + /// + /// + protected override void HandleTrace(HttpCwsContext context) + { + context.Response.StatusCode = 501; + context.Response.StatusDescription = "Not Implemented"; + context.Response.End(); + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs index 2bccc435..cc7a1528 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs @@ -1,10 +1,20 @@ -using Crestron.SimplSharp.WebScripting; +using System.Diagnostics; +using System.Linq; +using Crestron.SimplSharp.WebScripting; +using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Core.Web.RequestHandlers; +using Debug = PepperDash.Core.Debug; namespace PepperDash.Essentials.Core.Web.RequestHandlers { public class DevListRequestHandler : WebApiBaseRequestHandler { + private const string Key = "DevListRequestHandler"; + private const uint Trace = 0; + private const uint Info = 0; + private const uint Verbose = 0; + /// /// Handles CONNECT method requests /// @@ -33,8 +43,31 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers /// protected override void HandleGet(HttpCwsContext context) { - context.Response.StatusCode = 501; - context.Response.StatusDescription = "Not Implemented"; + var allDevices = DeviceManager.AllDevices; + allDevices.Sort((a, b) => System.String.Compare(a.Key, b.Key, System.StringComparison.Ordinal)); + + var devices = allDevices.Select(device => new + { + Key = device.Key, + Name = device is IKeyName ? (device as IKeyName).Name : "---" + + }).Cast().ToList(); + + var js = JsonConvert.SerializeObject(devices, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + TypeNameHandling = TypeNameHandling.None + }); + //Debug.Console(Verbose, "[{0}] HandleGet: \x0d\x0a{1}", Key.ToLower(), js); + + context.Response.StatusCode = 200; + context.Response.StatusDescription = "OK"; + context.Response.ContentType = "application/json"; + context.Response.ContentEncoding = System.Text.Encoding.UTF8; + context.Response.Write(js, false); context.Response.End(); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs index 2ee3fec4..a8b36eb5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs @@ -1,10 +1,18 @@ -using Crestron.SimplSharp.WebScripting; +using System.Linq; +using Crestron.SimplSharp.WebScripting; +using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Core.Web.RequestHandlers; namespace PepperDash.Essentials.Core.Web.RequestHandlers { public class ReportVersionsRequestHandler : WebApiBaseRequestHandler { + private const string Key = "ReportVersionsRequestHandler"; + private const uint Trace = 0; + private const uint Info = 0; + private const uint Verbose = 0; + /// /// Handles CONNECT method requests /// @@ -33,8 +41,27 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers /// protected override void HandleGet(HttpCwsContext context) { - context.Response.StatusCode = 501; - context.Response.StatusDescription = "Not Implemented"; + var assemblies = PluginLoader.LoadedAssemblies.Select(assembly => new + { + Name = assembly.Name, + Version = assembly.Version + }).Cast().ToList(); + + var js = JsonConvert.SerializeObject(assemblies, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + TypeNameHandling = TypeNameHandling.None + }); + //Debug.Console(Verbose, "[{0}] HandleGet: \x0d\x0a{1}", Key.ToLower(), js); + + context.Response.StatusCode = 200; + context.Response.StatusDescription = "OK"; + context.Response.ContentType = "application/json"; + context.Response.ContentEncoding = System.Text.Encoding.UTF8; + context.Response.Write(js, false); context.Response.End(); }