Use stong types instead object to manage extension confiuration with YAML

pull/638/head
Buddhika Chathuranga 2020-08-12 13:55:52 +05:30 committed by NextTurn
parent 8013ab3d9d
commit 566fc7e145
No known key found for this signature in database
GPG Key ID: 17A0D50ADDE1A0C4
11 changed files with 85 additions and 68 deletions

View File

@ -135,7 +135,7 @@ namespace WinSW.Configuration
// Extensions
public XmlNode? ExtensionsConfiguration => null;
public object? YamlExtensionsConfiguration => null;
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration => new List<YamlExtensionConfiguration>(0);
public string BaseName
{

View File

@ -76,7 +76,7 @@ namespace WinSW.Configuration
// Extensions
XmlNode? ExtensionsConfiguration { get; }
object? YamlExtensionsConfiguration { get; }
List<YamlExtensionConfiguration>? YamlExtensionsConfiguration { get; }
List<string> ExtensionIds { get; }

View File

@ -638,33 +638,26 @@ namespace WinSW.Configuration
public string LogMode => this.Log.Mode is null ? this.Defaults.LogMode : this.Log.Mode;
// TODO - Extensions
public XmlNode? ExtensionsConfiguration => null;
// YAML Extension
[YamlMember(Alias = "extensions")]
public object? YamlExtensionsConfiguration { get; set; }
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration { get; set; }
public List<string> ExtensionIds
{
get
{
var result = new List<string>();
if (!(this.YamlExtensionsConfiguration is List<object> extensions))
if (this.YamlExtensionsConfiguration is null)
{
return result;
return new List<string>(0);
}
foreach (var item in extensions)
{
if (!(item is Dictionary<object, object> dict))
{
continue;
}
var result = new List<string>();
var id = (string)dict["id"];
result.Add(id);
foreach (var item in this.YamlExtensionsConfiguration)
{
result.Add(item.GetId());
}
return result;

View File

@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;
namespace WinSW.Configuration
{
public class YamlExtensionConfiguration
{
[YamlMember(Alias = "id")]
public string? ExtensionId { get; set; }
[YamlMember(Alias = "classname")]
public string? ExtensionClassName { get; set; }
[YamlMember(Alias = "enabled")]
public bool Enabled { get; set; }
[YamlMember(Alias = "settings")]
public Dictionary<object, object>? Settings { get; set; }
public string GetId()
{
if (this.ExtensionId is null)
{
throw new InvalidDataException("Extension Id can't be empty");
}
return this.ExtensionId;
}
public string GetClassName()
{
if (this.ExtensionClassName is null)
{
throw new InvalidDataException("Extension ClassName can't be empty");
}
return this.ExtensionClassName;
}
public Dictionary<object, object> GetSettings()
{
if (this.Settings is null)
{
throw new InvalidDataException("Extension settings not found");
}
return this.Settings;
}
}
}

View File

@ -16,7 +16,7 @@ namespace WinSW.Extensions
// Do nothing
}
public virtual void Configure(IWinSWConfiguration descriptor, object yamlObject)
public virtual void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
{
// Do nothing
}

View File

@ -34,8 +34,8 @@ namespace WinSW.Extensions
/// Configure the extension from Yaml configuration
/// </summary>
/// <param name="descriptor">Yaml Service Descptor</param>
/// <param name="yamlObject">Configuration Node</param>
void Configure(IWinSWConfiguration descriptor, object yamlObject);
/// <param name="config">Configuration Node</param>
void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config);
/// <summary>
/// Start handler. Called during startup of the service before the child process.

View File

@ -1,7 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml;
using WinSW.Configuration;
using WinSW.Util;
namespace WinSW.Extensions
@ -44,16 +42,11 @@ namespace WinSW.Extensions
return new WinSWExtensionDescriptor(id, className, enabled);
}
public static WinSWExtensionDescriptor FromYaml(object node)
public static WinSWExtensionDescriptor FromYaml(YamlExtensionConfiguration config)
{
if (!(node is Dictionary<object, object> config))
{
throw new InvalidDataException("Cannot get the configuration entry");
}
bool enabled = ConfigHelper.YamlBoolParse((string)config["enabled"]);
string className = (string)config["classname"];
string id = (string)config["id"];
bool enabled = config.Enabled;
string className = config.GetClassName();
string id = config.GetId();
return new WinSWExtensionDescriptor(id, className, enabled);
}

View File

@ -160,7 +160,7 @@ namespace WinSW.Extensions
catch (Exception ex)
{ // Consider any unexpected exception as fatal
Log.Fatal("Failed to configure the extension " + id, ex);
throw ex;
throw new ExtensionException(id, "Failed to configure the extension");
}
this.Extensions.Add(id, extension);
@ -174,19 +174,14 @@ namespace WinSW.Extensions
private void LoadExtensionFromYaml(string id)
{
var extensionConfigList = this.ServiceDescriptor.YamlExtensionsConfiguration as List<object>;
var extensionConfigList = this.ServiceDescriptor.YamlExtensionsConfiguration;
if (extensionConfigList is null)
{
throw new ExtensionException(id, "Cannot get the configuration entry");
}
object? configNode = GetYamlonfigById(extensionConfigList, id);
if (configNode is null)
{
throw new ExtensionException(id, "Cannot get the configuration entry");
}
var configNode = GetYamlonfigById(extensionConfigList, id);
var descriptor = WinSWExtensionDescriptor.FromYaml(configNode);
@ -195,20 +190,14 @@ namespace WinSW.Extensions
IWinSWExtension extension = this.CreateExtensionInstance(descriptor.Id, descriptor.ClassName);
extension.Descriptor = descriptor;
if (!(configNode is Dictionary<object, object> dict))
{
// TODO : Replace with exntension exception
throw new InvalidDataException("Error in config node");
}
try
{
extension.Configure(this.ServiceDescriptor, dict["settings"]);
extension.Configure(this.ServiceDescriptor, configNode);
}
catch (Exception ex)
{ // Consider any unexpected exception as fatal
Log.Fatal("Failed to configure the extension " + id, ex);
throw ex;
throw new ExtensionException(id, "Failed to configure the extension");
}
this.Extensions.Add(id, extension);
@ -219,17 +208,17 @@ namespace WinSW.Extensions
Log.Warn("Extension is disabled: " + id);
}
object? GetYamlonfigById(List<object> configs, string id)
YamlExtensionConfiguration GetYamlonfigById(List<YamlExtensionConfiguration> configs, string id)
{
foreach (var item in configs)
{
if (item is Dictionary<object, object> config && config["id"].Equals(id))
if (item.GetId().Equals(id))
{
return item;
}
}
return null;
throw new ExtensionException(id, $@"Can't find extension with id: ""{id}"" ");
}
}

