Adds draft schema document and initial logic to validate config against schema

This commit is contained in:
Neil Dorin
2020-01-20 16:29:01 -07:00
parent 1017464980
commit aa64cc917c
6 changed files with 849 additions and 7 deletions

View File

@@ -11,9 +11,9 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
public class DeviceConfig
public class DeviceConfig : PropertiesConfigBase
{
[JsonProperty("key")]
[JsonProperty("key", Required = Required.Always)]
public string Key { get; set; }
[JsonProperty("uid")]
@@ -25,12 +25,87 @@ namespace PepperDash.Essentials.Core.Config
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("type")]
[JsonProperty("type", Required = Required.Always)]
public string Type { get; set; }
[JsonProperty("properties")]
[JsonProperty("properties", Required = Required.Always)]
[JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; }
public DeviceConfig()
{
SchemaJson = @"
{
'definitions': {},
'$schema': 'http://json-schema.org/draft-07/schema#',
'$id': 'http://example.com/root.json',
'type': 'object',
'title': 'The Root Schema',
'properties': {
'name': {
'$id': '#/properties/name',
'type': 'string',
'title': 'The Name Schema',
'default': '',
'examples': [
'App Server'
],
'pattern': '^(.*)$'
},
'group': {
'$id': '#/properties/group',
'type': 'string',
'title': 'The Group Schema',
'default': '',
'examples': [
'appServer'
],
'pattern': '^(.*)$'
},
'properties': {
'$id': '#/properties/properties',
'type': 'object',
'title': 'The Properties Schema'
},
'uid': {
'$id': '#/properties/uid',
'type': 'integer',
'title': 'The Uid Schema',
'default': 0,
'examples': [
4
]
},
'key': {
'$id': '#/properties/key',
'type': 'string',
'title': 'The Key Schema',
'default': '',
'examples': [
'display-1'
],
'pattern': '^(.*)$'
},
'type': {
'$id': '#/properties/type',
'type': 'string',
'title': 'The Type Schema',
'default': '',
'examples': [
'appServer'
],
'pattern': '^(.*)$'
}
},
'required': [
'group',
'properties',
'key',
'type'
]
}
";
}
}
/// <summary>
@@ -59,7 +134,7 @@ namespace PepperDash.Essentials.Core.Config
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");
throw new NotImplementedException("Not Supported");
}
}
}

View File

@@ -4,6 +4,7 @@ using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using PepperDash.Core;
using PepperDash.Core.Config;
@@ -91,6 +92,9 @@ namespace PepperDash.Essentials.Core.Config
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
// Attempt to validate config against schema
ValidateSchema(fs.ReadToEnd());
if (localConfigFound)
{
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
@@ -129,6 +133,22 @@ namespace PepperDash.Essentials.Core.Config
}
}
public static void ValidateSchema(string json)
{
JToken config = JToken.Parse(json);
var deviceConfig = new DeviceConfig();
JsonSchema schema = JsonSchema.Parse(deviceConfig.SchemaJson);
config.Validate(schema, _ValidationEventHandler);
}
public static void _ValidationEventHandler(object sender, ValidationEventArgs args)
{
Debug.Console(0, "{0}", args.Message);
}
/// <summary>
/// Returns all the files from the directory specified.
/// </summary>

View File

