Example #1
0
        internal void StartHeartBeat()
        {
            if (IsQSenderReadyForHB)
            {
                return;
            }
            IsQSenderReadyForHB = true;
            if (MyTSMHistory == null)
            {
                MyTSMHistory = new TheMirrorCache <TheSentRegistryItem>(TheBaseAssets.MyServiceHostInfo.TO.QSenderDejaSentTime);
            }

            if (!TheBaseAssets.MyServiceHostInfo.UseHBTimerPerSender)
            {
                TheQueuedSenderRegistry.RegisterHBTimer(sinkHeartBeatTimer);
            }
            else
            {
                lock (lockStartLock)
                {
                    if (mMyHeartBeatTimer == null)
                    {
                        mMyHeartBeatTimer = new Timer(sinkHeartBeatTimerLocal, null, TheBaseAssets.MyServiceHostInfo.TO.QSenderHealthTime, TheBaseAssets.MyServiceHostInfo.TO.QSenderHealthTime);
                    }
                }
            }
            InitHeartbeatTimer();
        }
Example #2
0
        public override bool Init()
        {
            if (mIsInitCalled)
            {
                return(false);
            }
            mIsInitCalled = true;

            ReqBuffer = new TheMirrorCache <TheRequestData>(0);
            string t = TheCommonUtils.CStr(TheBaseAssets.MySettings.GetSetting("WRA_RequestTimeout"));

            if (!string.IsNullOrEmpty(t))
            {
                RequestTimeout = TheCommonUtils.CInt(t);
            }
            if (RequestTimeout < 15)
            {
                RequestTimeout = 15;
            }

            InitServices();

            TheCommCore.MyHttpService.RegisterHttpInterceptorB4("/", InterceptHttpRequest);
            TheScopeManager.RegisterScopeChanged(sinkScopeIDUpdate);
            MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);

            mIsInitialized = true;
            MyBaseEngine.ProcessInitialized();
            return(true);
        }
        public void InstantiateTheMirrorCacheTest()
        {
            #region ASSEMBLE

            TheMirrorCache <TheStorageEngineTSM> mirror;

            #endregion

            #region ACT

            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };

            #endregion

            #region ASSERT

            Assert.IsTrue(mirror != null);
            mirror?.Dispose();
            mirror = null;

            #endregion
        }
        public void AddItemsToTheMirrorCacheTest()
        {
            #region ASSEMBLE

            int            totalCandidates = 5000;
            int            totalInserts    = 0;
            var            random          = new Random();
            var            data            = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            CountdownEvent countdown       = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            List <TheStorageEngineTSM>           TSMs = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs
            foreach (var payload in data)
            {
                TSMs.Add(new TheStorageEngineTSM()
                {
                    TXTPattern = payload.ToString()
                });
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };

            #endregion

            #region ACT

            mirror.AddItems(TSMs, response =>
            {
                totalInserts = response.Count();
                countdown.Signal();
            });

            countdown.Wait();
            countdown?.Dispose();
            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsTrue(totalCandidates == totalInserts);

            #endregion
        }
        public void RemoveAnItemByKeyFromTheMirrorCacheTest()
        {
            #region ASSEMBLE

            int totalCandidates            = 5000;
            int indexMiddle                = totalCandidates / 2;
            int indexCurrent               = 0;
            var random                     = new Random();
            var data                       = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            TheStorageEngineTSM        tsmCurrent = null;
            TheStorageEngineTSM        tsmMiddle  = null;
            TheStorageEngineTSM        tsmRemoved = null;
            TheStorageEngineTSM        tsmMatch   = null;
            List <TheStorageEngineTSM> TSMs       = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM> myRecords  = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs and cache the middle one
            foreach (var payload in data)
            {
                tsmCurrent = new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString()
                };
                TSMs.Add(tsmCurrent);
                if ((indexCurrent++ >= indexMiddle) && (tsmMiddle == null))
                {
                    tsmMiddle = tsmCurrent;
                }
            }
            if (tsmMiddle == null)
            {
                Assert.Fail("Unable to cache the middle TSM!");
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();
            if (TSMs.Count != myRecords.Count)
            {
                Assert.Fail("Not all test records were not added successfully.");
            }

            #endregion

            #region ACT

            // Attempt to remove your middle item
            Task.Factory.StartNew(() =>
            {
                mirror.RemoveAnItemByKey(tsmMiddle.cdeMID.ToString(), payload =>
                {
                    tsmRemoved = payload;
                    gate.Set();
                });
            });

            // Wait for response
            gate.Reset();
            gate.Wait(30000);
            if (tsmRemoved == null)
            {
                Assert.Fail("Unable to remove item by ID!");
            }

            // Attempt to retrieve your middle item
            tsmMatch = mirror.GetEntryByID(tsmMiddle.cdeMID);

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsTrue(tsmMatch == null);

            #endregion
        }
        public void GetRecordsFromTheMirrorCache(
            [Values(0, 500, 5000)] int maxCount,
            [Values(50, 5000)] int totalCandidates
            )
        {
            #region ASSEMBLE
            bool entryNotFound             = false;
            var  random                    = new Random();
            var  data                      = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            List <TheStorageEngineTSM>           TSMs      = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM>           myRecords = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs
            var baseTime = DateTimeOffset.Now;
            int counter  = 0;
            foreach (var payload in data)
            {
                TSMs.Add(new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString(),
                    cdeCTIM    = baseTime.AddTicks(counter++),
                });
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };
            if (maxCount != 0)
            {
                mirror.SetMaxStoreSize(maxCount);
            }

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();

            Assert.AreEqual(totalCandidates, myRecords.Count, "Not all test records were added successfully.");

            #endregion

            #region ACT

            var expectedCount = maxCount == 0 ? totalCandidates : Math.Min(maxCount, totalCandidates);
            Assert.AreEqual(expectedCount, mirror.Count, "Not all test records were not added successfully.");

            // Retrieve your items...
            counter = 0;
            foreach (var tsm in TSMs)
            {
                TheStorageEngineTSM match = mirror.GetEntryByID(tsm.cdeMID);
                if (counter >= TSMs.Count - expectedCount)
                {
                    if (match == null)
                    {
                        entryNotFound = true;
                        break;
                    }
                }
                else
                {
                    if (match != null)
                    {
                        Assert.IsNull(match, "Item found that was supposed to have been removed due to max count limit", counter);
                    }
                }
                counter++;
            }

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsFalse(entryNotFound, "TheMirrorCache was missing one or more test entries!");

            #endregion
        }
