public LiteConfig GetDefaults() { string startupConfigFilePath = _util.GetTempFolder() + Path.DirectorySeparatorChar + Constants.Dirs.Profiles + Path.DirectorySeparatorChar + Constants.StartupFileName; string tempPath = _util.GetTempFolder() + Path.DirectorySeparatorChar + "tmp"; return(new LiteConfig(startupConfigFilePath, tempPath)); }
public Profile Load(string fileName) { _logger.Log(LogLevel.Information, $"Loading: {fileName}"); string json = File.ReadAllText(fileName); if (json == null || json == "" || !json.StartsWith("{")) { //BOUR-994 try to load the .backup json = File.ReadAllText(_util.GetTempFolder(fileName + ".backup")); if (json == null || json == "" || !json.StartsWith("{")) { throw new Exception("Local Profile is null or blank"); } else { _logger.Log(LogLevel.Critical, $"Profile was corrupt, recovered from backup!!"); } } return(_jsonHelper.DeserializeObject(json)); }
public void LoadProfile(Profile profile, string filename) { Throw.IfNullOrWhiteSpace(filename); var tmpPath = _util.GetTempFolder(filename); FileInfo oFileInfo = new FileInfo(tmpPath); var currentDir = Directory.GetCurrentDirectory(); _logger.LogDebug($"Current dir: {currentDir}"); if (oFileInfo.LastWriteTime > Profile.modifiedDate || Profile.modifiedDate == null || Profile._overrideVersionAndModifiedDate == true) { Profile newProfile = _profileLoader.Load(filename); // Spit out errors, some of which may be fatal foreach (string error in newProfile.errors) { _logger.Log(LogLevel.Warning, error); } if (newProfile.IsInError() == false) { //profile.MergeProfile(newProfile); _profileMerger.MergeProfile(profile, newProfile); //_logger.Log(TraceEventType.Verbose, $"loaded profile {filename} {JValue.Parse(profile.ToString()).ToString(Formatting.Indented)}"); } else { _logger.Log(LogLevel.Critical, $"Profile {profile.startupParams.localProfilePath} failed to load {profile.jsonInError}"); throw new Exception($"Bad Json File: {profile.jsonInError}"); } Profile.modifiedDate = oFileInfo.LastWriteTime; } }
/// <summary> /// Merges another profile into this one in an additive fashion unless version is higher /// This should preserve the arg > file > remote precedence with the exception of variables required to be defined /// at program startup like kickoffInterval, logRetentionDays, name, etc. /// Command line args boot with version = 0 unless otherwise specified. /// To add settings without agent restart, add at Cloud or agent with same version. /// To replace settings without agent restart, add at Cloud or agent with incremented version.Note: live queues will reset. /// If you switch profiles at the agent, the name will (should) be different and merge is skipped. /// </summary> /// <param name="current"></param> /// <param name="profile"></param> public void MergeProfile(Profile current, Profile profile) { Throw.IfNull(current); bool bootstrap = current.name.Equals("Bootstrap"); if (profile == null) { return; } lock (current) { //game over!! Someone switched profiles on the client or server or it's not time if ((!current.name.Equals(profile.name) && !bootstrap) || !(DateTime.Now > profile.activationTime)) { _logger.Log(LogLevel.Debug, $"inbound profile name: {profile.name} this name: {current.name} bootstrap: {bootstrap}, inbound activationTime: {profile.activationTime} using ignore strategy"); return; } if (profile.version > current.version) { _logger.Log(LogLevel.Debug, $"inbound profile version {profile.version} greater than current version {current.version}, using replacement strategy"); // foreach (var conn in this.connections) // { // Logger.logger.Log(TraceEventType.Information, $"stopping {conn.name}"); // conn.stop(); // } _taskManager.Stop(); //replace all settings, realizing this dumps all live queues and connections //may want code that is more fine grained and doesn't drop work in progress. current.activationTime = profile.activationTime; current.availableCodeVersions = profile.availableCodeVersions; //this.backlog; shb nonserialized current.backlogDetection = profile.backlogDetection; current.backlogInterval = profile.backlogInterval; /* 2020-05-22 AMG added properties to profile */ current.duplicatesDetectionUpload = profile.duplicatesDetectionUpload; current.duplicatesDetectionDownload = profile.duplicatesDetectionDownload; current.duplicatesDetectionInterval = profile.duplicatesDetectionInterval; current.modalityList = profile.modalityList; current.modalityDetectionArchivePeriod = profile.modalityDetectionArchivePeriod; current.connections = profile.connections; current.dcmtkLibPath = profile.dcmtkLibPath; //this.errors = profile.errors; shb not needed //this.highWait = profile.highWait; shb nonserialized current.highWaitDelay = profile.highWaitDelay; //this.jsonInError = profile.jsonInError; shb not needed //this.jsonSchemaPath = profile.jsonSchemaPath; shb not needed current.KickOffInterval = profile.KickOffInterval; //this.lastKickOff = profile.lastKickOff; shb not needed //this.lastStartup = profile.lastStartup; shb not needed current.Labels = profile.Labels; //2018-02-13 shb need to assign inbound profile.logger settings during replacement strategy var primary = _connectionFinder.GetPrimaryLifeImageConnection(current); //current.logger = new Logger("default"); current.logger = new Logger(); current.logger.ConsoleTraceLevel = profile.logger.ConsoleTraceLevel; current.logger.SplunkTraceLevel = profile.logger.SplunkTraceLevel; current.logger.FileTraceLevel = profile.logger.FileTraceLevel; current.logger.TracePattern = profile.logger.TracePattern; Logger.logger = current.logger; //Logger.logger.Init(); _loggerManager.Init(current.logger); current.LogFileSize = profile.LogFileSize; current.logRetentionDays = profile.logRetentionDays; current.maxTaskDuration = profile.maxTaskDuration; //this.mediumWait = profile.mediumWait; shb nonserialized current.mediumWaitDelay = profile.mediumWaitDelay; current.minFreeDiskBytes = profile.minFreeDiskBytes; //this.modifiedDate = profile.modifiedDate; shb not needed current.name = profile.name; Profile._overrideVersionAndModifiedDate = Profile._overrideVersionAndModifiedDate; //profileConverter not needed current.recoveryInterval = profile.recoveryInterval; //this.rowVersion = profile.rowVersion; shb not merged because we get this from the api call current.rules = profile.rules; current.run = profile.run; //this.runningCodeVersion = profile.runningCodeVersion; shb not needed // Only allow startup params in startup profile this.startupParams = profile.startupParams; //startupConfigFilePath shb not needed //this.startupParams = profile.startupParams; shb not needed current.taskDelay = profile.taskDelay; current.tempFileRetentionHours = profile.tempFileRetentionHours; current.tempPath = profile.tempPath; current.updateCodeVersion = profile.updateCodeVersion; current.updateUrl = profile.updateUrl; current.updatePassword = profile.updatePassword; current.updateUsername = profile.updateUsername; current.useSocketsHttpHandler = profile.useSocketsHttpHandler; current.version = profile.version; // shb will change the value of tempPath and write back to a profile if saved (including possibly the same profile). //convenience assignment to reduce number of calls to get Windows ProgramData folder. current.tempPath = _util.GetTempFolder(current.tempPath); _profileWriter.SaveProfile(current).Wait(); if (!bootstrap) { throw new Exception("Replacement Strategy Needs Full LITE.init(), throwing this exception on purpose!"); } } else if (profile.version == current.version) { _logger.Log(LogLevel.Debug, $"inbound profile version {profile.version} same as current version {current.version}, using merge strategy"); //2018-03-03 shb need to assign inbound profile.logger settings during merge so we can have non-destructive loglevel changes // this.logger.logLevel = profile.logger.logLevel; var primary = _connectionFinder.GetPrimaryLifeImageConnection(current); //current.logger = new Logger("default"); current.logger = new Logger(); // this.logger.logLevel = profile.logger.logLevel; current.logger.ConsoleTraceLevel = profile.logger.ConsoleTraceLevel; current.logger.SplunkTraceLevel = profile.logger.SplunkTraceLevel; current.logger.FileTraceLevel = profile.logger.FileTraceLevel; current.logger.TracePattern = profile.logger.TracePattern; Logger.logger = current.logger; //Logger.logger.Init(); _loggerManager.Init(current.logger); if (current.updateCodeVersion == null) { current.updateCodeVersion = profile.updateCodeVersion; } //merge settings in additive fashion except override ones that startup with predefined values foreach (var srcConn in profile.connections) { Connection destConn = current.connections.Find(e => e.name == srcConn.name); if (destConn == null) { //srcConn.profile = this; current.connections.Add(srcConn); } } //dev hack to load in script example. Script script = new Script { name = "Hello World", source = "using System.Diagnostics; if (logger.logLevel == \"Trace\") logger.Log(TraceEventType.Verbose, $\"Hello World\");" }; if (current.rules.scripts.Find(e => e.name == script.name) == null) { _logger.Log(LogLevel.Debug, $"adding script {script.name}"); current.rules.scripts.Add(script); } foreach (var rule in profile.rules.destRules) { if (!current.rules.destRules.Exists(e => e.name == rule.name)) { current.rules.destRules.Add(rule); } } var msg = ""; foreach (var rule in current.rules.destRules) { msg += rule.name + " "; } _logger.Log(LogLevel.Debug, $"{current.rules.destRules.Count} rules after merge: {msg}"); } else if (profile.version < current.version) { //ignore _logger.Log(LogLevel.Debug, $"inbound profile version {profile.version} less than current version {current.version}, using ignore strategy"); return; } else { //ignore _logger.Log(LogLevel.Debug, $"Unexpected condition inbound version {profile.version} current version {current.version}, using ignore strategy"); return; } } }
public ConfigurationLoaderPackage LoadConfiguration(string[] args, List <string> argsList) { System.Reflection.Assembly assembly = System.Reflection.Assembly.GetEntryAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); var version = fvi.FileVersion; SaveInRegistry(version); var newCurrentDir = assembly.Location.Substring(0, assembly.Location.LastIndexOf(Path.DirectorySeparatorChar)); Directory.SetCurrentDirectory(newCurrentDir); _logger.LogInformation($"LiTE current directory = {newCurrentDir}"); var currentDir = Directory.GetCurrentDirectory(); _logger.Log(LogLevel.Information, $"Life Image Transfer Exchange v{version} Started"); var stopWatch = new Stopwatch(); var taskInfo = $""; stopWatch.Start(); ExtractWindowsDCMTK(); var platform = DetectPlatform(); string startupConfigFilePath = _liteConfigService.GetDefaults().StartupConfigFilePath; _logger.Log(LogLevel.Warning, $"startupConfigFilePath: {startupConfigFilePath} Profiles: {_util.GetTempFolder(Constants.Dirs.Profiles)}"); //2019-05-22 shb copy profile files to working folder. Needed for read-only installs such as OSX .app bundle and docker/kubernetes if (!Directory.Exists(_util.GetTempFolder(Constants.Dirs.Profiles))) { _logger.Log(LogLevel.Warning, $"{_util.GetTempFolder(Constants.Dirs.Profiles)} does not exist."); _logger.Log(LogLevel.Warning, $"Current Directory: {Directory.GetCurrentDirectory()}"); //TODO check legacy folder locations for existing profile and copy to new location if (Directory.Exists(Constants.ProgramDataDir + Path.DirectorySeparatorChar + Constants.Dirs.Profiles)) { _logger.Log(LogLevel.Warning, $"Copying legacy profiles {Constants.ProgramDataDir + Path.DirectorySeparatorChar + Constants.Dirs.Profiles}"); Directory.CreateDirectory(_util.GetTempFolder(Constants.Dirs.Profiles)); foreach (string filename in Directory.EnumerateFiles(Constants.ProgramDataDir + Path.DirectorySeparatorChar + Constants.Dirs.Profiles)) { var destfile = _util.GetTempFolder(Constants.Dirs.Profiles) + Path.DirectorySeparatorChar + filename.Substring(filename.LastIndexOf(Path.DirectorySeparatorChar)); _logger.Log(LogLevel.Information, $"Copying {filename} to {destfile}"); using FileStream SourceStream = File.Open(filename, FileMode.Open, FileAccess.Read); using FileStream DestinationStream = File.Create(destfile); SourceStream.CopyTo(DestinationStream); } } else if (Directory.Exists(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.Dirs.Profiles)) { _logger.Log(LogLevel.Warning, $"Copying default profiles {Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.Dirs.Profiles}"); Directory.CreateDirectory(_util.GetTempFolder(Constants.Dirs.Profiles)); foreach (string filename in Directory.EnumerateFiles(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.Dirs.Profiles)) { var destfile = _util.GetTempFolder(Constants.Dirs.Profiles) + Path.DirectorySeparatorChar + filename.Substring(filename.LastIndexOf(Path.DirectorySeparatorChar)); _logger.Log(LogLevel.Information, $"Copying {filename} to {destfile}"); using FileStream SourceStream = File.Open(filename, FileMode.Open, FileAccess.Read); using FileStream DestinationStream = File.Create(destfile); SourceStream.CopyTo(DestinationStream); } } else { _logger.Log(LogLevel.Warning, $"{Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.Dirs.Profiles} does not exist."); } } var startupProfile = _profileLoaderService.LoadStartupConfiguration(startupConfigFilePath); if (startupProfile.startupParams.localProfilePath != _util.GetTempFolder(startupProfile.startupParams.localProfilePath)) { _logger.Log(LogLevel.Warning, $"Changing startupProfile.startupParams.localProfilePath: {startupProfile.startupParams.localProfilePath} to {_util.GetTempFolder(startupProfile.startupParams.localProfilePath)}"); startupProfile.startupParams.localProfilePath = _util.GetTempFolder(startupProfile.startupParams.localProfilePath); startupProfile.startupParams.saveProfilePath = _util.GetTempFolder(startupProfile.startupParams.saveProfilePath); _profileFileWriter.Save(startupProfile, startupConfigFilePath); } // ulong installedMemory; // MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX(); // if (GlobalMemoryStatusEx(memStatus)) // { // installedMemory = memStatus.ullTotalPhys; // } //ShowGreetings(); // load the logger //var profile = new Profile(Logger.logger); var profile = new Profile(); //profile.logger // todo: load logger // check for setup // if (args.Length != 0 && args[0].ToLower() != "setup") // { // profile = loadArgs(args, profile); // re-assign, can be replaced // LITE.SaveToStartupConfigration(profile); // } // else // { //startupProfile = Profile.LoadStartupConfiguration(); startupProfile = _profileLoaderService.LoadStartupConfiguration(startupConfigFilePath); profile = startupProfile; // } // _logger.LogLevel = profile.logger.logLevel; Logger.logger.ConsoleTraceLevel = profile.logger.ConsoleTraceLevel; Logger.logger.FileTraceLevel = profile.logger.FileTraceLevel; Logger.logger.SplunkTraceLevel = profile.logger.SplunkTraceLevel; Logger.logger.TracePattern = profile.logger.TracePattern; _logger.Log(LogLevel.Debug, $"Startup Configuration: {profile}"); //setup if (args != null && args.Length > 0 && args[0] != null && args[0] == "setup") { bool exitCode = false; if (args.Length == 1) { Setup.EnterSetup(profile); } else { var arg = argsList.Find(x => x.Contains("register=")); if (arg != null) { var regParamList = argsList.Find(x => x.Contains("register=")).Substring(9); var regParams = regParamList.Split(','); if (regParams.Length == 4) { exitCode = Setup.Register(regParams, profile); _util.ConfigureService(true); } else { _logger.Log(LogLevel.Information, "Lite Registration: Lite register=\"username,password,orgcode,servicename\""); } } else { var argUninstall = argsList.Find(x => x.Contains("uninstall")); if (argUninstall != null) { _util.ConfigureService(false); } } } Environment.Exit((exitCode == false) ? 0 : 1); } // recovery loop _logger.Log(LogLevel.Information, "Life Image Transfer Exchange - Starting Processing"); profile.lastStartup = DateTime.Now; //instantiate the class instance //var lite = new LITE(profile); profile.runningCodeVersion = version; //LITE.profile.runningCodeVersion = version; _logger.Log(LogLevel.Information, $"{taskInfo} Running time: {stopWatch.Elapsed}"); return(new ConfigurationLoaderPackage(profile, platform, version)); }