예제 #1
0
        public async Task <IActionResult> Create()
        {
            try
            {
                MemoryStream stream = new MemoryStream();
                await HttpContext.Request.Body.CopyToAsync(stream);

                stream.Position = 0;
                StreamReader reader      = new StreamReader(stream);
                string       profilejson = reader.ReadToEnd();
                Profile      profile     = _profileJsonHelper.DeserializeObject(profilejson);
                var          connection  = _connectionFinder.GetPrimaryLITEConnection(profile);
                var          manager     = _connectionManagerFactory.GetManager(connection) as ILiteConnectionManager;
                await manager.RegisterLITE(profile);

                return(CreatedAtRoute("GetLITE", new { username = _connectionFinder.GetPrimaryLifeImageConnection(profile).username }, profile));
                //return CreatedAtRoute("GetFile", new { boxUuid = paths[0], fileID = paths[0] }, paths);
            }
            catch (TaskCanceledException)
            {
                _logger.LogInformation($"Task was canceled.");
                return(StatusCode(503));
            }
            catch (Exception e)
            {
                _logger.LogCritical($"{e.Message} {e.StackTrace}");
                return(StatusCode(503));
            }
        }
예제 #2
0
        public ActionResult <List <string> > GetAll()
        {
            List <string> list = new List <string>();

            foreach (var profile in LiteConnectionManager.LITERegistry)
            {
                var connection = _connectionFinder.GetPrimaryLifeImageConnection(profile);
                list.Add(connection.username);
            }
            return(list);
        }
        public async Task RegisterLITE(Profile lite)
        {
            try
            {
                //server side method the LITE will call to register itself, invoked from LITEController
                var registered = LITERegistry.ToList().FindAll(e => _connectionFinder.GetPrimaryLifeImageConnection(e).tenantID == _connectionFinder.GetPrimaryLifeImageConnection(lite).tenantID);
                switch (registered.Count)
                {
                case 0:
                    LITERegistry.Add(lite);
                    break;

                case 1:
                    //already registered, just update
                    registered[0] = lite;
                    break;

                default:
                    //duplicate entries?
                    break;
                }

                await Task.Yield();
            }
            catch (TaskCanceledException)
            {
                _logger.Log(LogLevel.Information, $"Task was canceled.");
            }
            catch (Exception e)
            {
                _logger.LogFullException(e);
            }

            return;
        }
예제 #4
0
        private async Task SyncWithCloud(Profile profile)
        {
            var cloudConn = _connectionFinder.GetPrimaryLifeImageConnection(profile);

            if (profile.startupParams.putServerProfile && !cloudConn.loginNeeded)
            {
                await _cloudProfileWriter.PutConfigurationToCloud(profile, cloudConn);

                // During write set modified date to now so it doesn't go back around and reload
                Profile.modifiedDate = DateTime.Now;
            }
        }