Example #7
0
        internal static void InitAssets(TheBaseApplication pApp)
        {
            if (IsInitialized)
            {
                return;
            }
            IsInitialized = true;
            if (MyServiceHostInfo == null || !(MySecrets?.IsApplicationIDValid() == true))
            {
                MasterSwitch = false;
                return;
            }
            MyApplication = pApp;

            #region step 1: Moved from StartApplication to here as all the following code is updating TheBaseAssets
            //The following section are "app.config" only settings required before cdeTPI is loaded. These settings cannot be set via the Provisioning Service
            int delay = TheCommonUtils.CInt(MySettings.GetSetting("StartupDelay"));
            if (delay > 0)
            {
                TheCommonUtils.SleepOneEye((uint)(delay * 1000), 100);
            }

            string temp = MySettings.GetSetting("AllowEnvironmentVarsToOverrideConfig");
            if (!string.IsNullOrEmpty(temp))
            {
                MyServiceHostInfo.AllowEnvironmentVarsToOverrideConfig = TheCommonUtils.CBool(temp);
            }
            temp = MySettings.GetSetting("AllowEnvironmentVars");
            if (!string.IsNullOrEmpty(temp))
            {
                MyServiceHostInfo.AllowEnvironmentVars = TheCommonUtils.CBool(temp);
            }
            temp = MySettings.GetSetting("DEBUGLEVEL");
            if (!string.IsNullOrEmpty(temp))
            {
                MyServiceHostInfo.DebugLevel = (eDEBUG_LEVELS)TheCommonUtils.CInt(temp);
            }
            //Clouds have special behavior and the CDE needs to know this upfront
            temp = MySettings.GetSetting("IsCloudService");
            if (!string.IsNullOrEmpty(temp))
            {
                MyServiceHostInfo.IsCloudService = TheCommonUtils.CBool(temp);
            }
            temp = MySettings.GetSetting("ISOEN");
            if (!string.IsNullOrEmpty(temp))
            {
                MyServiceHostInfo.IsIsolated  = true;
                MyServiceHostInfo.IsoEngine   = temp;
                MyServiceHostInfo.cdeNodeType = cdeNodeType.Active;
            }
            else
            {
                temp = MySettings.GetSetting("UseRandomDeviceID");
                if (!string.IsNullOrEmpty(temp))
                {
                    MyServiceHostInfo.UseRandomDeviceID = TheCommonUtils.CBool(temp);
                }
            }

            //Step 2: Restore from backup if exists
#if CDE_NET45 // Backup/Restore only support on NET45
            // To ensure that restored backups are not overwritten during shutdown, we write them to a temp directory and move them into place on start up
            if (!MyServiceHostInfo.UseRandomDeviceID && !MyServiceHostInfo.IsIsolated)
            {
                string cacheParentPath = TheCommonUtils.GetCurrentAppDomainBaseDirWithTrailingSlash() + "ClientBin\\";
                if (Directory.Exists(cacheParentPath + "__CacheToRestore"))
                {
                    // Keep the old Cache around just in case
                    try
                    {
                        // First make space for the old copy, in case there was one already
                        if (Directory.Exists(cacheParentPath + "__CacheOld"))
                        {
                            Directory.Delete(cacheParentPath + "__CacheOld", true);
                        }
                    }
                    catch
                    {
                        //ignored
                    }
                    try
                    {
                        Directory.Move(cacheParentPath + "Cache", cacheParentPath + "__CacheOld");
                    }
                    catch
                    {
                        //ignored
                    }

                    // Now move the restored cache into place
                    try
                    {
                        Directory.Move(cacheParentPath + "__CacheToRestore", cacheParentPath + "Cache");
                    }
                    catch
                    {
                        TheSystemMessageLog.ToCo("Failure while restoring backup");
                    }
                }
            }
#endif

            MyServiceHostInfo.EnableTaskKPIs = TheCommonUtils.CBool(MySettings.GetSetting("EnableTaskKPIs"));
            if (MyServiceHostInfo.EnableTaskKPIs)
            {
                var taskKpiThread = new Thread(() =>
                {
                    do
                    {
                        var kpis = TheCommonUtils.GetTaskKpis(null);
                        TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: {TheCommonUtils.SerializeObjectToJSONString(kpis)}");
                        Thread.Sleep(1000); // Keeping it simple here, to minimize interference on task scheduler/thread scheduler etc. (Assumption: not used on production systems) // TheCommonUtils.SleepOneEye(1000, 1000);
                    } while (MasterSwitch && !Engines.TheCDEngines.IsHostReady && MyServiceHostInfo.EnableTaskKPIs);
                    TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: KPIs Handoff to NodeHost");
                });
                taskKpiThread.Start();
            }
            #endregion

            if (MyActivationManager == null)
            {
                MyActivationManager = new TheDefaultActivationManager(MySecrets, MySYSLOG);
            }


            #region step 3: analyse os environment information
            OperatingSystem os           = Environment.OSVersion;
            var             osInfoForLog = $"C-DEngine version: {BuildVersion} OS:{Environment.OSVersion} OS Version:{os.VersionString} OS Version Numbers: {os.Version.Major}.{os.Version.Minor}.{os.Version.Build}.{os.Version.Revision} Platform:{os.Platform} SP:{os.ServicePack} Processor Count: {Environment.ProcessorCount} IsMono:{(Type.GetType("Mono.Runtime") != null)} IsNetCore:{TheCommonUtils.IsNetCore()} Product: {TheCommonUtils.GetAssemblyProduct(typeof(TheBaseAssets))} ";
            TheSystemMessageLog.ToCo(osInfoForLog);
            MyServiceHostInfo.OSInfo = osInfoForLog;
            string dotNetInfoForLog = string.Empty;
#if !CDE_NET35 && !CDE_NET4
            try
            {
                string frameworkDescription = null;
                string osDescription        = null;
                string processArchitecture  = null;
                string osArchitecture       = null;

#if CDE_STANDARD
                frameworkDescription = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;
                osDescription        = System.Runtime.InteropServices.RuntimeInformation.OSDescription;
                processArchitecture  = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString();
                osArchitecture       = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString();
#else
                var rtInfoType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                if (rtInfoType != null)
                {
                    frameworkDescription = rtInfoType.GetProperty("FrameworkDescription").GetValue(null).ToString();
                    osDescription        = rtInfoType.GetProperty("OSDescription").GetValue(null).ToString();
                    processArchitecture  = rtInfoType.GetProperty("ProcessArchitecture").GetValue(null).ToString();
                    osArchitecture       = rtInfoType.GetProperty("OSArchitecture").GetValue(null).ToString();
                }
#endif
                if (!string.IsNullOrEmpty(frameworkDescription))
                {
                    dotNetInfoForLog = $"NetFrameWork:{frameworkDescription} Processor:{processArchitecture} OS:{osDescription } OS Arch:{osArchitecture}";
                    TheSystemMessageLog.ToCo(dotNetInfoForLog);
                    MyServiceHostInfo.OSInfo += $" {dotNetInfoForLog}";
                }
            }
            catch
            {
            }
#endif
            if (TheCommonUtils.IsMono()) // CODE REVIEW: Need to clean this up - do we mean Mono or Linux or case-insensitive file systems? CM: No- here we need this to find out if we are running in the MONO Runtime
            {
                MyServiceHostInfo.cdePlatform = cdePlatform.MONO_V3;
            }
            else
            {
#if CDE_NET35
                MyServiceHostInfo.cdePlatform = cdePlatform.X32_V3;
#elif CDE_NET4
                MyServiceHostInfo.cdePlatform = Environment.Is64BitProcess ? cdePlatform.NETV4_64 : cdePlatform.NETV4_32;
#elif CDE_STANDARD
                MyServiceHostInfo.cdePlatform = cdePlatform.NETSTD_V20;
#else
                MyServiceHostInfo.cdePlatform = TheCommonUtils.GetAssemblyPlatform(Assembly.GetEntryAssembly(), false, out var empty);// old: Environment.Is64BitProcess ? cdePlatform.X64_V3 : cdePlatform.X32_V4;
#endif
            }
            TheSystemMessageLog.ToCo("BaseDir: " + MyServiceHostInfo.BaseDirectory);
            #endregion

            #region step 4: Prepare essential Subsystems (Syslog, ScopeManager, Diagnostics, Caches, AppInfo)
            MySYSLOG = new TheSystemMessageLog(500); // No more ToCo after this point (will be ignored)
            TheCDEKPIs.Reset();

            MyServiceHostInfo.MiniHostInfo.MySYSLOG = MySYSLOG;
            MyServiceHostInfo.MiniHostInfo.MyKPIs   = new TheKPIs();
            if (MyScopeManager == null)
            {
                MyScopeManager = new TheDefaultScopeManager();
            }
            MyScopeManager.SetMiniHSI(MyServiceHostInfo.MiniHostInfo);
            MyScopeManager.RegisterScopeChanged(localEventScopeChanged);

            TheDiagnostics.InitDiagnostics();
            TheDiagnostics.SetThreadName("MAIN THREAD");
            TheQueuedSenderRegistry.Startup();

            MyBlobCache     = new TheMirrorCache <TheBlobData>(MyServiceHostInfo.TO.StorageCleanCycle);
            MyReceivedParts = new TheMirrorCache <TheReceivedParts>(MyServiceHostInfo.TO.StorageCleanCycle);
            //TODO: I hope there is a better way to do this for Metro!
            MyServiceTypes.Add(typeof(TheBaseAssets));

            MyServiceHostInfo.TO.MakeHeartNormal();

            MyAppInfo = new ThePluginInfo
            {
                cdeMID             = MyServiceHostInfo.cdeMID,
                CurrentVersion     = MyServiceHostInfo.CurrentVersion,
                Developer          = MyServiceHostInfo.VendorName,
                DeveloperUrl       = MyServiceHostInfo.VendorUrl,
                HomeUrl            = MyServiceHostInfo.SiteName,
                IconUrl            = MyServiceHostInfo.UPnPIcon,
                LongDescription    = MyServiceHostInfo.Description,
                Platform           = MyServiceHostInfo.cdePlatform,
                Copyrights         = MyServiceHostInfo.Copyrights,
                Price              = 0,
                ServiceDescription = MyServiceHostInfo.Title,
                ServiceName        = MyServiceHostInfo.ApplicationName,
                Capabilities       = new List <eThingCaps> {
                    eThingCaps.Host
                },
                Categories    = new List <string>(),
                FilesManifest = new List <string>()
            };
            if (MyServiceHostInfo.ManifestFiles != null)
            {
                MyAppInfo.FilesManifest.AddRange(MyServiceHostInfo.ManifestFiles);
            }
            #endregion

            //Now load provisioning and local settings then parse them
#pragma warning disable CS0618 // Type or member is obsolete - its allowed here
            if (!TheCDESettings.ParseSettings(MyCmdArgs, true, false))
#pragma warning restore CS0618 // Type or member is obsolete
            {
                MasterSwitch = false;
                return;
            }

            if (MyCodeSigner == null)
            {
                MyCodeSigner = new TheDefaultCodeSigning(MySecrets, MySYSLOG);
            }
            string tBaseDir = MyServiceHostInfo.BaseDirectory;
            if (MyServiceHostInfo.cdeHostingType == cdeHostType.IIS)
            {
                tBaseDir += "bin\\";
            }
            string uDir = tBaseDir;
            if (!string.IsNullOrEmpty(MyServiceHostInfo.ISMMainExecutable))
            {
                uDir += MyServiceHostInfo.ISMMainExecutable;
                if (MyServiceHostInfo.cdeHostingType != cdeHostType.IIS)
                {
                    var hostPath = uDir + ".exe";
                    if (!File.Exists(hostPath))
                    {
                        // We may be running under .Net Core with a .dll-based host
                        hostPath = uDir + ".dll";
                    }
                    uDir = hostPath;
                }
            }
            else
            {
                uDir += "C-DEngine.dll";
            }
            MyServiceHostInfo.CodeSignThumb = MyCodeSigner.GetAppCert(MyServiceHostInfo.DontVerifyTrust, uDir, MyServiceHostInfo.VerifyTrustPath, MyServiceHostInfo.DontVerifyIntegrity);  //Must be loaded here to set trust level in HSI

            if (MyLoc as TheDefaultLocalizationUtils != null)
            {
                (MyLoc as TheDefaultLocalizationUtils).DoPseudoLoc = TheCommonUtils.CBool(MySettings.GetSetting("DoPseudoLoc"));
            }

            #region step 5: output some system information
            if (MyServiceHostInfo.IsMemoryOptimized)
            {
                MySYSLOG.SetMaxLogEntries(10);
            }
            MySYSLOG.WriteToLog(4151, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", osInfoForLog, eMsgLevel.l4_Message));

            if (!string.IsNullOrEmpty(dotNetInfoForLog))
            {
                MySYSLOG.WriteToLog(4152, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", dotNetInfoForLog, eMsgLevel.l4_Message));
            }
            MySYSLOG.WriteToLog(4153, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheBaseAssets", "BaseDir: " + MyServiceHostInfo.BaseDirectory, eMsgLevel.l4_Message));
            #endregion

            #region step 6: determine WebSocket8 vs. WebSocketsSharp
            var ws8FlagTemp = MySettings.GetSetting("DisallowWebSocket8");
            if (!string.IsNullOrEmpty(ws8FlagTemp))
            {
                MyServiceHostInfo.IsWebSocket8Active = !TheCommonUtils.CBool(ws8FlagTemp);
                MySYSLOG.WriteToLog(4154, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"Setting IsWebSocket8Active to {MyServiceHostInfo.IsWebSocket8Active} due to config", eMsgLevel.l4_Message));
            }
            else
            {
                MyServiceHostInfo.IsWebSocket8Active = true;
            }
            if ((os.Platform != PlatformID.Win32NT && !TheCommonUtils.IsNetCore()) || (os.Platform == PlatformID.Win32NT && (os.Version.Major < 6 || (os.Version.Major == 6 && os.Version.Minor < 2))))
            {
                MyServiceHostInfo.IsWebSocket8Active = false;
                string tWSMsg = "Older Windows or non-Windows OS Detected - No OS Support for WebSockets Found: ";
#if !CDE_USECSWS //OK
                TheBaseAssets.MyServiceHostInfo.DisableWebSockets = true;
                tWSMsg += "WebSockets are turned Off";
#else
                tWSMsg += "Switching to WebSockets-Sharp";
#endif
                MySYSLOG.WriteToLog(4155, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", tWSMsg, eMsgLevel.l4_Message));
            }
            #endregion

            #region step 7: Initialize Localization subsystem (ILocalizationHooks)
            bool bLocInitialized = false;
            try
            {
                var entryAssembly = Assembly.GetEntryAssembly();    //This does not work in IIS!
                if (entryAssembly != null)
                {
                    var CDEPlugins = from t in entryAssembly.GetTypes()
                                     let ifs = t.GetInterfaces()
                                               where ifs != null && ifs.Length > 0 && (ifs.Contains(typeof(ILocalizationHooks)))
                                               select new { Type = t, t.Namespace, t.Name, t.FullName };
                    if (CDEPlugins != null && CDEPlugins.Any())
                    {
                        MyLoc = Activator.CreateInstance(CDEPlugins.First().Type) as ILocalizationHooks;
                    }
                    bLocInitialized = true;
                }
            }
            catch
            {
            }
            if (!bLocInitialized)
            {
                MySYSLOG.WriteToLog(4156, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", "3rd Party ILocalization Hooks not found - using built-in", eMsgLevel.l4_Message));
            }
            #endregion

            #region step 8: Set MyStationUrl
            switch (MyServiceHostInfo.cdeHostingType)
            {
            case cdeHostType.Phone:
            case cdeHostType.Metro:
                MyServiceHostInfo.MyDeviceMoniker = "CDEV://";
                break;

            case cdeHostType.Silverlight:
                MyServiceHostInfo.MyDeviceMoniker = "CDES://";
                break;

            case cdeHostType.Device:
                MyServiceHostInfo.MyDeviceMoniker = "CDEC://";
                break;

            case cdeHostType.Mini:
                MyServiceHostInfo.MyDeviceMoniker = "CDEM://";
                break;

            default:     //Services
                MyServiceHostInfo.MyDeviceMoniker = "CDEB://";
                break;
            }
            if (TheCommonUtils.IsHostADevice())
            {
                MyServiceHostInfo.MyStationURL = MyServiceHostInfo.MyDeviceMoniker + "{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}".ToUpper(); //MSU-OK
            }
            else
            {
                if (MyServiceHostInfo.MyAltStationURLs.Count(s => s.StartsWith("CDEB")) == 0)
                {
                    MyServiceHostInfo.MyAltStationURLs.Add("CDEB://{" + MyServiceHostInfo.MyDeviceInfo.DeviceID + "}"); //TODO: Backchannel Possibly save to Config File
                }
            }
            #endregion

            #region step 9: Start Localhost QSender and SessionStateManager
            MySession        = new TheSessionStateManager(MyServiceHostInfo);
            LocalHostQSender = new TheQueuedSender();                                                                                                                                                                                 //NO connected or Error Event necessary
            LocalHostQSender.StartSender(new TheChannelInfo(MyServiceHostInfo.MyDeviceInfo.DeviceID, MyScopeManager.ScopeID, MyServiceHostInfo.MyDeviceInfo.SenderType, MyServiceHostInfo.GetPrimaryStationURL(false)), null, false); //NEW:2.06 Setting Realscope here ///null correct - no subs on LocalhostQS in beginning //RScope-OK
            if ((MyServiceHostInfo.DisableWebSockets || MyServiceHostInfo.MyStationWSPort == 0) && !TheCommonUtils.IsHostADevice())
            {
                MySYSLOG.WriteToLog(4157, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseAssets", $"WebSockets Disabled - no WSPort specified {MyServiceHostInfo.MyStationWSPort} or DisableWebSocket={MyServiceHostInfo.DisableWebSockets}", eMsgLevel.l4_Message));
            }
            #endregion

            // Post Device ID settings

            //Step 10: Save all settings to local cdeTPI
            MySettings.UpdateLocalSettings();
        }