implement some new Oms functions and OmsServer capabilities, make sure all tests are green again

This commit is contained in:
Michael Becker 2024-11-01 23:14:08 -04:00
parent 15b8f620fc
commit f0c428e3f9
7 changed files with 377 additions and 73 deletions

View File

@ -18,6 +18,7 @@ public class Program : WebApplication
public Program()
{
ShortName = "mocha-oms-server";
oms = new MemoryOms();
}
private LibraryHandle l_System, l_Web;
@ -27,7 +28,6 @@ public class Program : WebApplication
protected override void OnStartup(EventArgs e)
{
// this all has to be done before the Web server is started...
oms = new MemoryOms();
TenantHandle th = oms.CreateTenant("super");
oms.SelectTenant(th);
@ -36,7 +36,7 @@ public class Program : WebApplication
oms.AddLibraryReference(lh);
LibraryHandle lh2 = oms.LoadLibrary("/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/output/net.alcetech.Mocha.Web.mcl");
oms.AddLibraryReference(lh);
oms.AddLibraryReference(lh2);
// now we can start the Web server
base.OnStartup(e);
@ -127,14 +127,14 @@ public class Program : WebApplication
{
ihs = oms.GetInstances();
}
if (!String.IsNullOrEmpty(query))
{
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (InstanceHandle ih in ihs)
{
string text = oms.GetInstanceText(ih);
if (text.ToLower().Contains(query))
if (text.ToLower().Contains(query.ToLower()))
{
list.Add(ih);
}
@ -153,6 +153,126 @@ public class Program : WebApplication
sw.Write(obj.ToJsonString());
}
else if (e.Context.Request.PathParts.Length > 2)
{
InstanceKey k = InstanceKey.Parse(e.Context.Request.PathParts[2]);
InstanceHandle h = InstanceHandle.Empty;
if (!oms.TryGetInstance(k, out h))
{
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
sw.Flush();
sw.Close();
return;
}
if (e.Context.Request.PathParts.Length > 3)
{
if (e.Context.Request.PathParts[3] == "attributes")
{
if (e.Context.Request.PathParts.Length > 5)
{
string iid = e.Context.Request.PathParts[4];
InstanceHandle att = oms.GetInstance(InstanceKey.Parse(iid));
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts[5].Equals("current"))
{
}
string value = oms.GetAttributeValue<string>(h, att, String.Empty, dt);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "text/plain";
sw.Write(value);
sw.Flush();
sw.Close();
return;
}
JsonObject obj = new JsonObject();
InstanceHandle hAtt = InstanceHandle.Empty;
if (e.Context.Request.PathParts.Length > 4)
{
hAtt = oms.GetInstance(InstanceKey.Parse(e.Context.Request.PathParts[4]));
}
JsonArray objAttributes = GetAttributesAsJson(h, hAtt);
obj.Add("attributes", objAttributes);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
else if (e.Context.Request.PathParts[3] == "relationships")
{
if (e.Context.Request.PathParts.Length > 5)
{
string iid = e.Context.Request.PathParts[4];
InstanceHandle rel = oms.GetInstance(InstanceKey.Parse(iid));
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts[5].Equals("current"))
{
}
IEnumerable<InstanceHandle> rel_insts = oms.GetRelatedInstances(h, rel, dt);
JsonObject obj = new JsonObject();
JsonArray a = new JsonArray();
foreach (InstanceHandle ih in rel_insts)
{
a.Add(oms.GetInstanceKey(ih));
}
obj.Add("relationships", a);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
sw.Flush();
sw.Close();
return;
}
else
{
JsonObject obj = new JsonObject();
obj.Add("relationships", GetRelationshipsAsJson(h));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}
}
else
{
JsonObject obj = new JsonObject();
obj.Add("instanceKey", JsonValue.Create(oms.GetInstanceKey(h).ToString()));
obj.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(h).ToString("b")));
obj.Add("attributes", GetAttributesAsJson(h));
obj.Add("relationshps", GetRelationshipsAsJson(h));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}
}
else
{
@ -190,6 +310,77 @@ public class Program : WebApplication
sw.Close();
}
private JsonArray GetRelationshipsAsJson(InstanceHandle h, InstanceHandle hRel = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaRelationship> rels = oms.GetRelationships(h);
foreach (MochaRelationship rel in rels)
{
if (hRel != InstanceHandle.Empty)
{
if (!rel.RelationshipInstance.Equals(hRel))
{
continue;
}
}
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(oms.GetInstanceKey(rel.RelationshipInstance).ToString()));
string attrText = oms.GetInstanceText(rel.RelationshipInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (RelationshipValue val in rel.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("targetInstances", InstancesToJson(val.TargetInstances));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
private JsonArray GetAttributesAsJson(InstanceHandle h, InstanceHandle hAtt = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaAttribute> atts = oms.GetAttributes(h);
foreach (MochaAttribute att in atts)
{
if (hAtt != InstanceHandle.Empty)
{
if (!att.AttributeInstance.Equals(hAtt))
{
continue;
}
}
string iid = oms.GetInstanceKey(att.AttributeInstance).ToString();
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(iid));
string attrText = oms.GetInstanceText(att.AttributeInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (AttributeValue val in att.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("value", JsonValue.Create(val.Value));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
private JsonArray InstancesToJson(IEnumerable<InstanceHandle> ihs)
{
JsonArray array = new JsonArray();
@ -215,4 +406,4 @@ public class Program : WebApplication
{
return (new Program()).Start();
}
}
}

View File

@ -0,0 +1,30 @@
// 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/>.
namespace Mocha.Core;
public class MochaAttribute
{
public InstanceHandle AttributeInstance { get; }
public List<AttributeValue> Values { get; } = new List<AttributeValue>();
public MochaAttribute(InstanceHandle attributeInstance, IEnumerable<AttributeValue> values)
{
AttributeInstance = attributeInstance;
Values.AddRange(values);
}
}

View File

@ -0,0 +1,30 @@
// 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/>.
namespace Mocha.Core;
public class MochaRelationship
{
public InstanceHandle RelationshipInstance { get; }
public IEnumerable<RelationshipValue> Values { get; }
public MochaRelationship(InstanceHandle relationshipInstance, IEnumerable<RelationshipValue> values)
{
RelationshipInstance = relationshipInstance;
Values = values;
}
}

View File

@ -140,8 +140,8 @@ public abstract class Oms
}
}
private void UpdateSyntacticSugar<T>(Type sourceType) where T : ConcreteInstanceWrapper
{
private void UpdateSyntacticSugar<T>(Type sourceType) where T : ConcreteInstanceWrapper
{
Type destinationType = typeof(T);
PropertyInfo[] pis = destinationType.GetProperties(BindingFlags.Static | BindingFlags.Public);
foreach (PropertyInfo pi in pis)
@ -158,9 +158,9 @@ public abstract class Oms
{
}
}
}
}
protected abstract bool SelectTenantInternal(TenantHandle tenant);
protected abstract bool SelectTenantInternal(TenantHandle tenant);
public void SelectTenant(TenantHandle tenant)
{
if (SelectTenantInternal(tenant))
@ -1367,8 +1367,8 @@ public abstract class Oms
return null;
}
public bool TryGetSingularInstance(object? oih, out InstanceHandle ih)
{
public bool TryGetSingularInstance(object? oih, out InstanceHandle ih)
{
ih = InstanceHandle.Empty;
if (oih == null)
{
@ -1385,11 +1385,22 @@ public abstract class Oms
return true;
}
return false;
}
}
protected abstract IEnumerable<InstanceHandle> GetInstancesInternal();
public IEnumerable<InstanceHandle> GetInstances()
{
return GetInstancesInternal();
}
protected abstract IEnumerable<MochaAttribute> GetAttributesInternal(InstanceHandle h);
public IEnumerable<MochaAttribute> GetAttributes(InstanceHandle h)
{
return GetAttributesInternal(h);
}
protected abstract IEnumerable<MochaRelationship> GetRelationshipsInternal(InstanceHandle h);
public IEnumerable<MochaRelationship> GetRelationships(InstanceHandle h)
{
return GetRelationshipsInternal(h);
}
}

View File

@ -15,10 +15,6 @@
// 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.ComponentModel;
using System.Data;
namespace Mocha.Core.OmsImplementations;
public class MemoryOms : Oms
@ -57,6 +53,7 @@ public class MemoryOms : Oms
}
return Guid.Empty;
}
public InstanceKey GetInstanceKey(InstanceHandle instance)
{
if (_keysByInstance.ContainsKey(instance))
@ -277,22 +274,22 @@ public class MemoryOms : Oms
private List<LibraryHandle> _libraryReferences = new List<LibraryHandle>();
public void AddLibraryReference(LibraryHandle library)
{
public void AddLibraryReference(LibraryHandle library)
{
if (!_libraryReferences.Contains(library))
{
// please don't reference the same library multiple times
_libraryReferences.Add(library);
}
}
}
public void RemoveLibraryReference(LibraryHandle library)
{
if (_libraryReferences.Contains(library))
_libraryReferences.Remove(library);
}
public IEnumerable<InstanceHandle> GetInstances()
{
public IEnumerable<InstanceHandle> GetInstances()
{
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (LibraryHandle lh in _libraryReferences)
{
@ -301,8 +298,48 @@ public class MemoryOms : Oms
}
list.AddRange(_instancesByGuid.Values);
return list;
}
}
}
public IEnumerable<MochaAttribute> GetAttributes(InstanceHandle inst)
{
if (!_Attributes.ContainsKey(inst))
{
_Attributes[inst] = new Dictionary<InstanceHandle, List<AttributeValue>>();
}
List<MochaAttribute> list = new List<MochaAttribute>();
foreach (LibraryHandle lh in _libraryReferences)
{
IEnumerable<MochaAttribute> list2 = oms._libraries[lh].GetAttributes(inst);
list.AddRange(list2);
}
foreach (KeyValuePair<InstanceHandle, List<AttributeValue>> kvp in _Attributes[inst])
{
list.Add(new MochaAttribute(kvp.Key, kvp.Value));
}
return list;
}
public IEnumerable<MochaRelationship> GetRelationships(InstanceHandle inst)
{
if (!_Relationships.ContainsKey(inst))
{
_Relationships[inst] = new Dictionary<InstanceHandle, List<RelationshipValue>>();
}
List<MochaRelationship> list = new List<MochaRelationship>();
foreach (LibraryHandle lh in _libraryReferences)
{
IEnumerable<MochaRelationship> list2 = oms._libraries[lh].GetRelationships(inst);
list.AddRange(list2);
}
foreach (KeyValuePair<InstanceHandle, List<RelationshipValue>> kvp in _Relationships[inst])
{
list.Add(new MochaRelationship(kvp.Key, kvp.Value));
}
return list;
}
}
private Dictionary<TenantHandle, _Tenant> _tenantData = new Dictionary<TenantHandle, _Tenant>();
@ -311,12 +348,12 @@ public class MemoryOms : Oms
private TenantHandle _CurrentTenant = TenantHandle.Empty;
protected override TenantHandle CreateTenantInternal(string tenantName)
{
protected override TenantHandle CreateTenantInternal(string tenantName)
{
TenantHandle th = TenantHandle.Create();
_tenantData[th] = new _Tenant(this);
return th;
}
}
protected override bool SelectTenantInternal(TenantHandle tenant)
{
_CurrentTenantData = _tenantData[tenant];
@ -335,29 +372,24 @@ public class MemoryOms : Oms
_CurrentTenantData.AddLibraryReference(library);
}
}
protected override void RemoveLibraryReferenceInternal(LibraryHandle library)
{
protected override void RemoveLibraryReferenceInternal(LibraryHandle library)
{
if (_CurrentTenantData != null)
{
_CurrentTenantData.RemoveLibraryReference(library);
}
}
}
public void __Test_AddLibraryReference_1(LibraryHandle lhWeb, LibraryHandle lhSystem)
{
_libraries[lhWeb].AddLibraryReference(lhSystem);
}
protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance)
{
protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
Guid gid = _CurrentTenantData.GetGlobalIdentifier(instance);
return gid;
}
protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance)
{
}
protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
@ -366,7 +398,7 @@ public class MemoryOms : Oms
{
// create a new instance key for this instance
InstanceHandle parent = GetParentClass(instance);
if (parent == null)
if (parent == InstanceHandle.Empty)
{
// hack?
parent = GetInstance(KnownInstanceGuids.Classes.Class);
@ -389,11 +421,11 @@ public class MemoryOms : Oms
_CurrentTenantData.SetInstanceKey(instance, ik);
}
return ik;
}
}
protected override void InitializeLibraryInternal(LibraryHandle lh, Library data)
{
_Tenant lib = new _Tenant(this);
protected override void InitializeLibraryInternal(LibraryHandle lh, Library data)
{
_Tenant lib = new _Tenant(this);
// hack
_Tenant old = _CurrentTenantData;
@ -416,13 +448,18 @@ public class MemoryOms : Oms
}
foreach (LibraryAttribute att in data.Attributes)
{
// ! FIXME: attributes get set, but only if they are not inherited from foreign Instances (e.g. Class and Relationship)
if (lib.TryGetInstance(att.SourceInstanceGuid, out InstanceHandle src)
&& lib.TryGetInstance(att.AttributeInstanceGuid, out InstanceHandle dst))
{
// Console.WriteLine("library init: set attribute value {0} . {1} = '{2}'", att.SourceInstanceGuid.ToString("B"), att.AttributeInstanceGuid.ToString("B"), att.Value);
lib.SetAttributeValue(src, dst, att.Value, DateTime.Now);
}
else
{
}
}
foreach (LibraryRelationship rel in data.Relationships)
{
@ -440,7 +477,7 @@ public class MemoryOms : Oms
// hack
_CurrentTenantData = old;
}
}
private struct LibraryInst_g
{
@ -449,7 +486,7 @@ public class MemoryOms : Oms
public Guid GlobalIdentifier;
}
protected override bool TryGetInstanceInternal(Guid globalIdentifier, out InstanceHandle ih)
protected override bool TryGetInstanceInternal(Guid globalIdentifier, out InstanceHandle ih)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
@ -465,13 +502,13 @@ public class MemoryOms : Oms
return _CurrentTenantData.TryGetInstance(ik, out ih);
}
protected override void SetInstanceKeyInternal(InstanceHandle source, InstanceKey instanceKey)
{
protected override void SetInstanceKeyInternal(InstanceHandle source, InstanceKey instanceKey)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
_CurrentTenantData.SetInstanceKey(source, instanceKey);
}
}
protected override InstanceHandle CreateInstanceInternal(Guid guid)
{
@ -482,56 +519,63 @@ public class MemoryOms : Oms
return ir;
}
protected override void ClearRelationshipInternal(InstanceHandle source, InstanceHandle relationship)
{
protected override void ClearRelationshipInternal(InstanceHandle source, InstanceHandle relationship)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
_CurrentTenantData.ClearRelationship(source, relationship);
}
}
protected override void AssignRelationshipInternal(InstanceHandle source, InstanceHandle relationship, IEnumerable<InstanceHandle> targets, DateTime effectiveDate)
{
protected override void AssignRelationshipInternal(InstanceHandle source, InstanceHandle relationship, IEnumerable<InstanceHandle> targets, DateTime effectiveDate)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
_CurrentTenantData.AssignRelationship(source, relationship, targets, effectiveDate);
}
protected override IReadOnlyCollection<InstanceHandle> GetRelatedInstancesInternal(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate)
{
}
protected override IReadOnlyCollection<InstanceHandle> GetRelatedInstancesInternal(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
IReadOnlyCollection<InstanceHandle> insts = _CurrentTenantData.GetRelatedInstances(source, relationship, effectiveDate);
return insts;
}
}
protected override bool HasAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
{
protected override bool HasAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
return _CurrentTenantData.HasAttributeValue(source, attribute, effectiveDate);
}
protected override object? GetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
{
}
protected override object? GetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
object value = _CurrentTenantData.GetAttributeValue(source, attribute, effectiveDate);
return value;
}
protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)
{
}
protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)
{
if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first.");
_CurrentTenantData.SetAttributeValue(source, attribute, value, effectiveDate);
}
}
protected override IEnumerable<InstanceHandle> GetInstancesInternal()
{
return _CurrentTenantData.GetInstances();
}
protected override IEnumerable<MochaAttribute> GetAttributesInternal(InstanceHandle inst)
{
return _CurrentTenantData.GetAttributes(inst);
}
protected override IEnumerable<MochaRelationship> GetRelationshipsInternal(InstanceHandle inst)
{
return _CurrentTenantData.GetRelationships(inst);
}
}

View File

@ -35,8 +35,6 @@ public class LibraryLoaderTests : OmsTestsBase
lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl");
Oms.AddLibraryReference(lhWeb);
((MemoryOms)Oms).__Test_AddLibraryReference_1(lhWeb, lhSystem);
}
[Test]

View File

@ -103,10 +103,10 @@ public class GetRelationshipTests : MethodTestsBase
InstanceHandle valueIH = Oms.Execute(context, rsmb);
object? value_o = context.GetWorkData(valueIH);
InstanceHandle[] values = (InstanceHandle[])value_o;
IEnumerable<InstanceHandle> values = (IEnumerable<InstanceHandle>)value_o;
for (int i = 0; i < TEST_VALUES.Length; i++)
{
Assert.That(values[i], Is.EqualTo(TEST_VALUES[i]));
Assert.That(values.ElementAt(i), Is.EqualTo(TEST_VALUES[i]));
}
}