using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; 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.Email; using Sarand.Net.Standard.Base.IO; using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Dbas.Base; using Saxonite.Net.Core.Web.Admin.Consoles; using Saxonite.Net.Core.Web.Base.App; using Saxonite.Net.Core.Web.Base.Helpers; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using Saxonite.Net.Standard.Base.Consoles; using Saxonite.Net.Standard.Base.Helpers; using Saxonite.Net.Standard.Base.Mgr; using Saxonite.Net.Standard.Dbas.App; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Admin.App { //======================================================================= public class SaxApplication_Admin : SaxApplication_Web { //------------------------------------------------------------------- // Data members. private bool generateDatabaseDefinitions = false; private bool populateRegions = false; private Dictionary appConfigs = new Dictionary(); private Dictionary emailConfigs = new Dictionary(); // Session contexts. private class SessionContextData_Admin : SessionContextData_Web { public SessionContextData_Admin(SaxSessionContext_Web sessionContext) : base(sessionContext) { } } private readonly Dictionary sessionContexts = new Dictionary(); //------------------------------------------------------------------- // Construction. public SaxApplication_Admin(IConfiguration configuration) { InitialiseTemporaryLoggingFolder(); try { AppInstance = this; SaxGlobals.App = this; SaxGlobals.System = (System_Web = new SaxSystem_Web()); Configuration = configuration; ConsoleHelper_Web = new SaxConsoleHelper_WebAdmin(this); } catch (Exception exc) { SaLogger.Error(GetType().Name + ".CTR " + ExceptionUtil.GetErrorStateMessage(exc)); throw exc; } } //------------------------------------------------------------------- // Properties. public static SaxApplication_Admin AppInstance { get; private set; } public List Messages { get; } = new List(); public override ISacsDatabase GetDatabase(SaxSessionContext sessionContext, Sax.Database databaseType) { return sessionContexts.GetValue(sessionContext.Index, null)?.Databases.GetValue(databaseType, null); } public override String SessionCookieName { get { return Sax.Config.Admin.Session.Cookie.Name; } } // Configuration. public override SaxAppConfig AppConfig { get { return appConfigs.Values.ToList().getConfigForApplication(); } } public override SaxEmailConfig EmailConfig { get { return emailConfigs.Values.ToList().getConfigForSession(AppConfig); } } //------------------------------------------------------------------- // Initialisation. /// Initialise environment - from Startup. internal void InitWebHostEnvironment(IWebHostEnvironment env) { InitEnvironment(env); } /// Initialise environment - from internal (above) or unit tests. protected void InitEnvironment(IWebHostEnvironment env) { String fn = GetType().Name + ".InitEnvironment"; Development = env.IsDevelopment(); environmentName = env.EnvironmentName; SaLogger.LogFilenamePrefix = "Sax-Web-Adm"; SaLogger.IncludeHostInFileMessage = false; SaLogger.IncludeUserInFileMessage = false; try { // Load server configuration. var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false) .AddJsonFile($"appsettings.machine.{SaxSystem.ComputerName}.json", optional: false, reloadOnChange: false) .AddEnvironmentVariables(); SaxConfiguration = builder.Build(); //Messages.Add($"Host: {SaxSystem.ComputerName}"); //Messages.Add($"Config file: appsettings.machine.{SaxSystem.ComputerName}.json"); // Application configuration. appConfigs = SaxAppConfigHelper.ExtractAppConfigs(SaxConfiguration.GetSection("AppConfigs")); emailConfigs = SaxEmailConfigHelper.ExtractEmailConfigs(SaxConfiguration.GetSection("EmailConfigs")); LoggingRootFolder = AppConfig.Logging.RootFolder; // Application instance. if (AppConfig.Instance.EqualsCI("Dev")) instanceType = Sax.InstanceType.Dev; else if (AppConfig.Instance.ContainsCI("Q")) instanceType = Sax.InstanceType.QC; else if (AppConfig.Instance.ContainsCI("UAT")) instanceType = Sax.InstanceType.UAT; else if (AppConfig.Instance.EqualsCI("PreProd")) instanceType = Sax.InstanceType.UAT; // Initialise hard-coded logging path. if (StringUtil.IsEmpty(LoggingRootFolder)) { if (SaxSystem.ComputerName.EqualsCI("WIN-BPCLM1QUOMT")) LoggingRootFolder = @"D:\Saxonite\Logs\" + (Development ? "Dev" : "Test"); } if (DirectoryUtil.DirectoryExists(LoggingRootFolder)) SaLogger.LogFolder = LoggingRootFolder; LogApplicationStart(fn); //Messages.Add($"Database location: {AppConfig.CoreDatabase.Location}"); //Messages.Add($"LoggingRootFolder: {SaLogger.LogFolder}"); //Messages.Add($"OdbcDrivers: {OdbcUtil.GetOdbcDriverNames().Concat(", ")}"); //Messages.Add($"DbConnection: {coreDatabase.ConnectionString}"); // Session context - only one context available/necessary (for now). SessionContextData_Admin sessionContextData = new SessionContextData_Admin(new SaxSessionContext_Web(100, Sax.Application.Admin)); ConfigureDatabaseConnection(sessionContextData, Sax.Database.Core); ConfigureDatabaseConnection(sessionContextData, Sax.Database.Support); sessionContexts.Add(sessionContextData.SessionContext.Index, sessionContextData); SessionContext = sessionContextData.SessionContext; } catch (Exception exc) { SaLogger.Error(fn + " " + ExceptionUtil.GetLogMessage(exc)); } // Occasional startup processing. if (generateDatabaseDefinitions) GenerateDatabaseDefinitions(SessionContext); if (populateRegions) populateRegionsFromDataFile(SessionContext); } private void ConfigureDatabaseConnection(SessionContextData_Admin sessionContextData, Sax.Database databaseInstance) { String fn = GetType().Name + ".ConfigureDatabaseConnection"; // Configure database connection. SaxAppConfig.DatabaseConfig databaseConfig = AppConfig.Databases.Databases.GetValue(databaseInstance, new SaxAppConfig.DatabaseConfig()); SacsDatabaseConsole.OdbcConfig config = new SacsDatabaseConsole.OdbcConfig(); config.location = databaseConfig.Location; config.user = databaseConfig.User; config.pword = databaseConfig.Password; SacsDatabase database = SacsDatabaseConsole.OpenOdbcDatabase(config); if (database.HasErrorState()) SaLogger.Warn(fn + " " + databaseInstance.ToString() + " Database initialisation error: " + database.ErrorStateMessage); sessionContextData.Databases.Add(databaseInstance, database); } //------------------------------------------------------------------- private void GenerateDatabaseDefinitions(SaxSessionContext sessionContext) { // Generate database definitions. if (!generateDatabaseDefinitions || !SaxSystem.DebugMode || SessionContext == null) return; if (!StringUtil.EmptyOnNull(EnvironmentName).EqualsCI("Development")) return; // Core database. ISacsDatabase coreDatabase = GetDatabase(sessionContext, Sax.Database.Core); if (coreDatabase != null && !StringUtil.IsEmpty(coreDatabase.ConnectionString)) { SaxDbDfnGenerator.Generate(Sax.Database.Core, coreDatabase.ConnectionString); //SaUpdateLogDbDfnGenerator.Generate(database.ConnectionString); } // Support database. ISacsDatabase supportDatabase = GetDatabase(sessionContext, Sax.Database.Support); if (supportDatabase != null && !StringUtil.IsEmpty(supportDatabase.ConnectionString)) SaxDbDfnGenerator.Generate(Sax.Database.Support, supportDatabase.ConnectionString); } //------------------------------------------------------------------- private void populateRegionsFromDataFile(SaxSessionContext sessionContext) { using (SaxInternals internals = new SaxInternals(sessionContext)) { SaxReferenceMgr referenceMgr = internals.ReferenceMgr; String regionsData = SaxResourceHelper.GetTextResource(SaxResourceHelper.TextResource.Data_CountriesWithRegions_Txt); String[] regionDataValues = regionsData.Split("\n"); SysId parentRegionId = null; for (int idx = 0; idx < regionDataValues.Length; idx++) { String regionData = regionDataValues[idx].ReplaceAll("\r", ""); if (StringUtil.IsEmpty(regionData)) continue; if (regionData.Length > 3 && regionData[2] == ':') { String iso2Code = regionData.Substring(0, 2); String name = regionData.Substring(3); SaxRegion region = getRegionByName(referenceMgr, name); if (region == null) { region = referenceMgr.CreateRegion(); region.RegionType = Sax.RegionType.Country; region.CountryIso2Code = iso2Code; region.Name = name; region.RegionIdParent = parentRegionId; if (!referenceMgr.InsertRegion(region, new DbUpdateInfo(new SysId(), "", ""))) { SaLogger.Error("Failed to insert region - " + referenceMgr.ErrorStateMessage); return; } } } else { // Sub continent. SaxRegion region = getRegionByName(referenceMgr, regionData); if (region == null) { region = referenceMgr.CreateRegion(); region.RegionType = Sax.RegionType.SubContinent; region.Name = regionData; if (!referenceMgr.InsertRegion(region, new DbUpdateInfo(new SysId(), "", ""))) { SaLogger.Error("Failed to insert region - " + referenceMgr.ErrorStateMessage); return; } } parentRegionId = region.Id; } } } } private SaxRegion getRegionByName(SaxReferenceMgr referenceMgr, String name) { SaxRegion.Params prmRegion = new SaxRegion.Params(); prmRegion.NameFull = name; return referenceMgr.GetRegion(prmRegion); } //------------------------------------------------------------------- } //======================================================================= }