123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- using DSLink;
- using DSLink.Nodes;
- using DSLink.Nodes.Actions;
- using DSLink.Request;
- using Newtonsoft.Json.Linq;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
- using Serilog;
- using CommandLine;
- using System.IO;
- using RTSP_DSLink;
-
- namespace RTSP_DSLink
- {
- public class RSTP_DSLink : DSLinkContainer
- {
- private readonly Dictionary<string, Node> _rngValues;
- private readonly Random _random;
- private readonly Thread _randomNumberThread;
-
- private static void Main(string[] args)
- {
- Parser.Default.ParseArguments<CommandLineArguments>(args)
- .WithParsed(cmdLineOptions =>
- {
- cmdLineOptions = ProcessDSLinkJson(cmdLineOptions);
-
- //Init the logging engine
- InitializeLogging(cmdLineOptions);
-
- //Construct a link Configuration
- var config = new Configuration(cmdLineOptions.LinkName, true, true);
-
- //Construct our custom link
- var dslink = new RSTP_DSLink(config, cmdLineOptions);
-
- InitializeLink(dslink).Wait();
- })
- .WithNotParsed(errors => { Environment.Exit(-1); });
-
- while (true)
- {
- Thread.Sleep(1000);
- }
- }
-
- public static async Task InitializeLink(RSTP_DSLink dsLink)
- {
- await dsLink.Connect();
- await dsLink.SaveNodes();
- }
-
- public RSTP_DSLink(Configuration config, CommandLineArguments cmdLineOptions) : base(config)
- {
- //Perform any configuration overrides from command line options
- if (cmdLineOptions.BrokerUrl != null)
- {
- config.BrokerUrl = cmdLineOptions.BrokerUrl;
- }
-
- if (cmdLineOptions.Token != null)
- {
- config.Token = cmdLineOptions.Token;
- }
-
- if (cmdLineOptions.NodesFileName != null)
- {
- config.NodesFilename = cmdLineOptions.NodesFileName;
- }
-
- if (cmdLineOptions.KeysFolder != null)
- {
- config.KeysFolder = cmdLineOptions.KeysFolder;
- }
-
- _rngValues = new Dictionary<string, Node>();
- _random = new Random();
-
- Responder.AddNodeClass("rngAdd", delegate(Node node)
- {
- node.Configs.Set(ConfigType.DisplayName, new Value("Create RNG"));
- node.AddParameter(new Parameter
- {
- Name = "rngName",
- ValueType = DSLink.Nodes.ValueType.String
- });
- node.SetAction(new ActionHandler(Permission.Config, _createRngAction));
- });
-
- Responder.AddNodeClass("rng", delegate(Node node)
- {
- node.Configs.Set(ConfigType.Writable, new Value(Permission.Read.Permit));
- node.Configs.Set(ConfigType.ValueType, DSLink.Nodes.ValueType.Number.TypeValue);
- node.Value.Set(0);
-
- lock (_rngValues)
- {
- _rngValues.Add(node.Name, node);
- }
- });
-
- Responder.AddNodeClass("number", delegate (Node node)
- {
- node.Configs.Set(ConfigType.Writable, new Value(Permission.Read.Permit));
- node.Configs.Set(ConfigType.ValueType, DSLink.Nodes.ValueType.Number.TypeValue);
- node.Value.Set(0);
- });
-
- _randomNumberThread = new Thread(_updateRandomNumbers);
- _randomNumberThread.Start();
- }
-
- public override void InitializeDefaultNodes()
- {
- Responder.SuperRoot.CreateChild("createRNG", "rngAdd").BuildNode();
- }
-
- private void _updateRandomNumbers()
- {
- while (Thread.CurrentThread.IsAlive)
- {
- lock (_rngValues)
- {
- foreach (var n in _rngValues)
- {
- Node minChild, maxChild;
- n.Value.Children.TryGetValue("min", out minChild);
- n.Value.Children.TryGetValue("max", out maxChild);
- //Si les enfants ne sont pas initialisés, on met les valeurs de min et max à 0
- // Code équivalent à :
- //int min, max;
- //if (minChild != null) {
- // min = minChild.Value.Int;
- //}
- //else {
- // min = 0;
- //}
- //if (maxChild != null) {
- // max = maxChild.Value.Int;
- //}
- //else {
- // max = 0;
- //}
- int min = (minChild != null ? minChild.Value.Int : 0);
- int max = (maxChild != null ? maxChild.Value.Int : 0);
-
- n.Value.Value.Set(_random.Next(min, max+1));
- }
- }
-
- Thread.Sleep(10000);
- }
- }
-
- private async void _createRngAction(InvokeRequest request)
- {
- var rngName = request.Parameters["rngName"].Value<string>();
- if (string.IsNullOrEmpty(rngName)) return;
- if (Responder.SuperRoot.Children.ContainsKey(rngName)) return;
-
- var newRng = Responder.SuperRoot.CreateChild(rngName, "rng").BuildNode();
- newRng.CreateChild("min", "number").BuildNode();
- newRng.CreateChild("max", "number").BuildNode();
-
- await request.Close();
- await SaveNodes();
- }
-
- #region Initialize Logging
-
- /// <summary>
- /// This method initializes the logging engine. In this case Serilog is used, but you
- /// may use a variety of logging engines so long as they are compatible with
- /// Liblog (the interface used by the DSLink SDK)
- /// </summary>
- /// <param name="cmdLineOptions"></param>
- private static void InitializeLogging(CommandLineArguments cmdLineOptions)
- {
- if (cmdLineOptions.LogFileFolder != null &&
- !cmdLineOptions.LogFileFolder.EndsWith(Path.DirectorySeparatorChar))
- {
- throw new ArgumentException($"Specified LogFileFolder must end with '{Path.DirectorySeparatorChar}'");
- }
-
- var logConfig = new LoggerConfiguration();
- switch (cmdLineOptions.LogLevel)
- {
- case LogLevel.Debug:
- logConfig.MinimumLevel.Debug();
- break;
-
- case LogLevel.Unspecified:
- case LogLevel.Info:
- logConfig.MinimumLevel.Information();
- break;
-
- case LogLevel.Warning:
- logConfig.MinimumLevel.Warning();
- break;
-
- case LogLevel.Error:
- logConfig.MinimumLevel.Error();
- break;
- }
-
- logConfig.WriteTo.Console(
- outputTemplate:
- "{Timestamp:MM/dd/yyyy HH:mm:ss} {SourceContext} [{Level}] {Message}{NewLine}{Exception}");
- logConfig.WriteTo.Logger(lc =>
- {
- lc.WriteTo.RollingFile(cmdLineOptions.LogFileFolder + "log-{Date}.txt", retainedFileCountLimit: 3);
- });
- Log.Logger = logConfig.CreateLogger();
- }
-
- #endregion
-
- #region dslink-json file processing
-
- /// <summary>
- /// This method will return an instance of CommandLineArguments build with the following logic rules.
- /// The file dslink.json can be utilized to specifiy command line arguments. These live within the config block
- /// of the file. Here is an example:
- /// ...
- /// "configs" : {
- /// "broker" : {
- /// "type": "url",
- /// "value": "mybroker",
- /// "default": "http:localhost:8080\conn"
- /// },
- /// }
- ///
- /// The code in this method considers only the attribute's name ("broker") and value ("mybroker") in this example).
- /// "type" and "default" are not used.
- ///
- /// The receives an instance of CommandLineArguments previously built from the parser. If the dslink-json paramater
- /// is not null the code will use the value specified rather than the default value of "dslink.json" for the file
- /// to read containing the information.
- ///
- /// Options specified on the command line wins out over those specified in the file.
- ///
- /// </summary>
- /// <param name="cmdLineOptions"></param>
- /// <returns></returns>
- private static CommandLineArguments ProcessDSLinkJson(CommandLineArguments cmdLineOptions)
- {
- bool errorIfNotFound = false;
- string fileName = "dslink.json";
-
- //If filename is specified then error if it is not found
- if (!String.IsNullOrEmpty(cmdLineOptions.DSLinkJsonFilename))
- {
- errorIfNotFound = true;
- fileName = cmdLineOptions.DSLinkJsonFilename;
- }
-
- string fileData = "";
- if (File.Exists(fileName))
- {
- fileData = File.ReadAllText(fileName);
- Console.WriteLine(
- $"Will use a combination of options specified from the command line and those specified in {fileName}");
- }
- else
- {
- if (errorIfNotFound == true)
- {
- throw new ArgumentException($"Specified dslink-json file <{fileName}> was not found");
- }
- else
- {
- return cmdLineOptions;
- }
- }
-
- JObject dslinkJson = JObject.Parse(fileData);
- var dsLinkJsonConfig = dslinkJson["configs"];
-
- var cmdLineOptionsDslinkJson = new CommandLineArguments();
-
- cmdLineOptionsDslinkJson.BrokerUrl =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "broker", cmdLineOptions.BrokerUrl);
- cmdLineOptionsDslinkJson.LinkName =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "name", cmdLineOptions.LinkName);
- cmdLineOptionsDslinkJson.LogFileFolder =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "log-file", cmdLineOptions.LogFileFolder);
- cmdLineOptionsDslinkJson.KeysFolder =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "key", cmdLineOptions.KeysFolder);
- cmdLineOptionsDslinkJson.NodesFileName =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "nodes", cmdLineOptions.NodesFileName);
- cmdLineOptionsDslinkJson.Token =
- GetDsLinkStringValueForAttributeName(dsLinkJsonConfig, "token", cmdLineOptions.Token);
- cmdLineOptionsDslinkJson.LogLevel = GetDsLinkLogLevel(dsLinkJsonConfig, cmdLineOptions.LogLevel);
-
- return cmdLineOptionsDslinkJson;
- }
-
- private static LogLevel GetDsLinkLogLevel(JToken configObj, LogLevel logLevel)
- {
- if (logLevel != LogLevel.Unspecified)
- {
- return logLevel;
- }
-
- string testString = "";
- try
- {
- testString = configObj["log"]["value"].ToString();
- }
- catch
- {
- }
-
- ;
-
- LogLevel useLogLevel = LogLevel.Info;
- if (!Enum.TryParse(testString, out useLogLevel))
- {
- throw new ArgumentException("Invalid 'value' specified for 'log' value in dslink-json file");
- }
-
- return useLogLevel;
- }
-
- private static string GetDsLinkStringValueForAttributeName(JToken configObj, string attributeName,
- string cmdLineValue)
- {
- //use cmdLineValue if specified else attempt to use the one from the dslink-json
- if (cmdLineValue != null)
- {
- return cmdLineValue;
- }
-
- try
- {
- return configObj[attributeName]["value"].ToString();
- }
- catch
- {
- return null;
- }
- }
-
- #endregion processingq
- }
- }
|