From 0d9bde635131db0e7d9344e99151657d32aefadc Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Mon, 3 Mar 2025 19:09:24 -0500 Subject: [PATCH] updates --- mocha-common | 2 +- .../src/app/Mocha.Oms.Server/Program.cs | 130 +++++++++++++++--- .../Commands/ElementCommand.cs | 1 + .../Commands/ReloadCommand.cs | 45 ++++++ .../src/lib/Mocha.Core/KnownInstanceGuids.cs | 1 + mocha-dotnet/src/lib/Mocha.Core/Oms.cs | 2 +- mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs | 18 +++ .../src/lib/Mocha.Core/UI/Renderer.cs | 19 ++- .../src/lib/Mocha.Core/UI/Widgets/Element.cs | 2 + .../src/lib/Mocha.Core/UI/Widgets/Text.cs | 2 +- 10 files changed, 194 insertions(+), 28 deletions(-) create mode 100644 mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ReloadCommand.cs diff --git a/mocha-common b/mocha-common index 534face..94de4f0 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 534face1a0241487332b18b9fa93fa171b292a26 +Subproject commit 94de4f0a8e855543c0f1b0679aebf7caa2db56c9 diff --git a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs index 087a243..6ed1e90 100644 --- a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs +++ b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs @@ -1,27 +1,12 @@ namespace Mocha.Oms.Server; -using Mocha.Core; - using MBS.Web; using System; using Mocha.Core.OmsImplementations; -using System.Runtime.InteropServices; -using System.Diagnostics; -using System.Text.Json; -using System.Text.Json.Serialization; using System.Text.Json.Nodes; -using Mocha.Core.UI; -using Mocha.Core.Oop; using MBS.Core; -using MBS.Core.Collections.Generic; - -using System.Collections.ObjectModel; -using System.Runtime.CompilerServices; -using Mocha.Core.Responses; -using System.Runtime.Serialization; -using System.Reflection; - +using Mocha.Core; using Mocha.Core.UI.Server; /// @@ -48,14 +33,16 @@ public class Program : WebApplication private LibraryHandle l_System, l_Web; public Oms Oms { get; } + + private System.IO.StreamWriter? logSt = null; protected override WebServer CreateWebServer() - { - WebServer server = base.CreateWebServer(); + { + WebServer server = base.CreateWebServer(); // server.SSLCertificateFile = "/etc/ssl/certs/localhost.crt"; // server.SSLCertificateKeyFile = "/etc/ssl/certs/localhost.key"; return server; - } + } protected override void OnStartup(EventArgs e) { @@ -69,6 +56,22 @@ public class Program : WebApplication Console.Error.WriteLine("oms: error: failed to write PID file; graceful control will be unavailable"); } + string logFile = "/var/log/mocha/oms-dotnet.log"; + try + { + OpenLogFile(logFile); + } + catch (UnauthorizedAccessException ex) + { + logFile = System.IO.Path.Combine(new string[] { System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "oms-dotnet.log" }); + OpenLogFile(logFile); + } + + logSt?.WriteLine("**********"); + logSt?.WriteLine("Mocha .NET OMS, version {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); + logSt?.WriteLine(String.Format("{0} {1}", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString())); + logSt?.WriteLine("**********"); + // this all has to be done before the Web server is started... Oms.Initialize(); @@ -114,20 +117,103 @@ public class Program : WebApplication // !HACK return ctx2.GetExtraData("Client.IPAddress"); }); + // implement functions to update Mochafile + Oms.RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.UpdateMochafile, delegate (Oms oms2, OmsContext ctx2) + { + // !HACK + bool b = UpdateMochafile(); + return b; + }); Oms.SystemRoutineExecuted += oms_SystemRoutineExecuted; + UpdateMochafile(); + // now we can start the Web server - base.OnStartup(e); + base.OnStartup(e); } - private bool TryLoadLibrary(Oms oms, string path, string fileName) + private void OpenLogFile(string logFile) + { + string logDir = System.IO.Path.GetDirectoryName(logFile); + if (!System.IO.Directory.Exists(logDir)) + { + System.IO.Directory.CreateDirectory(logDir); + } + logSt = new StreamWriter(System.IO.File.Open(logFile, FileMode.Append, FileAccess.Write, FileShare.Read), System.Text.Encoding.UTF8); + logSt.AutoFlush = true; + } + + private bool UpdateMochafile() + { + bool enableMochaFile = true; + if (enableMochaFile) + { + // check to see if we have a Mochafile that we need to load + // (this should only be done on development build) + string Mochafilename = "/var/mocha/uploads/Mochafile.json"; + logSt.WriteLine(String.Format("oms-dotnet: looking for Mochafile '{0}'", Mochafilename)); + + if (System.IO.File.Exists(Mochafilename)) + { + logSt.WriteLine("oms-dotnet: Mochafile found"); + if (LoadMochafile(Mochafilename)) + { + return true; + } + } + else + { + logSt.WriteLine("oms-dotnet: Mochafile not found"); + } + } + else + { + logSt.WriteLine("oms-dotnet: skipping Mochafile processing (not enabled)"); + } + return false; + } + + private bool LoadMochafile(string mochafilename) + { + logSt?.Write(String.Format("oms-dotnet: loading Mochafile at '{0}'", mochafilename)); + + JsonObject? json = JsonNode.Parse(System.IO.File.ReadAllText(mochafilename)) as JsonObject; + if (json == null) + { + logSt?.Write("oms-dotnet: Mochafile error: could not parse JSON"); + return false; + } + + if (json.ContainsKey("tenants")) + { + if (json["tenants"] is JsonArray aryTenants) + { + foreach (JsonObject jo in aryTenants) + { + if (jo.ContainsKey("name")) + { + string name = jo["name"].GetValue(); + logSt?.Write(String.Format("oms-dotnet: Mochafile says create tenant '{0}'", name)); + + TenantHandle th = Oms.CreateTenant(name); + logSt?.Write(String.Format("oms-dotnet: create tenant ok, handle is '{0}'", th)); + } + } + } + } + + logSt?.Write("oms-dotnet: Mochafile processing complete"); + return true; + } + + private bool TryLoadLibrary(Oms oms, string path, string fileName) { string fullyQualifiedFileName = System.IO.Path.Combine(new string[] { path, fileName }); if (!System.IO.File.Exists(fullyQualifiedFileName)) { Console.WriteLine("file not found: {0}", fullyQualifiedFileName); return false; - } + } LibraryHandle lh = oms.LoadLibrary(fullyQualifiedFileName); if (lh == LibraryHandle.Empty) diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs index 63c51b1..01d29e6 100644 --- a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs @@ -130,6 +130,7 @@ public class ElementCommand : InstanceCommand InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task)); if (defaultTask != InstanceHandle.Empty) { + ctx.InitiatingInstance = ProcessingInstance; RespndWithTask(oms, sw, e.Context, ctx, defaultTask); } } diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ReloadCommand.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ReloadCommand.cs new file mode 100644 index 0000000..abc39b2 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ReloadCommand.cs @@ -0,0 +1,45 @@ +// Copyright (C) 2024 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +using System.Text.Json.Nodes; +using MBS.Web; +using Mocha.Core; + +namespace Mocha.Core.UI.Server.Commands; + +public class ReloadCommand : OmsServerCommand +{ + public override IEnumerable UriPatterns => new string[] { "/reload" }; + protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, OmsContext ctx, StreamWriter sw) + { + if (e.Context.Request.PathParts.Length == 2 && e.Context.Request.PathParts[1] == "reload") + { + // this should probably be a SIM - Spawn Internal Message method + InstanceHandle hrt = oms.GetInstance(KnownInstanceGuids.SystemAttributeRoutines.UpdateMochafile); + object? value = oms.ExecuteSystemRoutine(ctx, hrt); + + e.Context.Response.ResponseCode = 200; + e.Context.Response.ResponseText = "OK"; + e.Context.Response.ContentType = "application/json"; + + JsonObject obj = new JsonObject(); + obj.Add("result", JsonValue.Create("success")); + sw.Write(obj.ToJsonString()); + } + + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs index 7b8a53b..13a34db 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs @@ -292,6 +292,7 @@ namespace Mocha.Core public static Guid GetInstanceText { get; } = new Guid("{b024abd6-1f2b-495a-9da3-c9ce29fb0c2f}"); public static Guid GetRandomNumber { get; } = new Guid("{8f7945da-4cad-49cb-9838-85f3524a5adb}"); public static Guid GetIPAddress { get; } = new Guid("{45411e57-ef6e-44f5-8801-603e567d73d4}"); + public static Guid UpdateMochafile { get; } = new Guid("{9c3ae605-b8a0-4e68-9225-96674a9fb34e}"); public static Guid GetGlobalIdentifier { get; } = new Guid("{1a7ebec3-dc02-4c9b-a5df-0c72646453c9}"); } public static class SystemInstanceSetRoutines diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 9473b3d..c20f860 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -1490,7 +1490,7 @@ public abstract class Oms _systemRoutinesByInstance[globalIdentifier] = new SystemUpdateRoutine(this, globalIdentifier, func); } - internal object? ExecuteSystemRoutine(OmsContext context, InstanceHandle handle) + public object? ExecuteSystemRoutine(OmsContext context, InstanceHandle handle) { Guid globalIdentifier = this.GetGlobalIdentifier(handle); SystemRoutine sr = _systemRoutinesByInstance[globalIdentifier]; diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs index 42df2ff..8e2f55b 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs @@ -41,8 +41,18 @@ public class OmsContext } return null; } + set + { + if (TargetInstances.Count > 0) + { + TargetInstances.Pop(); + } + TargetInstances.Push(value); + } } + public IInstanceReference InitiatingInstance { get; set; } + internal OmsContext(Oms oms) { Oms = oms; @@ -225,4 +235,12 @@ public class OmsContext { _GlobalData[parm] = value; } + + public void Clear() + { + _GlobalData.Clear(); + _WorkData.Clear(); + WorkDataSets.Clear(); + TargetInstances.Clear(); + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs index 7a0c040..72a1568 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs @@ -34,6 +34,12 @@ public class Renderer } public Widget Parse(OmsContext context, InstanceHandle instance, InstanceHandle parentElementContent, InstanceHandle parentElement, InstanceHandle processingInstance) { + if (processingInstance == InstanceHandle.Empty && context.InitiatingInstance != null) + { + processingInstance = context.InitiatingInstance.GetHandle(); + } + + Widget[] availableWidgets = MBS.Core.Reflection.TypeLoader.GetAvailableTypes(new System.Reflection.Assembly[] { typeof(Widget).Assembly }, true); Console.Error.WriteLine("got {0} available widgets", availableWidgets.Length); @@ -120,11 +126,18 @@ public class Renderer { value = context.GetWorkData(ecinst); } - else + else if (ecinst != InstanceHandle.Empty) { // executable returning instance set? - InstanceHandle workSet = OMS.Execute(context, ecinst); - value = context.GetWorkData(workSet); + try + { + InstanceHandle workSet = OMS.Execute(context, ecinst); + value = context.GetWorkData(workSet); + } + catch (Exception ex) + { + value = ex.ToString(); + } } } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs index 4d7eeeb..2c92216 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs @@ -88,6 +88,8 @@ public class Element : Widget protected override void RenderJSONInternal(OmsContext context, JsonObject obj) { + context.Clear(); + IEnumerable displayOptions = OMS.GetRelatedInstances(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option)); InstanceHandle doSingular = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.Singular); diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Text.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Text.cs index a83914b..488e4e2 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Text.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Text.cs @@ -50,7 +50,7 @@ public class Text : Widget } else { - // context.SetWorkData(OMS.GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), TargetInstance); + context.SetWorkData(OMS.GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), context.InitiatingInstance); InstanceHandle workData = OMS.Execute(context, ParentInstance); object? val = context.GetWorkData(workData);