v1.3.0 Restructure Saxonite workspace and upgrade to .NET 10 (#1)
Move Saxonite’s projects into a dedicated `Workspace` folder and align the solution with .NET 10 and the current Common workspace. Update encryption integration, test project structure and coverage, and repository guidance and upgrade notes. - Relocate application and library projects while retaining Git rename history. - Split tests into Admin, Online, and Shared projects; add representative behavioral and serialization tests. - Update Common integration, application version, and repository documentation. Application version: 1.3.0 Reviewed-on: #1 Co-authored-by: andy <andy@sarand.com>
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Core.Web.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
{
|
||||
//=======================================================================
|
||||
public class SaxActivityConsole_Admin : SaxActivityConsole_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public SaxActivityConsole_Admin(SaxSessionContext sessionContext) :
|
||||
base(sessionContext)
|
||||
{
|
||||
SaLogger.Info(SysUtil.Fn + "");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utilities.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Core.Web.Admin.App;
|
||||
using Saxonite.Net.Core.Web.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
{
|
||||
//=======================================================================
|
||||
public class SaxConsoleHelper_Admin : SaxConsoleHelper_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members:
|
||||
private readonly SaxApplication_Admin app;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SaxConsoleHelper_Admin(SaxApplication_Admin app)
|
||||
{
|
||||
this.app = app;
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Clear process consoles.
|
||||
foreach (SaxProcessConsole_Admin processConsole in processConsoles.Values)
|
||||
{
|
||||
processConsole.Dispose();
|
||||
}
|
||||
processConsoles.Clear();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data cache console.
|
||||
public override SaxDataCacheConsole GetDataCacheConsole(SaxSessionContext sessionContext)
|
||||
{
|
||||
//throw new NotSupportedException(fn + " Data Cache Console not supported in Admin app.");
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Session data console.
|
||||
public override SaxSessionDataConsole GetSessionDataConsole(SaxSessionContext sessionContext)
|
||||
{
|
||||
// Method is called by Base Controller on ValidUserSession and must return null for Admin app.
|
||||
return null;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process console.
|
||||
private Dictionary<ushort, SaxProcessConsole_Admin> processConsoles { get; } = new Dictionary<ushort, SaxProcessConsole_Admin>();
|
||||
public SaxProcessConsole GetProcessConsole(SaxSessionContext sessionContext)
|
||||
{
|
||||
if (sessionContext == null) throw new NotSupportedException($"{SysUtil.Fn} Session Context must be specified.");
|
||||
SaxProcessConsole_Admin processConsole = processConsoles.GetValueOrDefault(sessionContext.Index, null);
|
||||
if (processConsole == null)
|
||||
{
|
||||
processConsole = processConsoles[sessionContext.Index] = new SaxProcessConsole_Admin(sessionContext);
|
||||
}
|
||||
return processConsole;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Activity console.
|
||||
public override SaxActivityConsole CreateActivityConsole(SaxSessionContext sessionContext)
|
||||
{
|
||||
return new SaxActivityConsole_Admin(sessionContext);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Email console.
|
||||
public override SaxEmailConsole CreateEmailConsole(SaxSessionContext sessionContext)
|
||||
{
|
||||
SaxEmailConsole emailConsole = new SaxEmailConsole_Web(app.EmailConfig);
|
||||
return emailConsole;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Tasks;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using Saxonite.Net.Core.Web.Admin.App;
|
||||
using Saxonite.Net.Core.Web.Base.Consoles;
|
||||
using Saxonite.Net.Core.Web.Base.Procs;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
{
|
||||
//=======================================================================
|
||||
public class SaxHostedServiceConsole_Admin : SaxHostedServiceConsole_Web
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
private enum ProcessType { Unknown = 0, GolfUsgaReferenceLookup }
|
||||
|
||||
/// <summary>
|
||||
/// Process tracking data to control when process is run.
|
||||
/// </summary>
|
||||
private class ProcessControlData
|
||||
{
|
||||
// Construction.
|
||||
public ProcessControlData(ProcessType processType, TimeSpan minTimeBetweenRuns)
|
||||
{
|
||||
this.ProcessType = processType;
|
||||
this.MinTimeBetweenRuns = minTimeBetweenRuns;
|
||||
ResetRunTime();
|
||||
}
|
||||
// Properties.
|
||||
public ProcessType ProcessType { get; }
|
||||
public TimeSpan MinTimeBetweenRuns { get; }
|
||||
public DateTime LastRunAt { get; private set; }
|
||||
// Utilities.
|
||||
public bool ReadyToRun()
|
||||
{
|
||||
//SaLogger.Info($"{SysUtil.Fn} Process: {ProcessType}. Secs since last run: {(DateTime.Now - LastRunAt).TotalSeconds}. Seconds between runs: {MinTimeBetweenRuns.TotalSeconds}.");
|
||||
return (DateTime.Now - LastRunAt) > MinTimeBetweenRuns;
|
||||
}
|
||||
public void ResetRunTime()
|
||||
{
|
||||
LastRunAt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Dictionary<ProcessType, ProcessControlData> processes { get; } = new Dictionary<ProcessType, ProcessControlData>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SaxHostedServiceConsole_Admin()
|
||||
{
|
||||
InitialiseProcesses();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Clean-up.
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Periodic processing to execute application processes as required.
|
||||
/// <para>- See parent class for timer logic.</para>
|
||||
/// </summary>
|
||||
protected override void DoWork(object state)
|
||||
{
|
||||
//SaLogger.Info($"{SysUtil.Fn} Timed Background Service is working. State: {state}");
|
||||
SaxSessionContext sessionContext = SaxApplication_Admin.AppInstance.SessionContext;
|
||||
DbUpdateInfo dbUpdateInfo = new DbUpdateInfo(new SysId(), "AdminScheduled", SacsSystem.ComputerName);
|
||||
|
||||
// Check for cancellation.
|
||||
var token = ProcessTaskData.CancellationToken;
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
// Identify processes that are ready to run.
|
||||
foreach (ProcessControlData process in processes.Where(item => item.Value.ReadyToRun()).Select(item => item.Value))
|
||||
{
|
||||
//SaLogger.Info($"{SysUtil.Fn} Executing process: {process.ProcessType}.");
|
||||
process.ResetRunTime();
|
||||
switch (process.ProcessType)
|
||||
{
|
||||
case ProcessType.GolfUsgaReferenceLookup:
|
||||
// Run on separate thread.
|
||||
Task task = new Task(() =>
|
||||
{
|
||||
SaxGolfUsgaDataLookup.ExecuteScheduledUsgaDataLookup(sessionContext, dbUpdateInfo, ProcessTaskData);
|
||||
}, ProcessTaskData.CancellationToken);
|
||||
task.Start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Initialisation.
|
||||
|
||||
private void InitialiseProcesses()
|
||||
{
|
||||
if (Sax.Config.Admin.Processes.Scheduled.UsgaGolfDataLookup.Enabled)
|
||||
InitialiseProcess(ProcessType.GolfUsgaReferenceLookup, TimeSpan.FromMinutes(MathUtil.Constrain(Sax.Config.Admin.Processes.Scheduled.UsgaGolfDataLookup.MinsBetweenExecution, 2, 120)));
|
||||
}
|
||||
|
||||
private void InitialiseProcess(ProcessType processType, TimeSpan minTimeBetweenRuns)
|
||||
{
|
||||
if (!processes.ContainsKey(processType))
|
||||
processes[processType] = new ProcessControlData(processType, minTimeBetweenRuns);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using MimeKit;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Procs;
|
||||
using Saxonite.Net.Core.Web.Admin.Procs;
|
||||
using Saxonite.Net.Core.Web.Base.Procs;
|
||||
using Saxonite.Net.Standard.Base.App;
|
||||
using Saxonite.Net.Standard.Base.Consoles;
|
||||
using Saxonite.Net.Standard.Base.Procs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Saxonite.Net.Core.Web.Admin.Consoles
|
||||
{
|
||||
//=======================================================================
|
||||
public class SaxProcessConsole_Admin : SaxProcessConsole
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public enum ProcessType
|
||||
{
|
||||
OrganisationUpload,
|
||||
GolfUsgaDataLookup
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Process cache - to sustain processes outside of request/response timescales.
|
||||
internal class ProcessData
|
||||
{
|
||||
public ProcessData(SaxProcess_Web process)
|
||||
{
|
||||
this.Process = process;
|
||||
|
||||
}
|
||||
public SaxProcess_Web Process { get; }
|
||||
}
|
||||
// Cache.
|
||||
private Dictionary<ProcessType, ProcessData> processes { get; } = new Dictionary<ProcessType, ProcessData>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
//private SaxInternals internals = null;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SaxProcessConsole_Admin(SaxSessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
}
|
||||
protected async override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Clear processes.
|
||||
foreach (ProcessData processData in processes.Values)
|
||||
{
|
||||
await processData.Process.StopProcessAsync();
|
||||
processData.Process.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Processes.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
public SaxProcess_Web GetProcess(ProcessType processType)
|
||||
{
|
||||
return processes.GetValueOrDefault(processType, null)?.Process;
|
||||
}
|
||||
|
||||
public bool IsProcessing(ProcessType processType)
|
||||
{
|
||||
SaxProcess_Web process = GetProcess(processType);
|
||||
if (process != null)
|
||||
if (process.Processing) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the process from the cache.
|
||||
/// </summary>
|
||||
/// <param name="processType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InProgressException"></exception>
|
||||
public bool ClearProcess(ProcessType processType)
|
||||
{
|
||||
SaxProcess_Web process = GetProcess(processType);
|
||||
if (process != null)
|
||||
{
|
||||
if (process.Processing)
|
||||
throw new SaProcess_Base.InProgressException();
|
||||
process.Dispose();
|
||||
}
|
||||
return processes.Remove(processType);
|
||||
}
|
||||
|
||||
public void SetProcess(ProcessType processType, SaxProcess_Web process)
|
||||
{
|
||||
ClearProcess(processType);
|
||||
processes.Add(processType, new ProcessData(process));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Specific processes.
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Organisation Upload.
|
||||
public SaxOrganisationUploader GetOrganisationUploader()
|
||||
{
|
||||
return GetProcess(ProcessType.OrganisationUpload) as SaxOrganisationUploader;
|
||||
}
|
||||
public void SetProcess(SaxOrganisationUploader process)
|
||||
{
|
||||
SetProcess(ProcessType.OrganisationUpload, process);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Organisation Upload.
|
||||
public SaxGolfUsgaDataLookup GetGolfUsgaDataLookup()
|
||||
{
|
||||
return GetProcess(ProcessType.GolfUsgaDataLookup) as SaxGolfUsgaDataLookup;
|
||||
}
|
||||
public void SetProcess(SaxGolfUsgaDataLookup process)
|
||||
{
|
||||
SetProcess(ProcessType.OrganisationUpload, process);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
Reference in New Issue
Block a user