diff --git a/src/LogExpert.sln b/src/LogExpert.sln index f8d00794..81360b89 100644 --- a/src/LogExpert.sln +++ b/src/LogExpert.sln @@ -56,8 +56,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "setup", "setup", "{C625E7C2 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegexColumnizer.UnitTests", "RegexColumnizer.UnitTests\RegexColumnizer.UnitTests.csproj", "{FBFB598D-B94A-4AD3-A355-0D5A618CEEE3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogexpertgRPCService", "LogexpertgRPCService\LogexpertgRPCService.csproj", "{D31D1721-9DEA-45A4-B813-D5023B2EC2CC}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.Core", "Logexpert.Core\LogExpert.Core.csproj", "{F49C6738-3F62-4890-8FF2-1F53A0F0A2CD}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.Resources", "Logexpert.Resources\LogExpert.Resources.csproj", "{578CC5D5-1DCD-47C2-8BD3-B32C14635BEC}" @@ -138,10 +136,6 @@ Global {FBFB598D-B94A-4AD3-A355-0D5A618CEEE3}.Debug|Any CPU.Build.0 = Debug|Any CPU {FBFB598D-B94A-4AD3-A355-0D5A618CEEE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {FBFB598D-B94A-4AD3-A355-0D5A618CEEE3}.Release|Any CPU.Build.0 = Release|Any CPU - {D31D1721-9DEA-45A4-B813-D5023B2EC2CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D31D1721-9DEA-45A4-B813-D5023B2EC2CC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D31D1721-9DEA-45A4-B813-D5023B2EC2CC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D31D1721-9DEA-45A4-B813-D5023B2EC2CC}.Release|Any CPU.Build.0 = Release|Any CPU {F49C6738-3F62-4890-8FF2-1F53A0F0A2CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F49C6738-3F62-4890-8FF2-1F53A0F0A2CD}.Debug|Any CPU.Build.0 = Debug|Any CPU {F49C6738-3F62-4890-8FF2-1F53A0F0A2CD}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/LogExpert/Classes/LogExpertApplicationContext.cs b/src/LogExpert/Classes/LogExpertApplicationContext.cs index b0a2af95..28099012 100644 --- a/src/LogExpert/Classes/LogExpertApplicationContext.cs +++ b/src/LogExpert/Classes/LogExpertApplicationContext.cs @@ -1,7 +1,7 @@ -using System; -using System.Windows.Forms; +using LogExpert.Controls.LogTabWindow; -using LogExpert.Controls.LogTabWindow; +using System; +using System.Windows.Forms; namespace LogExpert.Classes { diff --git a/src/LogExpert/Classes/LogExpertProxy.cs b/src/LogExpert/Classes/LogExpertProxy.cs index 31513af7..40f97257 100644 --- a/src/LogExpert/Classes/LogExpertProxy.cs +++ b/src/LogExpert/Classes/LogExpertProxy.cs @@ -1,5 +1,4 @@ using LogExpert.Controls.LogTabWindow; -using LogExpert.Grpc; using LogExpert.Interface; using NLog; @@ -10,11 +9,11 @@ namespace LogExpert.Classes { - internal class LogExpertProxy : LogExpertService.LogExpertServiceBase, ILogExpertProxy + internal class LogExpertProxy : ILogExpertProxy { #region Fields - private static readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); [NonSerialized] private readonly List _windowList = []; @@ -113,7 +112,7 @@ public void NewWindowOrLockedWindow(string[] fileNames) public void NewWindowWorker(string[] fileNames) { _logger.Info("Creating new LogTabWindow"); - LogTabWindow logWin = new(fileNames.Length > 0 ? fileNames : null, _logWindowIndex++, true) + LogTabWindow logWin = new(fileNames?.Length > 0 ? fileNames : null, _logWindowIndex++, true) { LogExpertProxy = this }; diff --git a/src/LogExpert/LogExpert.csproj b/src/LogExpert/LogExpert.csproj index 9d3c42b9..d57155ce 100644 --- a/src/LogExpert/LogExpert.csproj +++ b/src/LogExpert/LogExpert.csproj @@ -61,10 +61,6 @@ - - - - @@ -72,7 +68,6 @@ - diff --git a/src/LogExpert/Program.cs b/src/LogExpert/Program.cs index 27d21ec5..4dbdac5e 100644 --- a/src/LogExpert/Program.cs +++ b/src/LogExpert/Program.cs @@ -1,15 +1,14 @@ -using Grpc.Core; -using Grpc.Net.Client; - -using LogExpert.Classes; +using LogExpert.Classes; using LogExpert.Config; using LogExpert.Controls.LogTabWindow; using LogExpert.Core.Classes; +using LogExpert.Core.Classes.IPC; using LogExpert.Core.Config; using LogExpert.Dialogs; using LogExpert.UI.Dialogs; -using LogexpertGRPCService.Services; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using NLog; @@ -17,10 +16,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Pipes; using System.Reflection; using System.Security; using System.Security.Principal; +using System.Text; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; namespace LogExpert @@ -28,7 +30,12 @@ namespace LogExpert internal static class Program { #region Fields - private static readonly ILogger _logger = LogManager.GetLogger("Program"); + + private static readonly Logger _logger = LogManager.GetLogger("Program"); + private const string PIPE_SERVER_NAME = "LogExpert_IPC"; + private const int PIPE_CONNECTION_TIMEOUT_IN_MS = 5000; + private static readonly CancellationTokenSource _cts = new(); + #endregion #region Private Methods @@ -41,21 +48,16 @@ private static void Main(string[] orgArgs) { try { - var server = new Server() - { - Services = { Grpc.LogExpertService.BindService(new LogExpertServiceImpl()) }, - Ports = { new ServerPort("localhost", 5001, ServerCredentials.Insecure) } - }; - - Sub_Main(server, orgArgs); + Sub_Main(orgArgs); } catch (SecurityException se) { MessageBox.Show("Insufficient system rights for LogExpert. Maybe you have started it from a network drive. Please start LogExpert from a local drive.\n(" + se.Message + ")", "LogExpert Error"); + _cts.Cancel(); } } - private static void Sub_Main(Server server, string[] orgArgs) + private static void Sub_Main(string[] orgArgs) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.ThreadException += Application_ThreadException; @@ -70,25 +72,8 @@ private static void Sub_Main(Server server, string[] orgArgs) CmdLineString configFile = new("config", false, "A configuration (settings) file"); cmdLine.RegisterParameter(configFile); string[] remainingArgs = cmdLine.Parse(orgArgs); + string[] absoluteFilePaths = GenerateAbsoluteFilePaths(remainingArgs); - List argsList = []; - - // This loop tries to convert relative file names into absolute file names (assuming that platform file names are given). - // It tolerates errors, to give file system plugins (e.g. sftp) a change later. - // TODO: possibly should be moved to LocalFileSystem plugin - foreach (string fileArg in remainingArgs) - { - try - { - FileInfo info = new(fileArg); - argsList.Add(info.Exists ? info.FullName : fileArg); - } - catch (Exception) - { - argsList.Add(fileArg); - } - } - string[] args = [.. argsList]; if (configFile.Exists) { FileInfo cfgFileInfo = new(configFile.Value); @@ -102,6 +87,7 @@ private static void Sub_Main(Server server, string[] orgArgs) MessageBox.Show(@"Config file not found", @"LogExpert"); } } + PluginRegistry.PluginRegistry.Instance.Create(ConfigManager.ConfigDir, ConfigManager.Settings.Preferences.pollingInterval); int pId = Process.GetCurrentProcess().SessionId; @@ -117,52 +103,29 @@ private static void Sub_Main(Server server, string[] orgArgs) // first application instance Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - LogTabWindow logWin = new(args.Length > 0 ? args : null, 1, false); + LogTabWindow logWin = new(absoluteFilePaths.Length > 0 ? absoluteFilePaths : null, 1, false); // first instance WindowsIdentity wi = WindowsIdentity.GetCurrent(); - - server.Start(); - - //IpcServerChannel ipcChannel = new IpcServerChannel("LogExpert" + pId); - //ChannelServices.RegisterChannel(ipcChannel, false); - //RemotingConfiguration.RegisterWellKnownServiceType(typeof(LogExpertProxy), "LogExpertProxy", WellKnownObjectMode.Singleton); LogExpertProxy proxy = new(logWin); - //RemotingServices.Marshal(proxy, "LogExpertProxy"); - LogExpertApplicationContext context = new(proxy, logWin); - Application.Run(context); - //ChannelServices.UnregisterChannel(ipcChannel); - server.ShutdownAsync().Wait(); + Task.Run(() => RunServerLoopAsync(SendMessageToProxy, proxy, _cts.Token)); + + Application.Run(context); } else { int counter = 3; Exception errMsg = null; - //IpcClientChannel ipcChannel = new IpcClientChannel("LogExpertClient#" + pId, null); - //ChannelServices.RegisterChannel(ipcChannel, false); while (counter > 0) { try { - using var channel = GrpcChannel.ForAddress("https://localhost:5001"); - var client = new Grpc.LogExpertService.LogExpertServiceClient(channel); - - //Console.WriteLine("Greeting: " + reply.Result); - // another instance already exists WindowsIdentity wi = WindowsIdentity.GetCurrent(); - //LogExpertProxy proxy = (LogExpertProxy)Activator.GetObject(typeof(LogExpertProxy), "ipc://LogExpert" + pId + "/LogExpertProxy"); - if (settings.Preferences.allowOnlyOneInstance) - { - client.LoadFiles(new Grpc.FileNames { FileNames_ = { args } }); - } - else - { - client.NewWindowOrLockedWindow(new Grpc.FileNames { FileNames_ = { args } }); - } - + var command = SerializeCommandIntoNonFormattedJSON(absoluteFilePaths, settings.Preferences.allowOnlyOneInstance); + SendCommandToServer(command); break; } catch (Exception e) @@ -188,40 +151,187 @@ private static void Sub_Main(Server server, string[] orgArgs) settings.Preferences.ShowErrorMessageAllowOnlyOneInstances = !a.DoNotShowThisMessageAgain; ConfigManager.Save(SettingsFlags.All); } - - //MessageBox.Show($"Only one instance allowed, uncheck \"View Settings => Allow only 1 Instances\" to start multiple instances!", "Logexpert"); } } mutex.Close(); + _cts.Cancel(); } catch (Exception ex) { _logger.Error(ex, "Mutex error, giving up: "); + _cts.Cancel(); MessageBox.Show($"Cannot open connection to first instance ({ex.Message})", "LogExpert"); } } + private static string SerializeCommandIntoNonFormattedJSON(string[] fileNames, bool allowOnlyOneInstance) + { + var message = new IpcMessage() + { + Type = allowOnlyOneInstance ? IpcMessageType.NewWindowOrLockedWindow : IpcMessageType.NewWindow, + Payload = JObject.FromObject(new LoadPayload { Files = [.. fileNames] }) + }; + + return JsonConvert.SerializeObject(message, Formatting.None); + } + + // This loop tries to convert relative file names into absolute file names (assuming that platform file names are given). + // It tolerates errors, to give file system plugins (e.g. sftp) a change later. + // TODO: possibly should be moved to LocalFileSystem plugin + private static string[] GenerateAbsoluteFilePaths(string[] remainingArgs) + { + List argsList = []; + + foreach (string fileArg in remainingArgs) + { + try + { + FileInfo info = new(fileArg); + argsList.Add(info.Exists ? info.FullName : fileArg); + } + catch (Exception) + { + argsList.Add(fileArg); + } + } + + return [.. argsList]; + } + + private static void SendMessageToProxy(IpcMessage message, LogExpertProxy proxy) + { + switch (message.Type) + { + case IpcMessageType.Load: + { + var payLoad = message.Payload.ToObject(); + + if (CheckPayload(payLoad)) + { + proxy.LoadFiles([.. payLoad.Files]); + } + } + break; + case IpcMessageType.NewWindow: + { + var payLoad = message.Payload.ToObject(); + if (CheckPayload(payLoad)) + { + proxy.NewWindow([.. payLoad.Files]); + } + } + break; + case IpcMessageType.NewWindowOrLockedWindow: + { + var payLoad = message.Payload.ToObject(); + if (CheckPayload(payLoad)) + { + proxy.NewWindowOrLockedWindow([.. payLoad.Files]); + } + } + break; + default: + _logger.Error($"Unknown IPC Message Type {message.Type}"); + break; + } + } + + private static bool CheckPayload(LoadPayload payLoad) + { + if (payLoad == null) + { + _logger.Error("Invalid payload for NewWindow command"); + return false; + } + + return true; + } + + private static void SendCommandToServer(string command) + { + using var client = new NamedPipeClientStream(".", PIPE_SERVER_NAME, PipeDirection.Out); + + try + { + client.Connect(PIPE_CONNECTION_TIMEOUT_IN_MS); + } + catch (TimeoutException) + { + _logger.Error("Timeout connecting to pipe server"); + return; + } + catch (IOException ex) + { + _logger.Warn(ex, "An I/O error occurred while connecting to the pipe server."); + return; + } + catch (UnauthorizedAccessException ex) + { + _logger.Warn(ex, "Unauthorized access while connecting to the pipe server."); + return; + } + + using var writer = new StreamWriter(client, Encoding.UTF8) { AutoFlush = true }; + writer.WriteLine(command); + } + + private static async Task RunServerLoopAsync(Action onCommand, LogExpertProxy proxy, CancellationToken cancellationToken) + { + while (cancellationToken.IsCancellationRequested == false) + { + using var server = new NamedPipeServerStream( + PIPE_SERVER_NAME, + PipeDirection.In, + 1, + PipeTransmissionMode.Message, + PipeOptions.Asynchronous); + + try + { + await server.WaitForConnectionAsync(cancellationToken); + using var reader = new StreamReader(server, Encoding.UTF8); + string line = await reader.ReadLineAsync(cancellationToken); + + if (line != null) + { + var message = JsonConvert.DeserializeObject(line); + onCommand(message, proxy); + } + } + catch (OperationCanceledException) + { + break; + } + catch (Exception ex) + { + _logger.Warn(ex, "Pipe server error"); + } + } + } + [STAThread] private static void ShowUnhandledException(object exceptionObject) { string errorText = string.Empty; - string stackTrace = string.Empty; + string stackTrace; + if (exceptionObject is Exception exception) { errorText = exception.Message; - stackTrace = "\r\n" + exception.GetType().Name + "\r\n" + - exception.StackTrace; + stackTrace = $"\r\n{exception.GetType().Name}\r\n{exception.StackTrace}"; } else { stackTrace = exceptionObject.ToString(); string[] lines = stackTrace.Split('\n'); + if (lines != null && lines.Length > 0) { errorText = lines[0]; } } + ExceptionWindow win = new(errorText, stackTrace); _ = win.ShowDialog(); } @@ -234,9 +344,11 @@ private static void Application_ThreadException(object sender, ThreadExceptionEv { _logger.Fatal(e); - //ShowUnhandledException(e.Exception); - Thread thread = new(ShowUnhandledException); - thread.IsBackground = true; + Thread thread = new(ShowUnhandledException) + { + IsBackground = true + }; + thread.SetApartmentState(ApartmentState.STA); thread.Start(e.Exception); thread.Join(); @@ -247,9 +359,12 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc _logger.Fatal(e); object exceptionObject = e.ExceptionObject; - //ShowUnhandledException(exceptionObject); - Thread thread = new(ShowUnhandledException); - thread.IsBackground = true; + + Thread thread = new(ShowUnhandledException) + { + IsBackground = true + }; + thread.SetApartmentState(ApartmentState.STA); thread.Start(exceptionObject); thread.Join(); diff --git a/src/LogExpert/gRPC/LogExpert.proto b/src/LogExpert/gRPC/LogExpert.proto deleted file mode 100644 index 3a082a08..00000000 --- a/src/LogExpert/gRPC/LogExpert.proto +++ /dev/null @@ -1,45 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "LogExpert.Grpc"; - -package logexpert; - -// The log service definition. -service LogExpertService { - // Sends a log message - rpc SendLog (LogRequest) returns (LogReply) {} - rpc LoadFiles (FileNames); - rpc NewWindow (FileNames); - rpc NewWindowOrLockedWindow (FileNames); - rpc WindowClosed(); - rpc GetLogWindowCount() returns (Count); -} - -message FileNames -{ - repeated string FileNames = 4; -} - -message Count -{ - int32 count = 0; -} - -message FilesReply -{ - bool success = false; -} - -// The request message containing the log message. -message LogRequest -{ - string message = 1; -} - -message LoadFiles(repeated ) - -// The response message containing the response. -message LogReply -{ - string result = 1; -} \ No newline at end of file diff --git a/src/Logexpert.Core/Classes/CmdLine.cs b/src/Logexpert.Core/Classes/CmdLine.cs index 6f2e151a..cea24b31 100644 --- a/src/Logexpert.Core/Classes/CmdLine.cs +++ b/src/Logexpert.Core/Classes/CmdLine.cs @@ -3,6 +3,7 @@ * */ +//TODO Replace with https://github.com/commandlineparser/commandline namespace LogExpert.Core.Classes { /// @@ -32,29 +33,14 @@ public CmdLineException(string message) /// Parameters are words in the command line beginning with a hyphen (-). /// The value of the parameter is the next word in /// - public class CmdLineParameter + /// + /// Creates a new instance of this class. + /// + /// Name of parameter. + /// Require that the parameter is present in the command line. + /// The explanation of the parameter to add to the help screen. + public class CmdLineParameter(string name, bool required, string helpMessage) { - #region Fields - - #endregion - - #region cTor - - /// - /// Creates a new instance of this class. - /// - /// Name of parameter. - /// Require that the parameter is present in the command line. - /// The explanation of the parameter to add to the help screen. - public CmdLineParameter(string name, bool required, string helpMessage) - { - Name = name; - Required = required; - Help = helpMessage; - } - - #endregion - #region Properties /// @@ -65,7 +51,7 @@ public CmdLineParameter(string name, bool required, string helpMessage) /// /// Returns the help message associated with the parameter. /// - public string Help { get; } = ""; + public string Help { get; } = helpMessage; /// /// Returns true if the parameter was found in the command line. @@ -75,12 +61,12 @@ public CmdLineParameter(string name, bool required, string helpMessage) /// /// Returns true if the parameter is required in the command line. /// - public bool Required { get; } = false; + public bool Required { get; } = required; /// /// Returns the name of the parameter. /// - public string Name { get; } + public string Name { get; } = name; #endregion @@ -195,16 +181,8 @@ public static implicit operator int(CmdLineInt s) /// /// Represents an string command line parameter. /// - public class CmdLineString : CmdLineParameter + public class CmdLineString(string name, bool required, string helpMessage) : CmdLineParameter(name, required, helpMessage) { - #region cTor - - public CmdLineString(string name, bool required, string helpMessage) - : base(name, required, helpMessage) - { - } - - #endregion #region Public methods @@ -250,11 +228,11 @@ public CmdLineParameter this[string name] { get { - if (!parameters.ContainsKey(name)) + if (parameters.TryGetValue(name, out CmdLineParameter? value) == false) { throw new CmdLineException(name, "Not a registered parameter."); } - return parameters[name]; + return value; } } @@ -304,8 +282,8 @@ public string[] Parse(string[] args) if (args[i].Length > 1 && args[i][0] == '-') { // The current string is a parameter name - string key = args[i].Substring(1, args[i].Length - 1).ToLower(); - string value = ""; + string key = args[i][1..].ToLower(); + string argsValue = string.Empty; i++; if (i < args.Length) { @@ -316,21 +294,21 @@ public string[] Parse(string[] args) else { // The next string is a value, read the value and move forward - value = args[i]; + argsValue = args[i]; i++; } } - if (!parameters.ContainsKey(key)) + if (parameters.TryGetValue(key, out CmdLineParameter? cmdLineParameter) == false) { throw new CmdLineException(key, "Parameter is not allowed."); } - if (parameters[key].Exists) + if (cmdLineParameter.Exists) { throw new CmdLineException(key, "Parameter is specified more than once."); } - parameters[key].SetValue(value); + cmdLineParameter.SetValue(argsValue); } else { @@ -343,7 +321,7 @@ public string[] Parse(string[] args) // Check that required parameters are present in the command line. foreach (string key in parameters.Keys) { - if (parameters[key].Required && !parameters[key].Exists) + if (parameters[key].Required && parameters[key].Exists == false) { throw new CmdLineException(key, "Required parameter is not found."); } @@ -400,9 +378,9 @@ public ConsoleCmdLine() public new string[] Parse(string[] args) { - string[] ret = null; + string[] ret = []; - string error = ""; + string error = string.Empty; try { @@ -415,13 +393,11 @@ public ConsoleCmdLine() if (this["help"].Exists) { - //foreach(string s in base.HelpScreen().Split('\n')) - // Console.WriteLine(s); Console.WriteLine(HelpScreen()); Environment.Exit(0); } - if (error != "") + if (error != string.Empty) { Console.WriteLine(error); Console.WriteLine("Use -help for more information."); diff --git a/src/Logexpert.Core/Classes/IPC/IpcMessage.cs b/src/Logexpert.Core/Classes/IPC/IpcMessage.cs new file mode 100644 index 00000000..2549ed89 --- /dev/null +++ b/src/Logexpert.Core/Classes/IPC/IpcMessage.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json.Linq; + +namespace LogExpert.Core.Classes.IPC +{ + public class IpcMessage + { + public int Version { get; set; } + + public IpcMessageType Type { get; set; } = IpcMessageType.Load; + + public JObject Payload { get; set; } = []; + } +} diff --git a/src/Logexpert.Core/Classes/IPC/IpcMessageType.cs b/src/Logexpert.Core/Classes/IPC/IpcMessageType.cs new file mode 100644 index 00000000..cd4a4f7f --- /dev/null +++ b/src/Logexpert.Core/Classes/IPC/IpcMessageType.cs @@ -0,0 +1,9 @@ +namespace LogExpert.Core.Classes.IPC +{ + public enum IpcMessageType + { + Load, + NewWindow, + NewWindowOrLockedWindow + } +} diff --git a/src/Logexpert.Core/Classes/IPC/LoadPayload.cs b/src/Logexpert.Core/Classes/IPC/LoadPayload.cs new file mode 100644 index 00000000..6d5252a3 --- /dev/null +++ b/src/Logexpert.Core/Classes/IPC/LoadPayload.cs @@ -0,0 +1,7 @@ +namespace LogExpert.Core.Classes.IPC +{ + public class LoadPayload + { + public List Files { get; set; } = []; + } +} diff --git a/src/Logexpert.Core/Classes/Persister/Persister.cs b/src/Logexpert.Core/Classes/Persister/Persister.cs index 33eb710d..c5057224 100644 --- a/src/Logexpert.Core/Classes/Persister/Persister.cs +++ b/src/Logexpert.Core/Classes/Persister/Persister.cs @@ -52,7 +52,7 @@ public class Persister { #region Fields - private static readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); #endregion @@ -269,16 +269,21 @@ private static List ReadFilterTabs(XmlElement startNode) if (filterTabsNode != null) { XmlNodeList filterTabNodeList = filterTabsNode.ChildNodes; // all "filterTab" nodes + foreach (XmlNode node in filterTabNodeList) { PersistenceData persistenceData = ReadPersistenceDataFromNode(node); XmlNode filterNode = node.SelectSingleNode("tabFilter"); + if (filterNode != null) { List filterList = ReadFilter(filterNode as XmlElement); - FilterTabData data = new(); - data.PersistenceData = persistenceData; - data.FilterParams = filterList[0]; // there's only 1 + FilterTabData data = new() + { + PersistenceData = persistenceData, + FilterParams = filterList[0] // there's only 1 + }; + dataList.Add(data); } } @@ -322,9 +327,17 @@ private static List ReadFilter(XmlElement startNode) string base64Text = subNode.InnerText; byte[] data = Convert.FromBase64String(base64Text); MemoryStream stream = new(data); - FilterParams filterParams = JsonSerializer.Deserialize(stream); - filterParams.Init(); - filterList.Add(filterParams); + + try + { + FilterParams filterParams = JsonSerializer.Deserialize(stream); + filterParams.Init(); + filterList.Add(filterParams); + } + catch (JsonException ex) + { + _logger.Error($"Error while deserializing filter params. Exception Message: {ex.Message}"); + } } } } diff --git a/src/LogexpertgRPCService/LogexpertgRPCService.csproj b/src/LogexpertgRPCService/LogexpertgRPCService.csproj deleted file mode 100644 index a5d0b2bf..00000000 --- a/src/LogexpertgRPCService/LogexpertgRPCService.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - net8.0 - enable - false - enable - - - true - ..\Solution Items\Key.snk - - - - - - - - \ No newline at end of file diff --git a/src/LogexpertgRPCService/Program.cs b/src/LogexpertgRPCService/Program.cs deleted file mode 100644 index 7ecdb775..00000000 --- a/src/LogexpertgRPCService/Program.cs +++ /dev/null @@ -1,14 +0,0 @@ -using LogexpertGRPCService.Services; - -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. -builder.Services.AddGrpc(); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -app.MapGrpcService(); -app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); - -app.Run(); diff --git a/src/LogexpertgRPCService/Properties/launchSettings.json b/src/LogexpertgRPCService/Properties/launchSettings.json deleted file mode 100644 index 25ca2150..00000000 --- a/src/LogexpertgRPCService/Properties/launchSettings.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "http://localhost:5282", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "https://localhost:7125;http://localhost:5282", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/LogexpertgRPCService/Protos/Logexpert.proto b/src/LogexpertgRPCService/Protos/Logexpert.proto deleted file mode 100644 index 838357a7..00000000 --- a/src/LogexpertgRPCService/Protos/Logexpert.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "LogExpert.Grpc"; - -import "google/protobuf/empty.proto"; - -package logexpert; - -// The log service definition. -service LogExpertService -{ - // Sends a log message - rpc SendLog (LogRequest) returns (LogReply) ; - rpc LoadFiles (FileNames) returns (FilesReply); - rpc NewWindow (FileNames) returns (FilesReply); - rpc NewWindowOrLockedWindow (FileNames) returns (FilesReply); - //is this really needed? - rpc WindowClosed(google.protobuf.Empty) returns (google.protobuf.Empty); - rpc GetLogWindowCount(google.protobuf.Empty) returns (Count); -} - -message FileNames -{ - repeated string fileNames = 1; -} - -message Count -{ - int32 count = 1; -} - -message FilesReply -{ - bool success = 1; -} - -// The request message containing the log message. -message LogRequest -{ - string message = 1; -} - -// The response message containing the response. -message LogReply -{ - string result = 1; -} \ No newline at end of file diff --git a/src/LogexpertgRPCService/Services/LogExpertServiceImpl.cs b/src/LogexpertgRPCService/Services/LogExpertServiceImpl.cs deleted file mode 100644 index 86a237d4..00000000 --- a/src/LogexpertgRPCService/Services/LogExpertServiceImpl.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Grpc.Core; - -using LogExpert.Grpc; - -namespace LogexpertGRPCService.Services -{ - public class LogExpertServiceImpl : LogExpertService.LogExpertServiceBase - { - public override Task SendLog(LogRequest request, ServerCallContext context) - { - return Task.FromResult(new LogReply { Result = "Hello " + request.Message }); - } - - public override Task LoadFiles(FileNames fileNames, ServerCallContext context) - { - return Task.FromResult(new FilesReply { Success = true }); - } - - public override Task NewWindow(FileNames fileNames, ServerCallContext context) - { - return Task.FromResult(new FilesReply { Success = true }); - } - - public override Task NewWindowOrLockedWindow(FileNames fileNames, ServerCallContext context) - { - return Task.FromResult(new FilesReply { Success = true }); - } - - //public override void WindowClosed() - //{ - - //} - } -} diff --git a/src/LogexpertgRPCService/appsettings.Development.json b/src/LogexpertgRPCService/appsettings.Development.json deleted file mode 100644 index 0c208ae9..00000000 --- a/src/LogexpertgRPCService/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/src/LogexpertgRPCService/appsettings.json b/src/LogexpertgRPCService/appsettings.json deleted file mode 100644 index 1aef5074..00000000 --- a/src/LogexpertgRPCService/appsettings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Kestrel": { - "EndpointDefaults": { - "Protocols": "Http2" - } - } -}