namespace Framework.Cli.Config { using Framework.Config; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json.Serialization; /// /// Configuration used by all command cli. Values are stored in file ConfigCli.json. See also method ConfigCli.CopyConfigCliToConfigServer(); /// For default configuration see also method AppCli.InitConfigCli(); /// public class ConfigCli { /// /// Gets or sets EnvironmentName. This is the currently selected environment. /// public string EnvironmentName { get; set; } /// /// Returns EnvironmentName. This is the currently selected environment. Default is DEV. /// public string EnvironmentNameGet() { string result = EnvironmentName?.ToUpper(); if (UtilFramework.StringNull(result) == null) { result = "DEV"; } return result; } public List EnvironmentList { get; set; } /// /// Returns currently selected environment. Default is DEV. Adds new environment if none exists. /// public ConfigCliEnvironment EnvironmentGet() { if (EnvironmentList == null) { EnvironmentList = new List(); } var environmentName = EnvironmentNameGet(); var result = EnvironmentGet(environmentName); if (result == null) { result = new ConfigCliEnvironment { EnvironmentName = environmentName, IsUseDeveloperExceptionPage = environmentName == "DEV" }; EnvironmentList.Add(result); EnvironmentName = environmentName; } return result; } /// /// Returns specific environment. Returns null if not found in config. /// internal ConfigCliEnvironment EnvironmentGet(string environmentName) { return EnvironmentList.SingleOrDefault(item => item.EnvironmentName?.ToUpper() == environmentName); } /// /// Gets or sets WebsiteList. Multiple domain names can be served by one ASP.NET Core instance. /// public List WebsiteList { get; set; } /// /// Gets or sets ExternalGitList. /// public List ExternalGitList { get; set; } /// /// Gets ConfigCli.json. Used by CommandBuild. Created with default values if file does not exist. /// private static string FileName { get { return UtilFramework.FolderName + "ConfigCli.json"; } } /// /// Create default ConfigCli.json file. /// public static void Init(AppCli appCli) { if (!File.Exists(FileName)) { ConfigCli configCli = new ConfigCli(); configCli.EnvironmentName = configCli.EnvironmentNameGet(); configCli.EnvironmentList = new List(); configCli.WebsiteList = new List(); configCli.ExternalGitList = new List(); appCli.InitConfigCli(configCli); // EnvironmentName defined in WebsiteList List environmentNameList = new List(); foreach (var website in configCli.WebsiteList) { foreach (var domainName in website.DomainNameList) { environmentNameList.Add(domainName.EnvironmentName); } } environmentNameList = environmentNameList.Distinct().ToList(); // Add missing environments foreach (var environmentName in environmentNameList) { if (configCli.EnvironmentList.Where(item => item.EnvironmentName == environmentName).FirstOrDefault() == null) { configCli.EnvironmentList.Add(new ConfigCliEnvironment { EnvironmentName = environmentName, IsUseDeveloperExceptionPage = environmentName == "DEV" }); } } UtilFramework.ConfigSave(configCli, FileName); } } internal static ConfigCli Load() { var result = UtilFramework.ConfigLoad(FileName); result.EnvironmentName = result.EnvironmentNameGet(); // Init DEV if necessary if (result.WebsiteList == null) { result.WebsiteList = new List(); } if (result.ExternalGitList == null) { result.ExternalGitList = new List(); } var folderNameAngularList = new Dictionary(); int folderNameAngularIndex = 0; foreach (var website in result.WebsiteList) { // Init DomainNameList if (website.DomainNameList == null) { website.DomainNameList = new List(); } // Init FolderNameAngularIndex var folderNameAngular = UtilFramework.FolderNameParse(website.FolderNameAngular); if (folderNameAngular != null) { if (folderNameAngularList.ContainsKey(folderNameAngular) == false) { website.FolderNameAngularIndex = folderNameAngularIndex; folderNameAngularIndex += 1; } else { website.FolderNameAngularIsDuplicate = true; website.FolderNameAngularIndex = folderNameAngularList[folderNameAngular]; } } } return result; } internal static void Save(ConfigCli configCli) { UtilFramework.ConfigSave(configCli, FileName); } /// /// Copy from file ConfigCli.json to ConfigServer.json. Selects values depending on current EnvironmentName. /// internal static void CopyConfigCliToConfigServer() { // Console.WriteLine("Copy runtime specific values from ConfigCli to ConfigServer"); // There is also other values not needed for runtime like DeployAzureGitUrl. var configCli = ConfigCli.Load(); var configServer = ConfigServer.Load(); // Environment configServer.EnvironmentName = configCli.EnvironmentGet().EnvironmentName; configServer.IsUseDeveloperExceptionPage = configCli.EnvironmentGet().IsUseDeveloperExceptionPage; configServer.IsRedirectHttps = configCli.EnvironmentGet().IsRedirectHttps; configServer.IsRedirectWww = configCli.EnvironmentGet().IsRedirectWww; // ConnectionString configServer.ConnectionStringFramework = configCli.EnvironmentGet().ConnectionStringFramework; configServer.ConnectionStringApplication = configCli.EnvironmentGet().ConnectionStringApplication; // Website configServer.WebsiteList.Clear(); foreach (var webSite in configCli.WebsiteList) { configServer.WebsiteList.Add(new ConfigServerWebsite() { FolderNameAngular = webSite.FolderNameAngular, DomainNameList = webSite.DomainNameList.Where(item => item.EnvironmentName == configCli.EnvironmentGet().EnvironmentName).Select( // Copy config website values from Cli to Server item => new ConfigServerWebsiteDomain { DomainName = item.DomainName, AppTypeName = item.AppTypeName, IsRedirectHttps = item.IsRedirectHttps, BingMapKey = item.BingMapKey, GoogleAnalyticsId = item.GoogleAnalyticsId, GoogleAdSenseId = item.GoogleAdSenseId, Custom = item.Custom, PasswordSalt = item.PasswordSalt, }).ToList() }); } ConfigServer.Save(configServer); } } /// /// Definition of DEV, TEST, PROD environments in ConfigCli.json file. /// public class ConfigCliEnvironment { /// /// Gets or sets Name. For example DEV, TEST or PROD. /// public string EnvironmentName { get; set; } /// /// Gets or sets IsUseDeveloperExceptionPage. If true, show detailed exceptions. Restart web server after value change! /// public bool IsUseDeveloperExceptionPage { get; set; } /// /// Gets or sets IsRedirectHttps. If true, http is redirected to https. By default this value is false. Restart web server after value change! /// If true, server middelware redirects to https for all websites. /// public bool IsRedirectHttps { get; set; } /// /// Gets or sets IsRedirectWww. If ture, non www is redirected to wwww. For example workplacex.org is redirected to www.workplacex.org. /// public bool IsRedirectWww { get; set; } /// /// Gets or sets ConnectionStringFramework. Can be different from ConnectionStringApplication, if framework relevant tables are stored on another database. /// public string ConnectionStringFramework { get; set; } /// /// Gets or sets ConnectionStringApplication. Database containing business data. /// public string ConnectionStringApplication { get; set; } /// /// Gets or sets ConnectionString for Framework and Application. /// [JsonIgnore] public string ConnectionString { get { return ConnectionStringApplication; } set { ConnectionStringFramework = value; ConnectionStringApplication = value; } } /// /// Gets or sets DeployAzureGitUrl. Used by class ommandDeploy to deploy (publish) application to Azure cloud. /// public string DeployAzureGitUrl { get; set; } /// /// Gets or sets DeployLocalFolderName. Used by class CommandDeploy to deploy application to local folder. Typically an IIS server folder. /// public string DeployLocalFolderName { get; set; } } public class ConfigCliExternal { /// /// Gets or sets ExternalGit. For example: https://username:password@dev.azure.com/company/repo/_git/repo.git /// Clones and calls prebuild method AppCli.CommandExternalGit(); in ExternalGit cli build command. /// public string ExternalGit { get; set; } /// /// Gets or sets ExternalProjectName. For example MyApp. Used to build ExternalFolderName ExternalGit/MyApp/ Cli build command calls this .NET script. /// public string ExternalProjectName { get; set; } } /// /// Include layout website. /// public class ConfigCliWebsite { /// /// Gets or sets FolderNameAngular. This is the Angular folder. The following commands are executed: "npm install", "npm run build:ssr". /// public string FolderNameAngular { get; set; } /// /// Gets or sets FolderNameAngularIndex. Two websites with same FolderNameAngular get same index. /// internal int? FolderNameAngularIndex { get; set; } /// /// Gets FolderNameAngularWebsite. For example Website01. /// internal string FolderNameAngularWebsite => string.Format("Website{0:00}/", FolderNameAngularIndex.GetValueOrDefault() + 1); /// /// Gets or sets FolderNameAngularIsDuplicate. True, if another website has the same FolderNameAngular. /// internal bool FolderNameAngularIsDuplicate { get; set; } /// /// Gets DomainNameList. Domains mapped to this layout website. /// public List DomainNameList { get; set; } /// /// Returns property DomainNameList as text. /// public string DomainNameListToString() { string result = null; bool isFirst = true; if (DomainNameList != null) { foreach (var item in DomainNameList) { string domainName = item.DomainName; if (isFirst) { isFirst = false; } else { result += "; "; } result += domainName; } } return result; } } /// /// Mapping DomainName to AppTypeName. /// public class ConfigCliWebsiteDomain { /// /// Gets or sets EnvironmentName. This is the currently selected environment. /// public string EnvironmentName { get; set; } /// /// Gets or sets DomainName. For example "localhost". /// public string DomainName { get; set; } /// /// Gets or sets AppTypeName. Needs to derrive from AppJson. For example: "Application.AppJson, Application". If null, index.html is rendered without server side rendering. /// public string AppTypeName { get; set; } /// /// Gets or sets IsRedirectHttps. If true, it redirects on website level. See also property ConfigCliEnvironment.IsRedirectHttps. /// public bool IsRedirectHttps { get; set; } /// /// Gets or sets BingMapKey. See also class BingMap. /// public string BingMapKey { get; set; } /// /// Gets or sets GoogleAnalyticsId. This id is for Google Analytics 4. For example "G-XXXXXXXXXX". /// public string GoogleAnalyticsId { get; set; } /// /// Gets or sets GoogleAdSenseId. For example "ca-pub-XXXXXXXXXXXXXXXX". /// public string GoogleAdSenseId { get; set; } /// /// Gets or sets Custom. /// public object Custom { get; set; } /// /// Gets or sets PasswordSalt. Additional salt value for each website to validate passwords. See method UtilFramework.PasswordSaltConfigCreate(); to create a new key. /// public string PasswordSalt { get; set; } } }