Logging for Genesis toolbox

This commit is contained in:
Stoyan Zlatev
2023-06-05 11:33:01 +02:00
parent 33104bdca3
commit 559f01e549
14 changed files with 313 additions and 110 deletions
+1 -1
View File
@@ -155,7 +155,7 @@
</site>
<site name="MeterProcessState" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\laa_production\Common\Service\MeterProcessState" />
<virtualDirectory path="/" physicalPath="C:\Users\SZLATEV\source\repos\laa_production\Common\Service\MeterProcessState" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:56011:localhost" />
@@ -34,6 +34,7 @@
encoding: Encoding.UTF8,
content: JsonConvert.SerializeObject(new
{
windowsUser = Environment.UserName,
software,
functions
}));
@@ -78,6 +79,7 @@
appId,
username,
password,
windowsUser = Environment.UserName,
}));
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage))
@@ -101,5 +103,36 @@
.ConfigureAwait(true)
.GetAwaiter()
.GetResult();
internal static void LogAction(string buttonText, string buttonTag, string user, int appId)
=> Task
.Run(async () =>
{
try
{
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, "api/software/functions"))
{
httpRequestMessage.Content = new StringContent(
mediaType: APPLICATION_JSON,
encoding: Encoding.UTF8,
content: JsonConvert.SerializeObject(new
{
WindowsUser = Environment.UserName,
Action = "ACCESS",
AppId = appId,
Message = $"User '{user}' accessed '{buttonText}' with Tag: {buttonTag}"
}));
_ = await httpClient.SendAsync(httpRequestMessage);
}
}
catch (Exception)
{
// TODO: Log the error message.
}
})
.ConfigureAwait(true)
.GetAwaiter()
.GetResult();
}
}
@@ -8,11 +8,12 @@
{
internal const string UNAVAILABLE = "Genesis Toolbox is currently not available.";
private static IEnumerable<SoftwareFunctions> softwareFunctions;
internal static int Id { get; private set; }
internal static string User { get; private set; }
internal static bool IsAuthorized { get; private set; }
internal static bool Initialized { get; private set; }
@@ -40,6 +41,7 @@
{
softwareFunctions = ApplicationHttp.GetSoftwareFunction<SoftwareFunctions>(Id, username, password);
IsAuthorized = softwareFunctions != null;
User = username;
if (!IsAuthorized)
{
+2
View File
@@ -13,7 +13,9 @@
[STAThread]
internal static void Main()
{
// Initializes application state for the hole application as static properties and methods.
ApplicationState.Initialize();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMainForm());
+120 -89
View File
@@ -41,95 +41,6 @@ namespace Xylem.Common.Ui.GenesisToolBox
lblVersionNumber.Text = $@"Version: {version.Major}.{version.Minor}.{version.Build}";
}
private void InitializeFormState()
{
foreach (var control in this.Controls)
{
if (control is GroupBox groupBox)
{
groupBox.Hide();
}
}
this.btnSetup.Tag = SoftwareFunctions.GENERAL_SETUP;
this.btnAlarm.Tag = SoftwareFunctions.GENERAL_ALARM;
this.btnRegisterStore.Tag = SoftwareFunctions.GENERAL_REGISTER_STORE;
this.btnTempLogger.Tag = SoftwareFunctions.GENERAL_TEMP_METER;
this.btnStreamingQuality.Tag = SoftwareFunctions.GENERAL_STREAM_QUALITY;
this.btnFwUpdate.Tag = SoftwareFunctions.GENERAL_FIRMWARE_UPDATE;
this.btnLutUpdate.Tag = SoftwareFunctions.GENERAL_LUT_UPDATE;
this.button4.Tag = SoftwareFunctions.GENERAL_LUT_MANAGEMENT;
this.btnPressure.Tag = SoftwareFunctions.GENERAL_PRESSURE_LOG;
this.button1.Tag = SoftwareFunctions.GENERAL_PULS_CONFIG;
this.btnPassword.Tag = SoftwareFunctions.LAA_PASSWORD;
this.btnRegHistory.Tag = SoftwareFunctions.LAA_REGISTER_HISTORY;
this.btnPara.Tag = SoftwareFunctions.LAA_PARAMETERIZATION;
this.button2.Tag = SoftwareFunctions.LAA_PROCESS_PARAMETER;
this.button5.Tag = SoftwareFunctions.LAA_MAPPING_NA;
this.btnLegacyTestApp.Tag = SoftwareFunctions.DEV_LEGACY_TEST_APP;
this.btnFiles.Tag = SoftwareFunctions.DEV_FILE_CONTROL;
this.BtnFileSplit.Tag = SoftwareFunctions.DEV_FILE_SPLIT;
this.btnLowLevelTools.Tag = SoftwareFunctions.DEV_LOW_LEVEL_TOOLS;
if (!ApplicationState.Initialized)
{
this.Controls.Add(new Label()
{
Dock = DockStyle.Fill,
Text = ApplicationState.UNAVAILABLE,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold),
ForeColor = Color.DarkRed,
Padding = new Padding(15)
});
}
else if (!ApplicationState.IsAuthorized)
{
this.Controls.Add(new LoginForm(this.LoginFormSubmitted));
}
else
{
this.ShowAvailableSoftwareFunctions();
}
}
private void LoginFormSubmitted(string username, string password, object sender)
{
if (sender is LoginForm loginForm)
{
var errorMessage = default(string);
if (ApplicationState.Authorize(username, password, out errorMessage))
{
this.Controls.Remove(loginForm);
this.ShowAvailableSoftwareFunctions();
}
loginForm.ShowError(errorMessage);
}
}
private void ShowAvailableSoftwareFunctions()
{
foreach (var control in this.Controls)
{
if (control is GroupBox groupBox)
{
foreach (var groupBoxControl in groupBox.Controls)
{
if (groupBoxControl is Button button && button.Tag is SoftwareFunctions softwareFunction)
{
button.Enabled = ApplicationState.IsEnabled(softwareFunction);
}
}
groupBox.Show();
}
}
}
private void btnSetup_Click(Object sender, EventArgs e)
{
var form = new FrmSetup();
@@ -481,5 +392,125 @@ namespace Xylem.Common.Ui.GenesisToolBox
form.Closed += Form_Closed;
Hide();
}
#region Form initialization
private void HideContent()
{
foreach (var control in this.Controls)
{
if (control is GroupBox groupBox)
{
groupBox.Hide();
}
}
}
private void SetSoftwareFunctions()
{
this.btnSetup.Tag = SoftwareFunctions.GENERAL_SETUP;
this.btnAlarm.Tag = SoftwareFunctions.GENERAL_ALARM;
this.btnRegisterStore.Tag = SoftwareFunctions.GENERAL_REGISTER_STORE;
this.btnTempLogger.Tag = SoftwareFunctions.GENERAL_TEMP_METER;
this.btnStreamingQuality.Tag = SoftwareFunctions.GENERAL_STREAM_QUALITY;
this.btnFwUpdate.Tag = SoftwareFunctions.GENERAL_FIRMWARE_UPDATE;
this.btnLutUpdate.Tag = SoftwareFunctions.GENERAL_LUT_UPDATE;
this.button4.Tag = SoftwareFunctions.GENERAL_LUT_MANAGEMENT;
this.btnPressure.Tag = SoftwareFunctions.GENERAL_PRESSURE_LOG;
this.button1.Tag = SoftwareFunctions.GENERAL_PULS_CONFIG;
this.btnPassword.Tag = SoftwareFunctions.LAA_PASSWORD;
this.btnRegHistory.Tag = SoftwareFunctions.LAA_REGISTER_HISTORY;
this.btnPara.Tag = SoftwareFunctions.LAA_PARAMETERIZATION;
this.button2.Tag = SoftwareFunctions.LAA_PROCESS_PARAMETER;
this.button5.Tag = SoftwareFunctions.LAA_MAPPING_NA;
this.btnLegacyTestApp.Tag = SoftwareFunctions.DEV_LEGACY_TEST_APP;
this.btnFiles.Tag = SoftwareFunctions.DEV_FILE_CONTROL;
this.BtnFileSplit.Tag = SoftwareFunctions.DEV_FILE_SPLIT;
this.btnLowLevelTools.Tag = SoftwareFunctions.DEV_LOW_LEVEL_TOOLS;
}
private void ShowErrorMessage()
{
this.Controls.Add(new Label()
{
Dock = DockStyle.Fill,
Text = ApplicationState.UNAVAILABLE,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold),
ForeColor = Color.DarkRed,
Padding = new Padding(15)
});
}
private void LoginFormSubmitted(string username, string password, object sender)
{
if (sender is LoginForm loginForm)
{
var errorMessage = default(string);
if (ApplicationState.Authorize(username, password, out errorMessage))
{
this.Controls.Remove(loginForm);
this.ShowAvailableSoftwareFunctions();
}
loginForm.ShowError(errorMessage);
}
}
private void ShowAvailableSoftwareFunctions()
{
foreach (var control in this.Controls)
{
if (control is GroupBox groupBox)
{
foreach (var groupBoxControl in groupBox.Controls)
{
if (groupBoxControl is Button button)
{
if (button.Tag is SoftwareFunctions softwareFunction)
{
button.Enabled = ApplicationState.IsEnabled(softwareFunction);
}
button.Click += LogUserAction;
}
}
groupBox.Show();
}
}
}
private void LogUserAction(object sender, EventArgs e)
{
if (sender is Button button)
{
ApplicationHttp.LogAction(button.Text, $"{button.Tag}", ApplicationState.User, ApplicationState.Id);
}
}
private void InitializeFormState()
{
this.HideContent();
this.SetSoftwareFunctions();
if (!ApplicationState.Initialized)
{
this.ShowErrorMessage();
}
else if (!ApplicationState.IsAuthorized)
{
this.Controls.Add(new LoginForm(this.LoginFormSubmitted));
}
else
{
this.ShowAvailableSoftwareFunctions();
}
}
#endregion Form initialization
}
}
@@ -53,15 +53,19 @@
.ExecuteReader(x => x.GetString());
public short Login(string username, string password)
=> this.sqlClient.FirstOrDefault($@"
SELECT TOP 1 [MitarbeiterNr]
FROM [Mitarbeiter]
WHERE [Benutzername] LIKE @{nameof(username)}
AND [PasswordHash] LIKE @{nameof(password)}",
parameters => parameters
.Add(nameof(username), username)
.Add(nameof(password), password),
reader => reader.GetSmallint());
{
var userId = this.sqlClient
.FirstOrDefault($@"
SELECT TOP 1 [MitarbeiterNr]
FROM [Mitarbeiter]
WHERE [Benutzername] LIKE @{nameof(username)}
AND [PasswordHash] LIKE @{nameof(password)}",
parameters => parameters
.Add(nameof(username), username)
.Add(nameof(password), password),
reader => reader.GetSmallint());
return userId;
}
public int ResetPassword(string username)
=> this.sqlClient
@@ -0,0 +1,9 @@
namespace LaaProductionWeb.Services.Interfaces
{
using System;
public interface ILoggerService
{
void Log(Action<LoggerService.LogModel> logModel);
}
}
@@ -10,7 +10,7 @@
void DeleteFunction(int funcId);
short FindAndUpdateSoftware(string name, IEnumerable<string> functions);
short FindAndUpdateSoftware(string windowsUser, string software, IEnumerable<string> functions);
IEnumerable<SoftwareFunction> GetAllSoftwareFunctions();
@@ -61,11 +61,13 @@
<Compile Include="Interfaces\IAccountService.cs" />
<Compile Include="Interfaces\IApprovalsService.cs" />
<Compile Include="Interfaces\IHttpService.cs" />
<Compile Include="Interfaces\ILoggerService.cs" />
<Compile Include="Interfaces\IOrdersService.cs" />
<Compile Include="Interfaces\IProtocolService.cs" />
<Compile Include="Interfaces\IReportService.cs" />
<Compile Include="Interfaces\IShipmentsService.cs" />
<Compile Include="Interfaces\ISoftwareService.cs" />
<Compile Include="LoggerService.cs" />
<Compile Include="Models\Employee.cs" />
<Compile Include="Models\HttpResponseModel.cs" />
<Compile Include="Models\MissingItem.cs" />
@@ -0,0 +1,54 @@
namespace LaaProductionWeb.Services
{
using LaaProductionWeb.Data.Interfaces;
using LaaProductionWeb.Services.Interfaces;
using System;
public class LoggerService : ILoggerService
{
private readonly ISqlClient sqlClient;
public LoggerService(ISqlClient sqlClient)
=> this.sqlClient = sqlClient;
public class Actions
{
public const string RUN = nameof(RUN);
}
public class LogModel
{
public long Id { get; internal set; }
public DateTime Date { get; internal set; }
= DateTime.Now;
public string User { get; set; }
public string Action { get; set; }
public string Data { get; set; }
}
public void Log(Action<LogModel> logModel)
{
var model = new LogModel();
logModel?.Invoke(model);
this.sqlClient
.CreateCommand($@"
INSERT INTO [SoftwareFunctionsLog] (
[User]
, [Action]
, [Data])
VALUES (@{nameof(model.User)}
, @{nameof(model.Action)}
, @{nameof(model.Data)})")
.AddParameter(nameof(model.User), model.User)
.AddParameter(nameof(model.Action), model.Action)
.AddParameter(nameof(model.Data), model.Data)
.ExecuteNonQuery();
}
}
}
@@ -55,7 +55,7 @@
.ExecuteNonQuery();
}
public short FindAndUpdateSoftware(string name, IEnumerable<string> functions)
public short FindAndUpdateSoftware(string windowsUser, string name, IEnumerable<string> functions)
{
var appId = this.sqlClient
.CreateCommand($@"
@@ -67,13 +67,17 @@
.AddParameter(nameof(name), name)
.FirstOrDefault(x => x.GetSmallint());
if (appId > 0 && functions != null && functions.Any())
if (appId > 0)
{
foreach (var function in functions)
if (functions != null && functions.Any())
{
if (Regex.IsMatch(function, "[a-zA-Z_]+"))
foreach (var function in functions)
{
this.AddFunction(appId, function);
if (Regex.IsMatch(function, "[a-zA-Z_]+"))
{
this.AddFunction(appId, function);
}
}
}
}
@@ -41,6 +41,7 @@
services.AddScoped<IAccountService, AccountService>();
services.AddScoped<IApprovalsService, ApprovalsService>();
services.AddScoped<ILoggerService, LoggerService>();
services.AddScoped<IOrdersService, OrdersService>();
services.AddScoped<IProtocolService, ProtocolService>();
services.AddScoped<IReportService, ReportService>();
@@ -2,23 +2,41 @@
{
using LaaProductionWeb.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Web.Http;
public class AppIdController : ApiController
{
private readonly ISoftwareService softwareService;
private readonly ILoggerService loggerService;
public AppIdController()
=> this.softwareService = ServiceProvider.Current.GetService<ISoftwareService>();
{
this.softwareService = ServiceProvider.Current.GetService<ISoftwareService>();
this.loggerService = ServiceProvider.Current.GetService<ILoggerService>();
}
[HttpPost]
public int Post(AppIdPostInputModel model)
=> this.softwareService.FindAndUpdateSoftware(model.Software, model.Functions);
{
var appId = this.softwareService.FindAndUpdateSoftware(model.WindowsUser, model.Software, model.Functions);
this.loggerService.Log(x =>
{
x.User = model.WindowsUser;
x.Action = "STARTING APPLICATION";
x.Data = $"AppId: {appId}, Functions: {string.Join(", ", model.Functions ?? Array.Empty<string>())}";
});
return appId;
}
}
public class AppIdPostInputModel
{
public string WindowsUser { get; set; }
public string Software { get; set; }
public IEnumerable<string> Functions { get; set; }
@@ -2,17 +2,20 @@
{
using LaaProductionWeb.Services.Interfaces;
using System;
using System.Web.Http;
public class FunctionsController : ApiController
{
private readonly IAccountService accountService;
private readonly ISoftwareService softwareService;
private readonly ILoggerService loggerService;
public FunctionsController()
{
this.accountService = ServiceProvider.Current.GetService<IAccountService>();
this.softwareService = ServiceProvider.Current.GetService<ISoftwareService>();
this.loggerService = ServiceProvider.Current.GetService<ILoggerService>();
}
[HttpPost]
@@ -22,21 +25,61 @@
if (userId <= 0)
{
this.loggerService.Log(options =>
{
options.User = model.WindowsUser;
options.Action = "LOG IN FAILED";
options.Data = $"{model.WindowsUser}:{model.AppId} - for user {model.Username} with password {model.Password}";
});
return this.Unauthorized();
}
var functions = this.softwareService.GetSoftwareFunctions(model.AppId, userId);
this.loggerService.Log(options =>
{
options.User = model.WindowsUser;
options.Action = "LOG IN SUCCEEDED";
options.Data = $"{model.WindowsUser}:{model.AppId} - for user {model.Username} with password {model.Password}. User has following functions {string.Join(", ", functions ?? Array.Empty<string>())}";
});
return this.Json(functions);
}
[HttpPut]
public IHttpActionResult Put(FunctionsPutInputModel model)
{
this.loggerService.Log(options =>
{
options.User = model.WindowsUser;
options.Action = model.Action;
options.Data = $"AppId: {model.AppId} - reports: {model.Message}";
});
return this.Ok();
}
}
public class FunctionsPostInputModel
{
public short AppId { get; set; }
public string WindowsUser { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
public class FunctionsPutInputModel
{
public short AppId { get; set; }
public string WindowsUser { get; set; }
public string Message { get; set; }
public string Action { get; set; }
}
}