@@ -0,0 +1,744 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Essentials Configuration File Schema",
"description": "",
"type": "object",
"$ref":"#/definitions/EssentialsConfig",
"definitions": {
"EssentialsConfig": {
"type": "object",
"additionalProperties": false,
"properties": {
"template": {
"$ref": "#/definitions/BasicConfig"
},
"system_url": {
"type": "string",
"format": "uri",
"qt-uri-protocols": [
"https"
]
},
"system": {
"$ref": "#/definitions/BasicConfig"
},
"template_url": {
"type": "string",
"format": "uri",
"qt-uri-protocols": [
"https"
]
}
},
"required": [
"system",
"template"
],
"title": "Essentials Configuration"
},
"Info": {
"type": "object",
"additionalProperties": false,
"properties": {
"name":{
"type":"string"
},
"date":{
"type":"string",
"format": "date-time"
},
"version":{
"type":"string"
},
"runtimeInfo":{
"type":"object"
},
"comment":{
"type":"string"
},
"hostname":{
"type":"string"
},
"appNumber":{
"type":"integer"
},
"lastModifiedDate": {
"type": "string",
"format": "date-time"
}
},
"required": [
"lastModifiedDate"
],
"title": "SystemInfo"
},
"BasicConfig": {
"type": "object",
"additionalProperties": false,
"properties": {
"devices": {
"type": "array",
"items": {
"$ref": "#/definitions/Device"
}
},
"rooms": {
"type": "array",
"items": {
"$ref": "#/definitions/Room"
}
},
"info": {
"$ref": "#/definitions/Info"
},
"sourceLists": {
"$ref": "#/definitions/SourceLists"
}
},
"required": [
"devices",
"info",
"rooms",
"sourceLists",
"tieLines"
],
"title": "Template"
},
"Device": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"supportedConfigModes": {
"type": "array",
"items": {
"type": "string"
}
},
"group": {
"type": "string"
},
"properties": {
"$ref": "#/definitions/DeviceProperties"
},
"uid": {
"type": "integer"
},
"key": {
"type": "string"
},
"type": {
"type": "string"
},
"supportsCompliance": {
"type": "boolean"
},
"supportedSystemTypes": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"group",
"key",
"name",
"properties",
"type",
"uid"
],
"title": "Device"
},
"DeviceProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"numberOfRelays": {
"type": "integer"
},
"numberOfComPorts": {
"type": "integer"
},
"numberOfDIOPorts": {
"type": "integer"
},
"numberOfIrPorts": {
"type": "integer"
},
"hasControls": {
"type": "boolean"
},
"isDefault": {
"type": "boolean"
},
"hasAudio": {
"type": "boolean"
},
"hasDpad": {
"type": "boolean"
},
"hasNumeric": {
"type": "boolean"
},
"hasDvr": {
"type": "boolean"
},
"disableCodecSharing": {
"type": "boolean"
},
"control": {
"$ref": "#/definitions/Control"
},
"serverUrl": {
"type": "string"
},
"communicationMonitorProperties": {
"$ref": "#/definitions/CommunicationMonitorProperties"
},
"phonebookMode": {
"type": "string"
},
"occupancy": {
"$ref": "#/definitions/Occupancy"
},
"favorites": {
"type": "array",
"items": {
"$ref": "#/definitions/Favorite"
}
},
"sgdFile": {
"type": "string"
},
"showTime": {
"type": "boolean"
},
"showVolumeGauge": {
"type": "boolean"
},
"sourcesOverflowCount": {
"type": "integer"
},
"showDate": {
"type": "boolean"
},
"headerStyle": {
"type": "string"
},
"usesSplashPage": {
"type": "boolean"
},
"roomListKey": {
"type": "string"
},
"defaultRoomKey": {
"type": "string"
}
},
"required": [],
"title": "DeviceProperties"
},
"CommunicationMonitorProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"timeToError": {
"type": "integer"
},
"timeToWarning": {
"type": "integer"
},
"pollInterval": {
"type": "integer"
},
"pollString": {
"type": "string"
}
},
"required": [
"pollInterval",
"pollString",
"timeToError",
"timeToWarning"
],
"title": "CommunicationMonitorProperties"
},
"Control": {
"type": "object",
"additionalProperties": false,
"properties": {
"irFile": {
"type": "string"
},
"controlPortNumber": {
"type": "integer"
},
"controlPortDevKey": {
"type": "string"
},
"method": {
"type": "string"
},
"tcpSshProperties": {
"$ref": "#/definitions/TCPSSHProperties"
},
"controlPortName": {
"type": "string"
},
"ipid": {
"type": "string",
"format": "integer"
},
"endOfLineChar": {
"type": "string"
},
"endOfLineString": {
"type": "string"
},
"deviceReadyResponsePattern": {
"type": "string"
},
"params": {
"$ref": "#/definitions/Params"
}
},
"required": [],
"title": "Control"
},
"Params": {
"type": "object",
"additionalProperties": false,
"properties": {
"deviceReadyResponsePattern": {
"type": "string"
},
"endOfLineString": {
"type": "string"
}
},
"required": [
"deviceReadyResponsePattern",
"endOfLineString"
],
"title": "Params"
},
"TCPSSHProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"username": {
"type": "string"
},
"port": {
"type": "integer"
},
"address": {
"type": "string"
},
"password": {
"type": "string"
},
"autoReconnect": {
"type": "boolean"
},
"autoReconnectIntervalMs": {
"type": "integer"
},
"bufferSize": {
"type": "integer"
}
},
"required": [
"address",
"autoReconnect",
"autoReconnectIntervalMs",
"bufferSize",
"password",
"port",
"username"
],
"title": "TCPSSHProperties"
},
"Favorite": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"number": {
"type": "string",
"format": "integer"
}
},
"required": [
"name",
"number"
],
"title": "Favorite"
},
"Occupancy": {
"type": "object",
"additionalProperties": false,
"properties": {
"available": {
"type": "boolean"
}
},
"required": [
"available"
],
"title": "Occupancy"
},
"TemplateInfo": {
"type": "object",
"additionalProperties": false,
"properties": {
"lastUid": {
"type": "integer"
},
"processorType": {
"type": "string"
},
"systemType": {
"type": "string"
},
"lastModifiedDate": {
"type": "string",
"format": "date-time"
},
"requiredControlSofwareVersion": {
"type": "string"
},
"comment": {
"type": "string"
}
},
"required": [
"comment",
"lastModifiedDate",
"lastUid",
"processorType",
"requiredControlSofwareVersion",
"systemType"
],
"title": "TemplateInfo"
},
"Room": {
"type": "object",
"additionalProperties": false,
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"properties": {
"$ref": "#/definitions/RoomProperties"
},
"type": {
"type": "string"
}
},
"required": [
"key",
"name",
"properties",
"type"
],
"title": "Room"
},
"RoomProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"volumes": {
"$ref": "#/definitions/Volumes"
},
"defaultDisplayKey": {
"type": "string"
},
"defaultAudioKey": {
"type": "string"
},
"helpMessage": {
"type": "string"
},
"hasDsp": {
"type": "boolean"
},
"defaultSourceItem": {
"type": "string"
},
"logo": {
"$ref": "#/definitions/Logo"
},
"environment": {
"$ref": "#/definitions/Environment"
},
"defaultVideoBehavior": {
"type": "string"
},
"videoCodecKey": {
"type": "string"
},
"sourceListKey": {
"type": "string"
}
},
"required": [
"defaultAudioKey",
"defaultDisplayKey",
"defaultSourceItem",
"defaultVideoBehavior",
"description",
"environment",
"hasDsp",
"helpMessage",
"logo",
"sourceListKey",
"videoCodecKey",
"volumes"
],
"title": "RoomProperties"
},
"Environment": {
"type": "object",
"additionalProperties": false,
"properties": {
"deviceKeys": {
"type": "array",
"items": {}
}
},
"required": [
"deviceKeys"
],
"title": "Environment"
},
"Logo": {
"type": "object",
"additionalProperties": false,
"properties": {
"url": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"type",
"url"
],
"title": "Logo"
},
"Volumes": {
"type": "object",
"additionalProperties": false,
"properties": {
"master": {
"$ref": "#/definitions/Master"
}
},
"required": [
"master"
],
"title": "Volumes"
},
"Master": {
"type": "object",
"additionalProperties": false,
"properties": {
"level": {
"type": "integer"
},
"deviceKey": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"deviceKey",
"label",
"level"
],
"title": "Master"
},
"SourceLists": {
"type": "object",
"additionalProperties": false,
"properties": {
"default": {
"$ref": "#/definitions/Default"
}
},
"required": [
"default"
],
"title": "SourceLists"
},
"Default": {
"type": "object",
"additionalProperties": false,
"properties": {
"codecOsd": {
"$ref": "#/definitions/CodecOsd"
},
"source-1": {
"$ref": "#/definitions/Source"
},
"roomOff": {
"$ref": "#/definitions/RoomOff"
},
"source-2": {
"$ref": "#/definitions/Source"
}
},
"required": [
"codecOsd",
"roomOff",
"source-1",
"source-2"
],
"title": "Default"
},
"CodecOsd": {
"type": "object",
"additionalProperties": false,
"properties": {
"sourceKey": {
"type": "string"
},
"name": {
"type": "string"
},
"routeList": {
"type": "array",
"items": {
"$ref": "#/definitions/RouteList"
}
},
"includeInSourceList": {
"type": "boolean"
},
"type": {
"type": "string"
},
"order": {
"type": "integer"
}
},
"required": [
"includeInSourceList",
"name",
"order",
"routeList",
"sourceKey",
"type"
],
"title": "CodecOsd"
},
"RouteList": {
"type": "object",
"additionalProperties": false,
"properties": {
"destinationKey": {
"type": "string"
},
"sourceKey": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"destinationKey",
"sourceKey",
"type"
],
"title": "RouteList"
},
"RoomOff": {
"type": "object",
"additionalProperties": false,
"properties": {
"sourceKey": {
"type": "string"
},
"routeList": {
"type": "array",
"items": {
"$ref": "#/definitions/RouteList"
}
},
"type": {
"type": "string"
}
},
"required": [
"routeList",
"sourceKey",
"type"
],
"title": "RoomOff"
},
"Source": {
"type": "object",
"additionalProperties": false,
"properties": {
"icon": {
"type": "string"
},
"volumeControlKey": {
"type": "string"
},
"sourceKey": {
"type": "string"
},
"routeList": {
"type": "array",
"items": {
"$ref": "#/definitions/RouteList"
}
},
"includeInSourceList": {
"type": "boolean"
},
"type": {
"type": "string"
},
"altIcon": {
"type": "string"
},
"order": {
"type": "integer"
},
"disableCodecSharing": {
"type": "boolean"
}
},
"required": [
"altIcon",
"icon",
"includeInSourceList",
"order",
"routeList",
"sourceKey",
"type",
"volumeControlKey"
],
"title": "Source"
}
}
}