This commit is contained in:
Michael Becker 2025-03-03 19:09:24 -05:00
parent f8d8e7d752
commit 0d9bde6351
10 changed files with 194 additions and 28 deletions

@ -1 +1 @@
Subproject commit 534face1a0241487332b18b9fa93fa171b292a26 Subproject commit 94de4f0a8e855543c0f1b0679aebf7caa2db56c9

View File

@ -1,27 +1,12 @@
namespace Mocha.Oms.Server; namespace Mocha.Oms.Server;
using Mocha.Core;
using MBS.Web; using MBS.Web;
using System; using System;
using Mocha.Core.OmsImplementations; 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 System.Text.Json.Nodes;
using Mocha.Core.UI;
using Mocha.Core.Oop;
using MBS.Core; using MBS.Core;
using MBS.Core.Collections.Generic; using Mocha.Core;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using Mocha.Core.Responses;
using System.Runtime.Serialization;
using System.Reflection;
using Mocha.Core.UI.Server; using Mocha.Core.UI.Server;
/// <summary> /// <summary>
@ -49,13 +34,15 @@ public class Program : WebApplication
public Oms Oms { get; } public Oms Oms { get; }
private System.IO.StreamWriter? logSt = null;
protected override WebServer CreateWebServer() protected override WebServer CreateWebServer()
{ {
WebServer server = base.CreateWebServer(); WebServer server = base.CreateWebServer();
// server.SSLCertificateFile = "/etc/ssl/certs/localhost.crt"; // server.SSLCertificateFile = "/etc/ssl/certs/localhost.crt";
// server.SSLCertificateKeyFile = "/etc/ssl/certs/localhost.key"; // server.SSLCertificateKeyFile = "/etc/ssl/certs/localhost.key";
return server; return server;
} }
protected override void OnStartup(EventArgs e) 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"); 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... // this all has to be done before the Web server is started...
Oms.Initialize(); Oms.Initialize();
@ -114,13 +117,96 @@ public class Program : WebApplication
// !HACK // !HACK
return ctx2.GetExtraData<string>("Client.IPAddress"); return ctx2.GetExtraData<string>("Client.IPAddress");
}); });
// implement functions to update Mochafile
Oms.RegisterSystemAttributeRoutine<bool>(KnownInstanceGuids.SystemAttributeRoutines.UpdateMochafile, delegate (Oms oms2, OmsContext ctx2)
{
// !HACK
bool b = UpdateMochafile();
return b;
});
Oms.SystemRoutineExecuted += oms_SystemRoutineExecuted; Oms.SystemRoutineExecuted += oms_SystemRoutineExecuted;
UpdateMochafile();
// now we can start the Web server // 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<string>();
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 }); string fullyQualifiedFileName = System.IO.Path.Combine(new string[] { path, fileName });
if (!System.IO.File.Exists(fullyQualifiedFileName)) if (!System.IO.File.Exists(fullyQualifiedFileName))

View File

@ -130,6 +130,7 @@ public class ElementCommand : InstanceCommand
InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task)); InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task));
if (defaultTask != InstanceHandle.Empty) if (defaultTask != InstanceHandle.Empty)
{ {
ctx.InitiatingInstance = ProcessingInstance;
RespndWithTask(oms, sw, e.Context, ctx, defaultTask); RespndWithTask(oms, sw, e.Context, ctx, defaultTask);
} }
} }

View File

@ -0,0 +1,45 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// 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 <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server.Commands;
public class ReloadCommand : OmsServerCommand
{
public override IEnumerable<string> 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());
}
}
}

View File

@ -292,6 +292,7 @@ namespace Mocha.Core
public static Guid GetInstanceText { get; } = new Guid("{b024abd6-1f2b-495a-9da3-c9ce29fb0c2f}"); 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 GetRandomNumber { get; } = new Guid("{8f7945da-4cad-49cb-9838-85f3524a5adb}");
public static Guid GetIPAddress { get; } = new Guid("{45411e57-ef6e-44f5-8801-603e567d73d4}"); 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 Guid GetGlobalIdentifier { get; } = new Guid("{1a7ebec3-dc02-4c9b-a5df-0c72646453c9}");
} }
public static class SystemInstanceSetRoutines public static class SystemInstanceSetRoutines

View File

@ -1490,7 +1490,7 @@ public abstract class Oms
_systemRoutinesByInstance[globalIdentifier] = new SystemUpdateRoutine(this, globalIdentifier, func); _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); Guid globalIdentifier = this.GetGlobalIdentifier(handle);
SystemRoutine sr = _systemRoutinesByInstance[globalIdentifier]; SystemRoutine sr = _systemRoutinesByInstance[globalIdentifier];

View File

@ -41,8 +41,18 @@ public class OmsContext
} }
return null; return null;
} }
set
{
if (TargetInstances.Count > 0)
{
TargetInstances.Pop();
}
TargetInstances.Push(value);
}
} }
public IInstanceReference InitiatingInstance { get; set; }
internal OmsContext(Oms oms) internal OmsContext(Oms oms)
{ {
Oms = oms; Oms = oms;
@ -225,4 +235,12 @@ public class OmsContext
{ {
_GlobalData[parm] = value; _GlobalData[parm] = value;
} }
public void Clear()
{
_GlobalData.Clear();
_WorkData.Clear();
WorkDataSets.Clear();
TargetInstances.Clear();
}
} }

View File

@ -34,6 +34,12 @@ public class Renderer
} }
public Widget Parse(OmsContext context, InstanceHandle instance, InstanceHandle parentElementContent, InstanceHandle parentElement, InstanceHandle processingInstance) 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<Widget>(new System.Reflection.Assembly[] { typeof(Widget).Assembly }, true); Widget[] availableWidgets = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<Widget>(new System.Reflection.Assembly[] { typeof(Widget).Assembly }, true);
Console.Error.WriteLine("got {0} available widgets", availableWidgets.Length); Console.Error.WriteLine("got {0} available widgets", availableWidgets.Length);
@ -120,11 +126,18 @@ public class Renderer
{ {
value = context.GetWorkData(ecinst); value = context.GetWorkData(ecinst);
} }
else else if (ecinst != InstanceHandle.Empty)
{ {
// executable returning instance set? // executable returning instance set?
InstanceHandle workSet = OMS.Execute(context, ecinst); try
value = context.GetWorkData(workSet); {
InstanceHandle workSet = OMS.Execute(context, ecinst);
value = context.GetWorkData(workSet);
}
catch (Exception ex)
{
value = ex.ToString();
}
} }
} }
} }

View File

@ -88,6 +88,8 @@ public class Element : Widget
protected override void RenderJSONInternal(OmsContext context, JsonObject obj) protected override void RenderJSONInternal(OmsContext context, JsonObject obj)
{ {
context.Clear();
IEnumerable<InstanceHandle> displayOptions = OMS.GetRelatedInstances(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option)); IEnumerable<InstanceHandle> displayOptions = OMS.GetRelatedInstances(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option));
InstanceHandle doSingular = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.Singular); InstanceHandle doSingular = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.Singular);

View File

@ -50,7 +50,7 @@ public class Text : Widget
} }
else else
{ {
// context.SetWorkData(OMS.GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), TargetInstance); context.SetWorkData(OMS.GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), context.InitiatingInstance);
InstanceHandle workData = OMS.Execute(context, ParentInstance); InstanceHandle workData = OMS.Execute(context, ParentInstance);
object? val = context.GetWorkData(workData); object? val = context.GetWorkData(workData);