mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-06 00:05:05 +00:00
Compare commits
9 Commits
xml-docs-e
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c55003a20 | ||
|
|
9c56b9b057 | ||
|
|
95fc8ddfff | ||
|
|
79d07ab7f4 | ||
|
|
213973a323 | ||
|
|
0a85f1706e | ||
|
|
a7267f1df3 | ||
|
|
df61fdfea1 | ||
|
|
db3ceaf0b4 |
@@ -25,6 +25,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
||||||
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />
|
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />
|
||||||
|
|||||||
@@ -0,0 +1,193 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Web.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for HTTP method attributes
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||||
|
public abstract class HttpMethodAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Method { get; }
|
||||||
|
|
||||||
|
protected HttpMethodAttribute(string method)
|
||||||
|
{
|
||||||
|
Method = method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that a request handler supports HTTP GET operations
|
||||||
|
/// </summary>
|
||||||
|
public class HttpGetAttribute : HttpMethodAttribute
|
||||||
|
{
|
||||||
|
public HttpGetAttribute() : base("GET") { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that a request handler supports HTTP POST operations
|
||||||
|
/// </summary>
|
||||||
|
public class HttpPostAttribute : HttpMethodAttribute
|
||||||
|
{
|
||||||
|
public HttpPostAttribute() : base("POST") { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that a request handler supports HTTP PUT operations
|
||||||
|
/// </summary>
|
||||||
|
public class HttpPutAttribute : HttpMethodAttribute
|
||||||
|
{
|
||||||
|
public HttpPutAttribute() : base("PUT") { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that a request handler supports HTTP DELETE operations
|
||||||
|
/// </summary>
|
||||||
|
public class HttpDeleteAttribute : HttpMethodAttribute
|
||||||
|
{
|
||||||
|
public HttpDeleteAttribute() : base("DELETE") { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides OpenAPI operation metadata for a request handler
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||||
|
public class OpenApiOperationAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A brief summary of what the operation does
|
||||||
|
/// </summary>
|
||||||
|
public string Summary { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A verbose explanation of the operation behavior
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unique string used to identify the operation
|
||||||
|
/// </summary>
|
||||||
|
public string OperationId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of tags for API documentation control
|
||||||
|
/// </summary>
|
||||||
|
public string[] Tags { get; set; }
|
||||||
|
|
||||||
|
public OpenApiOperationAttribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a response from an API operation
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||||
|
public class OpenApiResponseAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The HTTP status code
|
||||||
|
/// </summary>
|
||||||
|
public int StatusCode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A short description of the response
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The content type of the response
|
||||||
|
/// </summary>
|
||||||
|
public string ContentType { get; set; } = "application/json";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type that represents the response schema
|
||||||
|
/// </summary>
|
||||||
|
public Type Type { get; set; }
|
||||||
|
|
||||||
|
public OpenApiResponseAttribute(int statusCode)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that an operation requires a request body
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||||
|
public class OpenApiRequestBodyAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the request body is required
|
||||||
|
/// </summary>
|
||||||
|
public bool Required { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The content type of the request body
|
||||||
|
/// </summary>
|
||||||
|
public string ContentType { get; set; } = "application/json";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type that represents the request body schema
|
||||||
|
/// </summary>
|
||||||
|
public Type Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Description of the request body
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public OpenApiRequestBodyAttribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a parameter for the operation
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||||
|
public class OpenApiParameterAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the parameter
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The location of the parameter
|
||||||
|
/// </summary>
|
||||||
|
public ParameterLocation In { get; set; } = ParameterLocation.Path;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether this parameter is mandatory
|
||||||
|
/// </summary>
|
||||||
|
public bool Required { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A brief description of the parameter
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The type of the parameter
|
||||||
|
/// </summary>
|
||||||
|
public Type Type { get; set; } = typeof(string);
|
||||||
|
|
||||||
|
public OpenApiParameterAttribute(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The location of the parameter
|
||||||
|
/// </summary>
|
||||||
|
public enum ParameterLocation
|
||||||
|
{
|
||||||
|
Query,
|
||||||
|
Header,
|
||||||
|
Path,
|
||||||
|
Cookie
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -210,6 +210,11 @@ namespace PepperDash.Essentials.Core.Web
|
|||||||
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddRoute(new HttpCwsRoute("swagger") {
|
||||||
|
Name = "OpenAPI Documentation",
|
||||||
|
RouteHandler = new SwaggerHandler(_server.GetRouteCollection(), BasePath)
|
||||||
|
});
|
||||||
|
|
||||||
// If running on an appliance
|
// If running on an appliance
|
||||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,12 +2,22 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
using System;
|
using System;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "AppDebug",
|
||||||
|
Description = "Get or set application debug level settings",
|
||||||
|
OperationId = "appDebug")]
|
||||||
|
[OpenApiRequestBody(Description = "Debug level configuration")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
public class AppDebugRequestHandler : WebApiBaseRequestHandler
|
public class AppDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Crestron.SimplSharpPro.EthernetCommunication;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -13,7 +14,15 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
public class DebugSessionRequestHandler : WebApiBaseRequestHandler
|
[HttpGet]
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DebugSession",
|
||||||
|
Description = "Start or stop a WebSocket debug session",
|
||||||
|
OperationId = "debugSession")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
public class DebugSessionRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
public DebugSessionRequestHandler()
|
public DebugSessionRequestHandler()
|
||||||
: base(true)
|
: base(true)
|
||||||
|
|||||||
@@ -3,10 +3,20 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DevJson",
|
||||||
|
Description = "Send a command to a specific device",
|
||||||
|
OperationId = "sendDeviceCommand")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device to send the command to")]
|
||||||
|
[OpenApiRequestBody(Description = "Device command data")]
|
||||||
|
[OpenApiResponse(200, Description = "Command executed successfully")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
public class DevJsonRequestHandler : WebApiBaseRequestHandler
|
public class DevJsonRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,17 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DevList",
|
||||||
|
Description = "Retrieve a list of all devices in the system",
|
||||||
|
OperationId = "getDevices")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(404, Description = "Not Found")]
|
||||||
public class DevListRequestHandler : WebApiBaseRequestHandler
|
public class DevListRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,9 +3,19 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DevMethods",
|
||||||
|
Description = "Retrieve available methods for a specific device",
|
||||||
|
OperationId = "getDeviceMethods")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device not found")]
|
||||||
public class DevMethodsRequestHandler : WebApiBaseRequestHandler
|
public class DevMethodsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DevProps",
|
||||||
|
Description = "Retrieve properties for a specific device",
|
||||||
|
OperationId = "getDeviceProperties")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device not found")]
|
||||||
public class DevPropsRequestHandler : WebApiBaseRequestHandler
|
public class DevPropsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DisableAllStreamDebug",
|
||||||
|
Description = "Disable stream debugging for all devices",
|
||||||
|
OperationId = "disableAllStreamDebug")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response")]
|
||||||
public class DisableAllStreamDebugRequestHandler : WebApiBaseRequestHandler
|
public class DisableAllStreamDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "DoNotLoadConfigOnNextBoot",
|
||||||
|
Description = "Get or set flag to prevent configuration loading on next boot",
|
||||||
|
OperationId = "doNotLoadConfigOnNextBoot")]
|
||||||
|
[OpenApiRequestBody(Description = "Configuration loading flag")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
public class DoNotLoadConfigOnNextBootRequestHandler : WebApiBaseRequestHandler
|
public class DoNotLoadConfigOnNextBootRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetFeedbacksForDeviceKey",
|
||||||
|
Description = "Get feedback values from a specific device",
|
||||||
|
OperationId = "getDeviceFeedbacks")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device to get feedbacks from")]
|
||||||
|
[OpenApiResponse(200, Description = "Device feedback values")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device not found")]
|
||||||
public class GetFeedbacksForDeviceRequestHandler : WebApiBaseRequestHandler
|
public class GetFeedbacksForDeviceRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,9 +3,19 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetJoinMapsForBridgeKey",
|
||||||
|
Description = "Retrieve all join maps for a specific bridge",
|
||||||
|
OperationId = "getJoinMapForBridge")]
|
||||||
|
[OpenApiParameter("bridgeKey", Description = "The key of the bridge")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Bridge not found")]
|
||||||
public class GetJoinMapForBridgeKeyRequestHandler : WebApiBaseRequestHandler
|
public class GetJoinMapForBridgeKeyRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,21 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetJoinMapsForDeviceKey",
|
||||||
|
Description = "Retrieve join map for a specific device within a bridge",
|
||||||
|
OperationId = "getJoinMapForDevice")]
|
||||||
|
[OpenApiParameter("bridgeKey", Description = "The key of the bridge")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Bridge not found")]
|
||||||
|
[OpenApiResponse(500, Description = "Device join map not found")]
|
||||||
public class GetJoinMapForDeviceKeyRequestHandler : WebApiBaseRequestHandler
|
public class GetJoinMapForDeviceKeyRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,16 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetPaths",
|
||||||
|
Description = "Get available API paths and routes",
|
||||||
|
OperationId = "getApiPaths")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response")]
|
||||||
public class GetRoutesHandler:WebApiBaseRequestHandler
|
public class GetRoutesHandler:WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
private HttpCwsRouteCollection routeCollection;
|
private HttpCwsRouteCollection routeCollection;
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
public class GetRoutingPortsHandler : WebApiBaseRequestHandler
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "Get Routing Ports for a device",
|
||||||
|
Description = "Retrieve routing input and output ports for a specific device",
|
||||||
|
OperationId = "getDeviceRoutingPorts")]
|
||||||
|
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device not found")]
|
||||||
|
public class GetRoutingPortsHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
public GetRoutingPortsHandler() : base(true) { }
|
public GetRoutingPortsHandler() : base(true) { }
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
public class GetTieLinesRequestHandler : WebApiBaseRequestHandler
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "Get TieLines",
|
||||||
|
Description = "Retrieve a list of all tie lines in the system",
|
||||||
|
OperationId = "getTieLines")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
public class GetTieLinesRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
public GetTieLinesRequestHandler() : base(true) { }
|
public GetTieLinesRequestHandler() : base(true) { }
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,19 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetTypesByFilter",
|
||||||
|
Description = "Retrieve device types filtered by a specific category",
|
||||||
|
OperationId = "getDeviceTypesByFilter")]
|
||||||
|
[OpenApiParameter("filter", Description = "The filter criteria for device types")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Filtered device types not found")]
|
||||||
public class GetTypesByFilterRequestHandler : WebApiBaseRequestHandler
|
public class GetTypesByFilterRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,18 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "GetTypes",
|
||||||
|
Description = "Retrieve a list of all available device types",
|
||||||
|
OperationId = "getDeviceTypes")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device factory not found")]
|
||||||
public class GetTypesRequestHandler : WebApiBaseRequestHandler
|
public class GetTypesRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,9 +3,16 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "Load Config",
|
||||||
|
Description = "Load configuration",
|
||||||
|
OperationId = "loadConfig")]
|
||||||
|
[OpenApiResponse(200, Description = "Configuration load initiated successfully")]
|
||||||
public class LoadConfigRequestHandler : WebApiBaseRequestHandler
|
public class LoadConfigRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,17 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "ReportVersions",
|
||||||
|
Description = "Get version information for loaded assemblies",
|
||||||
|
OperationId = "getVersions")]
|
||||||
|
[OpenApiResponse(200, Description = "List of loaded assemblies with version information")]
|
||||||
|
[OpenApiResponse(500, Description = "Internal Server Error")]
|
||||||
public class ReportVersionsRequestHandler : WebApiBaseRequestHandler
|
public class ReportVersionsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,9 +3,16 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "Restart Program",
|
||||||
|
Description = "Restart the program",
|
||||||
|
OperationId = "restartProgram")]
|
||||||
|
[OpenApiResponse(200, Description = "Program restart initiated successfully")]
|
||||||
public class RestartProgramRequestHandler : WebApiBaseRequestHandler
|
public class RestartProgramRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,9 +3,20 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "SetDeviceStreamDebug",
|
||||||
|
Description = "Configure stream debugging settings for a device",
|
||||||
|
OperationId = "setDeviceStreamDebug")]
|
||||||
|
[OpenApiRequestBody(Description = "Device stream debug configuration")]
|
||||||
|
[OpenApiResponse(200, Description = "Successful response")]
|
||||||
|
[OpenApiResponse(400, Description = "Bad Request")]
|
||||||
|
[OpenApiResponse(404, Description = "Device not found")]
|
||||||
|
[OpenApiResponse(500, Description = "Internal Server Error")]
|
||||||
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,9 +2,16 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[OpenApiOperation(
|
||||||
|
Summary = "ShowConfig",
|
||||||
|
Description = "Retrieve the current system configuration",
|
||||||
|
OperationId = "getConfig")]
|
||||||
|
[OpenApiResponse(200, Description = "Current system configuration")]
|
||||||
public class ShowConfigRequestHandler : WebApiBaseRequestHandler
|
public class ShowConfigRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -0,0 +1,470 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.WebScripting;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
using PepperDash.Essentials.Core.Web.Attributes;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
|
{
|
||||||
|
public class SwaggerHandler : WebApiBaseRequestHandler
|
||||||
|
{
|
||||||
|
private HttpCwsRouteCollection routeCollection;
|
||||||
|
private string basePath;
|
||||||
|
|
||||||
|
public SwaggerHandler(HttpCwsRouteCollection routeCollection, string basePath)
|
||||||
|
{
|
||||||
|
this.routeCollection = routeCollection;
|
||||||
|
this.basePath = basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void HandleGet(HttpCwsContext context)
|
||||||
|
{
|
||||||
|
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 serverUrl = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
|
||||||
|
? $"https://{hostname}/VirtualControl/Rooms/{InitialParametersClass.RoomId}/cws{basePath}"
|
||||||
|
: $"https://{currentIp}/cws{basePath}";
|
||||||
|
|
||||||
|
var openApiDoc = GenerateOpenApiDocument(serverUrl);
|
||||||
|
|
||||||
|
var response = JsonConvert.SerializeObject(openApiDoc, Formatting.Indented);
|
||||||
|
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.Headers.Add("Content-Type", "application/json");
|
||||||
|
context.Response.Write(response, false);
|
||||||
|
context.Response.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GenerateOpenApiDocument(string serverUrl)
|
||||||
|
{
|
||||||
|
var paths = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// Add paths based on existing routes
|
||||||
|
foreach (var route in routeCollection)
|
||||||
|
{
|
||||||
|
var pathKey = "/" + route.Url;
|
||||||
|
var pathItem = GeneratePathItem(route);
|
||||||
|
if (pathItem != null)
|
||||||
|
{
|
||||||
|
paths[pathKey] = pathItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new
|
||||||
|
{
|
||||||
|
openapi = "3.0.3",
|
||||||
|
info = new
|
||||||
|
{
|
||||||
|
title = "PepperDash Essentials API",
|
||||||
|
description = "RESTful API for PepperDash Essentials control system",
|
||||||
|
version = "1.0.0",
|
||||||
|
contact = new
|
||||||
|
{
|
||||||
|
name = "PepperDash Technology",
|
||||||
|
url = "https://www.pepperdash.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
servers = new[]
|
||||||
|
{
|
||||||
|
new { url = serverUrl, description = "Essentials API Server" }
|
||||||
|
},
|
||||||
|
paths = paths,
|
||||||
|
components = new
|
||||||
|
{
|
||||||
|
schemas = GetSchemas()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GeneratePathItem(HttpCwsRoute route)
|
||||||
|
{
|
||||||
|
if (route.RouteHandler == null) return null;
|
||||||
|
|
||||||
|
var handlerType = route.RouteHandler.GetType();
|
||||||
|
var operations = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// Get HTTP method attributes from the handler class
|
||||||
|
var httpMethodAttributes = handlerType.GetCustomAttributes(typeof(HttpMethodAttribute), false)
|
||||||
|
.Cast<HttpMethodAttribute>()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// If no HTTP method attributes found, fall back to the original logic
|
||||||
|
if (!httpMethodAttributes.Any())
|
||||||
|
{
|
||||||
|
httpMethodAttributes = DetermineHttpMethodsFromRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var methodAttr in httpMethodAttributes)
|
||||||
|
{
|
||||||
|
var operation = GenerateOperation(route, methodAttr.Method, handlerType);
|
||||||
|
if (operation != null)
|
||||||
|
{
|
||||||
|
operations[methodAttr.Method.ToLower()] = operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations.Count > 0 ? operations : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HttpMethodAttribute> DetermineHttpMethodsFromRoute(HttpCwsRoute route)
|
||||||
|
{
|
||||||
|
var methods = new List<HttpMethodAttribute>();
|
||||||
|
var routeName = route.Name?.ToLower() ?? "";
|
||||||
|
var routeUrl = route.Url?.ToLower() ?? "";
|
||||||
|
|
||||||
|
// Fallback logic for routes without attributes
|
||||||
|
if (routeName.Contains("get") || routeUrl.Contains("devices") || routeUrl.Contains("config") ||
|
||||||
|
routeUrl.Contains("versions") || routeUrl.Contains("types") || routeUrl.Contains("tielines") ||
|
||||||
|
routeUrl.Contains("apipaths") || routeUrl.Contains("feedbacks") || routeUrl.Contains("properties") ||
|
||||||
|
routeUrl.Contains("methods") || routeUrl.Contains("joinmap") || routeUrl.Contains("routingports"))
|
||||||
|
{
|
||||||
|
methods.Add(new HttpGetAttribute());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (routeName.Contains("command") || routeName.Contains("restart") || routeName.Contains("load") ||
|
||||||
|
routeName.Contains("debug") || routeName.Contains("disable"))
|
||||||
|
{
|
||||||
|
methods.Add(new HttpPostAttribute());
|
||||||
|
}
|
||||||
|
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GenerateOperation(HttpCwsRoute route, string method, Type handlerType)
|
||||||
|
{
|
||||||
|
var operation = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// Get OpenApiOperation attribute
|
||||||
|
var operationAttr = handlerType.GetCustomAttribute<OpenApiOperationAttribute>();
|
||||||
|
if (operationAttr != null)
|
||||||
|
{
|
||||||
|
operation["summary"] = operationAttr.Summary ?? route.Name ?? "API Operation";
|
||||||
|
operation["operationId"] = operationAttr.OperationId ?? route.Name?.Replace(" ", "") ?? "operation";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(operationAttr.Description))
|
||||||
|
{
|
||||||
|
operation["description"] = operationAttr.Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operationAttr.Tags != null && operationAttr.Tags.Length > 0)
|
||||||
|
{
|
||||||
|
operation["tags"] = operationAttr.Tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback to route name
|
||||||
|
operation["summary"] = route.Name ?? "API Operation";
|
||||||
|
operation["operationId"] = route.Name?.Replace(" ", "") ?? "operation";
|
||||||
|
|
||||||
|
// Add fallback description
|
||||||
|
var fallbackDescription = GetFallbackDescription(route);
|
||||||
|
if (!string.IsNullOrEmpty(fallbackDescription))
|
||||||
|
{
|
||||||
|
operation["description"] = fallbackDescription;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get response attributes
|
||||||
|
var responses = new Dictionary<string, object>();
|
||||||
|
var responseAttrs = handlerType.GetCustomAttributes<OpenApiResponseAttribute>().ToList();
|
||||||
|
|
||||||
|
if (responseAttrs.Any())
|
||||||
|
{
|
||||||
|
foreach (var responseAttr in responseAttrs)
|
||||||
|
{
|
||||||
|
var responseObj = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["description"] = responseAttr.Description ?? "Response"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(responseAttr.ContentType))
|
||||||
|
{
|
||||||
|
responseObj["content"] = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[responseAttr.ContentType] = new { schema = new { type = "object" } }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
responses[responseAttr.StatusCode.ToString()] = responseObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default responses
|
||||||
|
responses["200"] = new
|
||||||
|
{
|
||||||
|
description = "Successful response",
|
||||||
|
content = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["application/json"] = new { schema = new { type = "object" } }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
responses["400"] = new { description = "Bad Request" };
|
||||||
|
responses["404"] = new { description = "Not Found" };
|
||||||
|
responses["500"] = new { description = "Internal Server Error" };
|
||||||
|
}
|
||||||
|
|
||||||
|
operation["responses"] = responses;
|
||||||
|
|
||||||
|
// Get parameter attributes
|
||||||
|
var parameterAttrs = handlerType.GetCustomAttributes<OpenApiParameterAttribute>().ToList();
|
||||||
|
var parameters = new List<object>();
|
||||||
|
|
||||||
|
// Add parameters from attributes
|
||||||
|
foreach (var paramAttr in parameterAttrs)
|
||||||
|
{
|
||||||
|
parameters.Add(new
|
||||||
|
{
|
||||||
|
name = paramAttr.Name,
|
||||||
|
@in = paramAttr.In.ToString().ToLower(),
|
||||||
|
required = paramAttr.Required,
|
||||||
|
schema = new { type = GetSchemaType(paramAttr.Type) },
|
||||||
|
description = paramAttr.Description ?? $"The {paramAttr.Name} parameter"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add parameters from URL path variables (fallback)
|
||||||
|
if (route.Url.Contains("{"))
|
||||||
|
{
|
||||||
|
var url = route.Url;
|
||||||
|
while (url.Contains("{"))
|
||||||
|
{
|
||||||
|
var start = url.IndexOf("{");
|
||||||
|
var end = url.IndexOf("}", start);
|
||||||
|
if (end > start)
|
||||||
|
{
|
||||||
|
var paramName = url.Substring(start + 1, end - start - 1);
|
||||||
|
|
||||||
|
// Only add if not already added from attributes
|
||||||
|
if (!parameters.Any(p => ((dynamic)p).name == paramName))
|
||||||
|
{
|
||||||
|
parameters.Add(new
|
||||||
|
{
|
||||||
|
name = paramName,
|
||||||
|
@in = "path",
|
||||||
|
required = true,
|
||||||
|
schema = new { type = "string" },
|
||||||
|
description = $"The {paramName} parameter"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
url = url.Substring(end + 1);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters.Count > 0)
|
||||||
|
{
|
||||||
|
operation["parameters"] = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get request body attribute for POST operations
|
||||||
|
if (method == "POST")
|
||||||
|
{
|
||||||
|
var requestBodyAttr = handlerType.GetCustomAttribute<OpenApiRequestBodyAttribute>();
|
||||||
|
if (requestBodyAttr != null)
|
||||||
|
{
|
||||||
|
operation["requestBody"] = new
|
||||||
|
{
|
||||||
|
required = requestBodyAttr.Required,
|
||||||
|
description = requestBodyAttr.Description,
|
||||||
|
content = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[requestBodyAttr.ContentType] = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["schema"] = requestBodyAttr.Type != null
|
||||||
|
? (object)new Dictionary<string, object> { ["$ref"] = $"#/components/schemas/{requestBodyAttr.Type.Name}" }
|
||||||
|
: new Dictionary<string, object> { ["type"] = "object" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (route.Name != null && route.Name.Contains("Command"))
|
||||||
|
{
|
||||||
|
// Fallback for command routes
|
||||||
|
operation["requestBody"] = new
|
||||||
|
{
|
||||||
|
required = true,
|
||||||
|
content = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["application/json"] = new
|
||||||
|
{
|
||||||
|
schema = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/DeviceCommand" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetSchemaType(Type type)
|
||||||
|
{
|
||||||
|
if (type == typeof(string)) return "string";
|
||||||
|
if (type == typeof(int) || type == typeof(long)) return "integer";
|
||||||
|
if (type == typeof(bool)) return "boolean";
|
||||||
|
if (type == typeof(double) || type == typeof(float)) return "number";
|
||||||
|
return "string"; // default
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetFallbackDescription(HttpCwsRoute route)
|
||||||
|
{
|
||||||
|
var routeName = route.Name?.ToLower() ?? "";
|
||||||
|
var routeUrl = route.Url?.ToLower() ?? "";
|
||||||
|
|
||||||
|
if (routeUrl.Contains("devices") && !routeUrl.Contains("{"))
|
||||||
|
{
|
||||||
|
return "Retrieve a list of all devices in the system";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("versions"))
|
||||||
|
{
|
||||||
|
return "Get version information for loaded assemblies";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("config"))
|
||||||
|
{
|
||||||
|
return "Retrieve the current system configuration";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("devicecommands"))
|
||||||
|
{
|
||||||
|
return "Send a command to a specific device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("devicefeedbacks"))
|
||||||
|
{
|
||||||
|
return "Get feedback values from a specific device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("deviceproperties"))
|
||||||
|
{
|
||||||
|
return "Get properties of a specific device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("devicemethods"))
|
||||||
|
{
|
||||||
|
return "Get available methods for a specific device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("types"))
|
||||||
|
{
|
||||||
|
return routeUrl.Contains("{") ? "Get types filtered by the specified filter" : "Get all available types";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("tielines"))
|
||||||
|
{
|
||||||
|
return "Get information about tielines in the system";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("joinmap"))
|
||||||
|
{
|
||||||
|
return "Get join map information for bridge or device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("routingports"))
|
||||||
|
{
|
||||||
|
return "Get routing ports for a specific device";
|
||||||
|
}
|
||||||
|
else if (routeUrl.Contains("apipaths"))
|
||||||
|
{
|
||||||
|
return "Get available API paths and routes";
|
||||||
|
}
|
||||||
|
else if (routeName.Contains("restart"))
|
||||||
|
{
|
||||||
|
return "Restart the program";
|
||||||
|
}
|
||||||
|
else if (routeName.Contains("debug"))
|
||||||
|
{
|
||||||
|
return "Debug operation";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> GetSchemas()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["DeviceCommand"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["deviceKey"] = new { type = "string", description = "The key of the device" },
|
||||||
|
["methodName"] = new { type = "string", description = "The method to call on the device" },
|
||||||
|
["params"] = new { type = "array", items = new { type = "object" }, description = "Parameters for the method call" }
|
||||||
|
},
|
||||||
|
required = new[] { "deviceKey", "methodName" }
|
||||||
|
},
|
||||||
|
["Device"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["key"] = new { type = "string", description = "Device key" },
|
||||||
|
["name"] = new { type = "string", description = "Device name" },
|
||||||
|
["type"] = new { type = "string", description = "Device type" },
|
||||||
|
["isOnline"] = new { type = "boolean", description = "Device online status" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Feedback"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["BoolValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/BoolFeedback" } },
|
||||||
|
["IntValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/IntFeedback" } },
|
||||||
|
["SerialValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/StringFeedback" } }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["BoolFeedback"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["FeedbackKey"] = new { type = "string" },
|
||||||
|
["Value"] = new { type = "boolean" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["IntFeedback"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["FeedbackKey"] = new { type = "string" },
|
||||||
|
["Value"] = new { type = "integer" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["StringFeedback"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["FeedbackKey"] = new { type = "string" },
|
||||||
|
["Value"] = new { type = "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["ApiRoutes"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["url"] = new { type = "string", description = "Base URL for the API" },
|
||||||
|
["routes"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/Route" } }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Route"] = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["name"] = new { type = "string", description = "Route name" },
|
||||||
|
["url"] = new { type = "string", description = "Route URL pattern" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user