예제 #5
0
        public async Task Process()
        {
            var taskInfo = $"";
            var profile  = _profileStorage.Current;

            _logger.Log(LogLevel.Information, "Life Image Transfer Exchange Loop");

            try
            {
                try
                {
                    lock (ProfileLocker)
                    {
                        _profileManager.LoadProfile(profile, profile.startupParams.localProfilePath);
                        //Profile.LoadProfile(profile, profile.startupParams.localProfilePath);
                        if (profile.duplicatesDetectionUpload)
                        {
                            string message = "Duplicates detection and elimination process is active for upload process.";
                            _logger.Log(LogLevel.Information, $"{message}");
                        }
                        else
                        {
                            string message = "Duplicates detection and elimination process is not active for upload process.";
                            _logger.Log(LogLevel.Information, $"{message}");
                        }
                        if (profile.duplicatesDetectionDownload)
                        {
                            string message = "Duplicates detection and elimination process is active for download process.";
                            _logger.Log(LogLevel.Information, $"{message}");
                        }
                        else
                        {
                            string message = "Duplicates detection and elimination process is not active for download process.";
                            _logger.Log(LogLevel.Information, $"{message}");
                        }
                        //var primaryConnection = profile.GetPrimaryLifeImageConnection();
                        var primaryConnection = _connectionFinder.GetPrimaryLifeImageConnection(profile);
                        if (primaryConnection == null)
                        {
                            throw new Exception($"Primary Connection Missing out of {profile.connections.Capacity} total connections.");
                        }

                        if (platform.Equals("win") && string.IsNullOrEmpty(profile.dcmtkLibPath))
                        {
                            Console.WriteLine(profile.name);
                            profile.dcmtkLibPath = "tools" + Path.DirectorySeparatorChar + Constants.Dirs.dcmtk + Path.DirectorySeparatorChar + "dcmtk-3.6.3-win64-dynamic";
                            //profile.SaveProfile();
                            _profileWriter.SaveProfile(profile).Wait();
                        }

                        if (!primaryConnection.loginNeeded)
                        {
                            _cloudProfileLoaderService.LoadProfile(profile, primaryConnection).Wait();
                            //profile.LoadProfile(primaryConnection).Wait();
                        }

                        //profile.SaveProfile();
                        _profileWriter.SaveProfile(profile).Wait();

                        bool isEnabled = false;
                        AppContext.TryGetSwitch("System.Net.Http.useSocketsHttpHandler", out isEnabled);

                        if (isEnabled != profile.useSocketsHttpHandler)
                        {
                            _logger.Log(LogLevel.Debug, $"{taskInfo} Calling AppContext.SetSwitch(\"System.Net.Http.useSocketsHttpHandler\", {profile.useSocketsHttpHandler})"); AppContext.SetSwitch("System.Net.Http.useSocketsHttpHandler", profile.useSocketsHttpHandler);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.Message.Contains("Replacement Strategy Needs Full LITE.init()"))
                    {
                        _logger.Log(LogLevel.Critical, $"{taskInfo} Configuration changed received.");
                    }
                    else
                    {
                        _logger.LogFullException(e, $"{taskInfo} Profile Operations Problem: {e.Message}");
                    }

                    throw e;
                }

                //adjust loglevel if necessary
                //                                    _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;

                //compile the scripts as needed
                foreach (var myscript in profile.rules.scripts)
                {
                    if (myscript.script == null)
                    {
                        _logger.Log(LogLevel.Debug, $"compiling {myscript.name}");
                        _scriptService.Compile(myscript);
                    }
                }


                //let's queue up some work
                _logger.Log(LogLevel.Information, "Life Image Transfer Exchange kickoff start");

                var newTaskID = _taskManager.NewTaskID();
                await kickOff(newTaskID);

                _logger.Log(LogLevel.Information, "Life Image Transfer Exchange kickoff end");

                if (profile.backlogDetection)
                {
                    foreach (var conn in profile.connections)
                    {
                        if (conn.toRules.Count > 0)
                        {
                            profile.backlog = true;
                        }
                    }

                    if (profile.backlog)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} Detected Backlog, skipping kickoffInterval");
                        await Task.Delay(profile.backlogInterval, _taskManager.cts.Token);

                        profile.backlog = false;
                    }
                    else
                    {
                        await Task.Delay(profile.KickOffInterval, _taskManager.cts.Token);
                    }
                }
                else
                {
                    await Task.Delay(profile.KickOffInterval, _taskManager.cts.Token);
                }

                RecoveryCount = 0;
            }
            catch (Exception e)
            {
                if (LITETask._shutdown)
                {
                    throw new Exception("Application is terminated");
                }
                ;

                if (e.Message.Contains("Replacement Strategy Needs Full LITE.init()"))
                {
                }
                else
                {
                    _logger.Log(LogLevel.Critical, $"{taskInfo} Life Image Transfer Exchange Loop Exception: breaking out of run loop due to unrecoverable exception. {e.Message}");
                    if (e.InnerException != null)
                    {
                        _logger.Log(LogLevel.Critical, $"Inner Exception: {e.InnerException}");
                    }
                }
            }
        }