View File

@ -704,6 +704,6 @@ namespace WinSW
return environment;
}
public object? YamlExtensionsConfiguration => null;
public List<YamlExtensionConfiguration>? YamlExtensionsConfiguration => Defaults.YamlExtensionsConfiguration;
}
}

View File

@ -194,13 +194,9 @@ namespace WinSW.Plugins.RunawayProcessKiller
this.CheckWinSWEnvironmentVariable = checkWinSWEnvironmentVariable is null ? true : bool.Parse(checkWinSWEnvironmentVariable);
}
public override void Configure(IWinSWConfiguration descriptor, object yamlObject)
public override void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
{
if (!(yamlObject is Dictionary<object, object> dict))
{
// TODO : throw ExtensionException
throw new InvalidDataException("Cann't configure");
}
var dict = config.GetSettings();
this.Pidfile = (string)dict["pidfile"];
this.StopTimeout = TimeSpan.FromMilliseconds(int.Parse((string)dict["stopTimeOut"]));

View File

@ -44,26 +44,21 @@ namespace WinSW.Plugins.SharedDirectoryMapper
}
}
public override void Configure(IWinSWConfiguration descriptor, object yamlObject)
public override void Configure(IWinSWConfiguration descriptor, YamlExtensionConfiguration config)
{
if (!(yamlObject is Dictionary<object, object> dict))
{
// TODO : throw ExtensionException
throw new InvalidDataException("Conn't configure");
}
var dict = config.GetSettings();
var mappingNode = dict["mapping"];
if (!(mappingNode is List<object> mappings))
{
// TODO : throw ExtensionException
throw new InvalidDataException("Conn't configure");
throw new InvalidDataException("SharedDirectoryMapper mapping should be a list");
}
foreach (var map in mappings)
{
var config = SharedDirectoryMapperConfig.FromYaml(map);
this._entries.Add(config);
var mapConfig = SharedDirectoryMapperConfig.FromYaml(map);
this._entries.Add(mapConfig);
}
}