| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- using System.Globalization;
- using System.Runtime.InteropServices.JavaScript;
- using System.Text;
- using System.Text.Json;
- using Quadarax.Foundation.Core.Data;
- using Quadarax.Foundation.Core.QConsole;
- using Quadarax.Foundation.Core.QConsole.Argument;
- using Quadarax.Foundation.Core.QConsole.Attributes;
- using Quadarax.Foundation.Core.QConsole.Value;
- using Quadarax.Foundation.Core.QMonitor.Interfaces;
- using Quadarax.Foundation.Core.Value.Extensions;
- using Result = Quadarax.Foundation.Core.Value.Result;
- namespace Quadarax.Foundation.Core.QMonitor.Console.Commands
- {
- [CommandDefinition]
- internal class MonitorCommand : BaseCommand
- {
- #region *** Constants ***
- private const string CS_CMD_MONITOR_NAME = "monitor";
- private const string CS_CMD_MONITOR_DESC = "Monitor specific single channel";
- protected const string CS_ARG_NAME_IID = "iid";
- private const string CS_ARG_HINT_IID = "<instance_identifier>";
- private const string CS_ARG_DESC_IID = "Specify instance identifier to listen from.";
- protected const string CS_ARG_NAME_CHANNEL = "channel";
- private const string CS_ARG_HINT_CHANNEL = "<chennel>";
- private const string CS_ARG_DESC_CHANNEL = "Specify full channel name to monitor.";
- protected const string CS_ARG_NAME_REFRESH = "refresh";
- private const string CS_ARG_HINT_REFRESH = "<refresh_interval>";
- private const string CS_ARG_DESC_REFRESH = "Specify receiver refresh interval to detect changes. Default is 00:00:05.";
- protected const string CS_ARG_NAME_GENFILE = "genfile";
- private const string CS_ARG_HINT_GENFILE = "<general_file>";
- private const string CS_ARG_DESC_GENFILE = "Use general metadata from json file during initialization (no needs to wait to receive).";
- protected const string CS_ARG_NAME_REWIND = "rewind";
- private const string CS_ARG_HINT_REWIND = "<is_rewind>";
- private const string CS_ARG_DESC_REWIND = "Flag defines if rewind to first available cached data (may live when no cached data), otherwise wait for new data.";
-
- #endregion
- #region *** Properties ***
- public override string Name => CS_CMD_MONITOR_NAME;
- public override string Description => CS_CMD_MONITOR_DESC;
-
- private string InstanceIdentifier { get; set; }
- private string ChannelName { get; set; }
- private TimeSpan RefreshInterval { get; set; }
- private string GeneralFile { get; set; }
- private bool IsRewind { get; set; }
- #endregion
- #region *** Private fields ***
- private long _dumpCnt;
- private MonData? _lastData;
- private IDictionary<string, MonData> _lastDataCollection = new Dictionary<string, MonData>();
- #endregion
- #region *** Constructor ***
- public MonitorCommand(Engine engine) : base(engine)
- {
- }
- #endregion
- #region *** Execute ***
- protected override Result OnExecute()
- {
- WriteInfo($"Refresh interval is set to {RefreshInterval}");
- WriteInfo($"Waiting for channel definition '{InstanceIdentifier}' and channel '{ChannelName}'...");
- using (var hnd = Receiver.CreateHandler(InstanceIdentifier, ChannelName, RefreshInterval,GeneralFile, true))
- {
- hnd.ReceiverHandlerStateChanged += OnReceiverHandlerStateChanged;
- hnd.ReceiverHandlerDataChanged += OnReceiverHandlerDataChanged;
- if (IsRewind)
- {
- WriteInfo("Rewind to first available cached data.");
- hnd.Rewind(isBackward:true);
- hnd.Play(false);
- }
- else
- {
- hnd.Play(true);
- }
- WriteCaption("To close receiver press any key ...");
- System.Console.ReadKey();
- }
- return new Result();
- }
- #endregion
- #region *** Private Operations ***
- protected override void OnInitialize()
- {
- base.OnInitialize();
- InstanceIdentifier = GetArgumentValueOrDefault<string>(CS_ARG_NAME_IID);
- ChannelName = GetArgumentValueOrDefault<string>(CS_ARG_NAME_CHANNEL);
- RefreshInterval = GetArgumentValueOrDefault<TimeSpan>(CS_ARG_NAME_REFRESH);
- GeneralFile = GetArgumentValueOrDefault<string>(CS_ARG_NAME_GENFILE);
- IsRewind = GetArgumentValueOrDefault<bool>(CS_ARG_NAME_REWIND);
- }
- protected override IEnumerable<AbstractArgument> OnSetupArguments()
- {
- var list = base.OnSetupArguments().ToList();
- list.Add(new NamedArgument(CS_ARG_NAME_IID, CS_ARG_HINT_IID, CS_ARG_DESC_IID, TypeValuesEnum.String,string.Empty,true));
- list.Add(new NamedArgument(CS_ARG_NAME_CHANNEL, CS_ARG_HINT_CHANNEL, CS_ARG_DESC_CHANNEL, TypeValuesEnum.String,string.Empty,true));
- list.Add(new NamedArgument(CS_ARG_NAME_REFRESH, CS_ARG_HINT_REFRESH, CS_ARG_DESC_REFRESH, TypeValuesEnum.TimeSpan,TimeSpan.FromSeconds(5).ToString(),false));
- list.Add(new NamedArgument(CS_ARG_NAME_GENFILE, CS_ARG_HINT_GENFILE, CS_ARG_DESC_GENFILE, TypeValuesEnum.String, string.Empty, false));
- list.Add(new FlagArgument(CS_ARG_NAME_REWIND, CS_ARG_HINT_REWIND, CS_ARG_DESC_REWIND, false));
- return list;
- }
- private void OnReceiverHandlerDataChanged(IReceiverHandler sender, MonData newData)
- {
- RenderData(sender.Descriptor, newData);
- }
- private void OnReceiverHandlerStateChanged(IReceiverHandler sender, ReceiverHandlerStateEnum state)
- {
- WriteInfo($"! Receiver state change to {sender.State.ToString().ToUpper()}");
- }
- private void RenderData(MonItemGeneral descriptor, MonData data)
- {
- var firstLine = $"*** Dump [{_dumpCnt}] {descriptor.ViewType} * {descriptor.Caption} ***";
- WriteInfo(firstLine);
- WriteCaption($"Timestamp: {DateTime.FromFileTimeUtc(data.TimestampFtUtc)} ({data.TimestampFtUtc})");
- WriteCaption($"Name: {data.Name}");
- WriteInfo(new('-', firstLine.Length));
- var diff = _lastData?.Diff(data);
- if (descriptor.ViewType == MonItemGeneral.MonViewType.Item)
- {
- //item view
- foreach (var item in descriptor.Items.OrderBy(x=>x.Order))
- {
- var sb = new StringBuilder();
- if (diff != null)
- {
- if (diff.ContainsKey(item.Name)) sb.Append("[*] ");
- }
- sb.Append(string.IsNullOrEmpty(item.Label) ? item.Name : item.Label).Append(" : ");
- var properties = ParseProperties(JsonDocument.Parse(data.Data).RootElement);
- var arg = properties.FirstOrDefault(x => string.Equals(x.Name, item.Name, StringComparison.InvariantCultureIgnoreCase));
- sb.Append(arg != null ? arg.Value : "N/A");
- WriteInfo(sb.ToString());
- }
- }
- WriteInfo(new('-', firstLine.Length));
- _lastData = data;
- _dumpCnt++;
- }
- private TypedArgument[] ParseProperties(JsonElement element)
- {
- var result = new List<TypedArgument>();
- foreach (var property in element.EnumerateObject())
- {
- if (property.Value.ValueKind.In(JsonValueKind.False, JsonValueKind.True, JsonValueKind.Number,
- JsonValueKind.String))
- {
- TypedArgument? arg = null;
- if (property.Value.ValueKind.In(JsonValueKind.False, JsonValueKind.True))
- {
- arg = new TypedArgument(property.Name, property.Value.GetBoolean());
- }
- else if (property.Value.ValueKind == JsonValueKind.Null)
- {
- result.Add(new TypedArgument(property.Name,null, typeof(string)));
- }
- else if (property.Value.ValueKind == JsonValueKind.Number)
- {
- result.Add(new TypedArgument(property.Name, property.Value.GetDecimal()));
- }
- else if (property.Value.ValueKind == JsonValueKind.String)
- {
- result.Add(new TypedArgument(property.Name, property.Value.GetString()));
- }
- if (arg != null)
- result.Add(arg);
- }
-
- }
- return result.ToArray();
- }
- #endregion
-
- }
- }
|