예제 #6
0
        public void InitConnections(Profile profile, List <string> argsList, object ProfileLocker)
        {
            Throw.IfNull(profile);

            try
            {
                //if (profile.startupParams.generateSchema == true)
                //{
                //    Directory.CreateDirectory("JSONSchema");

                //    Logger.logger.Log(TraceEventType.Information, "Registering Newtonsoft.Json.Schema.License.");
                //    Newtonsoft.Json.Schema.License.RegisterLicense(
                //        "3606-tXIhm+ANdVeBkIPZuD16/AYNS41W5oqeEbwG065ms41NYxGKi2qqOtqI9rjSh4TTaOAnj9dYS0hk6cFHAoKcuFJZXg9dhTaBzx/Hx7Oq43qE7bJyWPyHaTaGRMZlZEq2xiPMzOl9x4gBNkgdLz3sJaG9thZJRLSwCdcp0qXXxZ17IklkIjozNjA2LCJFeHBpcnlEYXRlIjoiMjAxOS0wMy0xNVQyMDoyNDozMS43MzkzNzU0WiIsIlR5cGUiOiJKc29uU2NoZW1hQnVzaW5lc3MifQ==");
                //    Logger.logger.Log(TraceEventType.Information,
                //        "Newtonsoft.Json.Schema.License registration complete.");

                //    var types = Assembly
                //        .GetExecutingAssembly()
                //        .GetTypes();
                //    //.Where(t => t.Namespace.StartsWith("LifeImageLite"));

                //    foreach (var file in Directory.EnumerateFiles("JSONSchema"))
                //    {
                //        File.Delete(file);
                //    }

                //    foreach (var type in types)
                //    {
                //        if (type.IsPublic && type.Namespace == "LifeImageLite" && type.Name == "Profile")
                //        {
                //            string schemaString = null;
                //            try
                //            {
                //                JSchemaGenerator generator = new JSchemaGenerator();
                //                JSchema schema = generator.Generate(type);

                //                schemaString = schema.ToString();
                //                if (Logger.logger.FileTraceLevel == "Verbose")
                //                    Logger.logger.Log(TraceEventType.Verbose, $"JSON Schema for {type}");
                //                if (Logger.logger.FileTraceLevel == "Verbose")
                //                    Logger.logger.Log(TraceEventType.Verbose, $"{schemaString}");

                //                if (schemaString != null && !type.Name.Contains("<"))
                //                {
                //                    File.WriteAllTextAsync(
                //                        "JSONSchema" + Path.DirectorySeparatorChar + type.Name + ".schema.json",
                //                        schemaString);
                //                }
                //            }

                //            catch (Newtonsoft.Json.Schema.JSchemaException e)
                //            {
                //                Logger.logger.Log(TraceEventType.Warning, $"{e.Message} {e.StackTrace}");
                //            }
                //        }
                //    }
                //}
            }
            catch (NullReferenceException)
            {
                _logger.Log(LogLevel.Information, $"no startupProfile.startupParams.generateSchema.");
            }

            Directory.CreateDirectory(profile.tempPath);

            //Load Profile from file if specified

            var arg = argsList.Find(x => x.Contains("loadProfileFile="));

            if (arg != null)
            {
                var fileName = argsList.Find(x => x.Contains("loadProfileFile=")).Substring(16);
                if (fileName != null)
                {
                    _logger.Log(LogLevel.Information, $"loadProfileFile={fileName}. Loading this profile");
                    lock (ProfileLocker)
                    {
                        profile.startupParams.localProfilePath = fileName;
                        profile.startupParams.saveProfilePath  = fileName;
                        //Profile.LoadProfile(profile, profile.startupParams.localProfilePath);
                        //Profile.LoadProfile(profile, profile.startupParams.localProfilePath);
                        _profileManager.LoadProfile(profile, profile.startupParams.localProfilePath);
                    }
                }
            }
            else
            {
                _logger.Log(LogLevel.Information, $"no loadProfileFile arg.  Using startup.config.json");
                _logger.Log(LogLevel.Information, $"profile.startupParams.localProfilePath: {profile.startupParams.localProfilePath}");

                if (profile.startupParams.localProfilePath != null)
                {
                    lock (ProfileLocker)
                    {
                        _profileManager.LoadProfile(profile, profile.startupParams.localProfilePath);
                        //Profile.LoadProfile(profile, profile.startupParams.localProfilePath);
                    }
                }
                else
                {
                    //Find the current profile from the LITE.sh file
                    var currentProfile = File.ReadAllText("LITE.sh");
                    var elements       = currentProfile.Split(" ");
                    currentProfile = elements[2].Substring(16);

                    lock (ProfileLocker)
                    {
                        profile.startupParams.localProfilePath = currentProfile;
                        profile.startupParams.saveProfilePath  = currentProfile;
                        profile.startupParams.getServerProfile = true;
                        profile.startupParams.putServerProfile = true;
                        profile.startupParams.generateSchema   = true;
                        profile.startupParams.validateProfile  = true;

                        //Profile.LoadProfile(profile, currentProfile);
                        _profileManager.LoadProfile(profile, currentProfile);
                    }
                }
            }

            _logger.Log(LogLevel.Debug, $"Replacing Logger.logger with Profile.logger");

            //            Logger.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;

            //initialize the connections

            var primary = _connectionFinder.GetPrimaryLifeImageConnection(profile);
            //LifeImageCloudConnection primary = profile.GetPrimaryLifeImageConnection(); /* AMG Why do we need to find primary connection if we are not using it? What is there is more than 1. The code is expecting only one primary connection */
            Rules rules = profile.rules;

            foreach (var conn in profile.connections)
            {
                if (conn.enabled == true)
                {
                    var connManager = _connectionManagerFactory.GetManager(conn);
                    connManager.Init();
                    //conn.init();
                }
            }

            //Create the specified folders
            Directory.CreateDirectory(profile.tempPath);
        }
예제 #7
0
        /// <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;
                }
            }
        }