Example #1
0
        public MainWindow()
        {
            InitializeComponent();

            // Start the CDEngine communication channels
            StartCDEngineHost();

            TheBaseEngine.WaitForEnginesStartedAsync().ContinueWith(t =>
            {
                try
                {
                    // Express our interest in the EngineName used for the chat, so that a subscription to the cloud is established even though the engine has not matching plug-in on this node
                    TheCDEngines.RegisterNewMiniRelay(strChatEngine);

                    // Intercept any messages sent to the chat engine
                    var chatEngine = TheThingRegistry.GetBaseEngine(strChatEngine);
                    chatEngine.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);

                    // Intercept any messages sent to the ContentService (we will use that as the originating thing, and acknowledge messages will come back to it)
                    TheThingRegistry.GetBaseEngineAsThing(eEngineName.ThingService).RegisterEvent(eThingEvents.IncomingMessage, HandleMessage);
                }
                catch
                {
                }
            });
        }
        private static IServiceCollection AddCdePubSubServices(this IServiceCollection collection)
        {
            collection.AddSingleton(sp =>
            {
                sp.UseCde();
                var engines = TheThingRegistry.GetBaseEngines(false);
                var engine  = engines.FirstOrDefault(e => e.GetEngineName() == InfrastructureEngine);
                if (engine != null)
                {
                    return(engine.GetBaseThing());
                }

                if (!TheCDEngines.RegisterNewMiniRelay(InfrastructureEngine))
                {
                    throw new InvalidOperationException("Failed to register CDE infrastructure engine");
                }

                engine = TheThingRegistry.GetBaseEngine(InfrastructureEngine, false);
                return(engine.GetBaseThing());
            });

            collection.AddSingleton(sp => new Publisher(Operator.GetLine(sp.GetRequiredService <TheThing>())).ConnectAsync().Result as Publisher)
            .AddSingleton(sp => sp.GetRequiredService <Publisher>() as IPublisher);
            collection.AddSingleton(sp => new Subscriber(Operator.GetLine(sp.GetRequiredService <TheThing>()), sp.GetRequiredService <Publisher>()))
            .AddSingleton(sp => sp.GetRequiredService <Subscriber>() as ISubscriber);

            return(collection);
        }
Example #3
0
 internal void InterceptRSSEvtRequest(TheRequestData pRequest)
 {
     if (pRequest == null)
     {
         return;
     }
     try
     {
         TheStorageMirror <TheEventLogData> tEventLog = TheCDEngines.GetStorageMirror("EventLog") as TheStorageMirror <TheEventLogData>;
         if (tEventLog != null)
         {
             CreateEvtLogFeed(pRequest, tEventLog?.TheValues.OrderByDescending(s => s.cdeCTIM).ThenByDescending(s => s.cdeCTIM.Millisecond).ToList(), 200);
         }
         else
         {
             TheRSSGenerator.CreateRSS(pRequest, new List <TheEventLogData>()
             {
                 new TheEventLogData()
                 {
                     EventName = "No Eventlog on this Node"
                 }
             }, 1);
         }
     }
     catch
     {
         //ignored
     }
 }
Example #4
0
        async void sinkReady()
        {
            TheCDEngines.RegisterNewMiniRelay("CHATSTER");
            var tThing = TheThingRegistry.GetBaseEngine("CHATSTER");

            tThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessageAsync);
            await UpdateLog("SYSTEM: Connected to Cloud");
        }
 /// <summary>
 /// Add the current station DeviceID to the list of Originators
 /// </summary>
 public bool AddHopToOrigin()
 {
     if (!DoesORGContain(TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID))
     {
         if (string.IsNullOrEmpty(ORG))
         {
             ORG = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString();
         }
         else
         {
             ORG += ";" + TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString();
         }
         if (TheBaseAssets.MyServiceHostInfo.EnableCosting)
         {
             TheCDEngines.updateCosting(this);
         }
         return(true);
     }
     return(false);
 }
Example #6
0
        public static void CreateSysLogFeed(TheRequestData pRequest, int MaxCnt)
        {
            if (pRequest.RequestUri != null && !string.IsNullOrEmpty(pRequest.RequestUri.Query) && pRequest.RequestUri.Query.Length > 1)
            {
                var QParts = TheCommonUtils.ParseQueryString(pRequest.RequestUri.Query); //.Split('=');
                //if (QParts.ContainsKey("SID") && (!TheScopeManager.IsValidScopeID(TheScopeManager.GetScrambledScopeIDFromEasyID(QParts["SID"])) || QParts.ContainsKey("NID")))
                //{
                //    pRequest.SessionState.SScopeID = TheScopeManager.GetScrambledScopeIDFromEasyID(QParts["SID"]);
                //    Guid tTarget = Guid.Empty;
                //    if (QParts.ContainsKey("NID"))
                //        tTarget = TheCommonUtils.CGuid(QParts["NID"]);
                //    Communication.HttpService.TheHttpService.cdeStreamFile(pRequest, true, 10, tTarget);
                //    if (pRequest.ResponseBuffer == null)
                //        TheRSSGenerator.CreateRSS(pRequest, new List<TheEventLogData>() { new TheEventLogData() { EventName = "Relay did not answer" } }, 1);
                //    return;
                //}
            }
            TheStorageMirror <TheEventLogEntry> tEventLog = TheCDEngines.GetStorageMirror($"{typeof(TheEventLogEntry)}") as TheStorageMirror <TheEventLogEntry>;

            TheRSSGenerator.CreateRSS(pRequest, tEventLog.TheValues.OrderByDescending(s => s.cdeCTIM).ThenByDescending(s => s.cdeCTIM.Millisecond).ToList(), MaxCnt);
        }
Example #7
0
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main thread";  // Helps Debugging

            //SDK Non-Commercial ID. FOR COMMERCIAL APP GET THIS ID FROM C-LABS!
            TheScopeManager.SetApplicationID("/cVjzPfjlO;{@QMj:jWpW]HKKEmed[llSlNUAtoE`]G?");

            //
            //  Establish service parameters
            //
            TheBaseAssets.MyServiceHostInfo = new TheServiceHostInfo(cdeHostType.Application)
            {
                // TODO: Generate host service unique ID
                cdeMID = TheCommonUtils.CGuid("{65CB9142-7D26-40E4-AE54-3E4DD75B3760}"),

                // TCP/IP Port Assignments
                MyStationPort = 8720,                     // Port for REST access to this node.
                                                          // If your PC already uses port 80 for another webserver, change this port.
                                                          // We recommend using Port 8700 and higher for UPnP to work properly.

                MyStationWSPort = 8721,                   // Enables WebSockets on the station port.
                                                          // If UseRandomDeviceID is false, this Value cannot be changed here once the
                                                          // app runs for the first time.
                                                          // On Windows 8 and later, MyStationPort and MyStationWSPort
                                                          // can be the same port if running as Administrator.

                ISMMainExecutable = "MyTestHost2",        // Name of the executable (without .exe)
                ApplicationName   = "My-Relay",           // Friendly Name of Application
                Title             = "My-Relay (C) 2020 ", // Title of this Host Service
                ApplicationTitle  = "My-Relay Portal",    // Title visible in the NMI Portal

                SiteName = "http://cloud.c-labs.com",     // Link to the main Cloud Node of this host.
                                                          // Not required, for documentation only

                CurrentVersion = 1.0001,                  // Service version of this Service.
                                                          // Increase when you publish a new version so the
                                                          // online store can display the correct update icon
                DebugLevel   = eDEBUG_LEVELS.OFF,         // Define a DebugLevel for the SystemLog output.
                ServiceRoute = "wss://cloud.c-labs.com",  // Points at the cloud
            };

            // Generate random Scope ID every time we run.
            strScope = TheScopeManager.GenerateNewScopeID();   // TIP: instead of creating a new random ID every
                                                               // time your host starts, you can put a breakpoint in the
                                                               // next line, record the ID and feed it in the "SetScopeIDFromEasyID".
                                                               // Or even set a fixed ScopeID here. (FOR TESTING ONLY!!)

            TheScopeManager.SetScopeIDFromEasyID("1234");      // Set a ScopeID - the security context of this node.
                                                               // Replace strScope with any random 8 characters or numbers

            //
            // Create dictionary to hold configuration settings.
            //
            #region Args Parsing
            ArgList = new Dictionary <string, string>();
            for (int i = 0; i < args.Length; i++)
            {
                string[] tArgs = args[i].Split('=');
                if (tArgs.Length == 2)
                {
                    string key = tArgs[0].ToUpper();
                    ArgList[key] = tArgs[1];
                }
            }
            #endregion

            ArgList["DontVerifyTrust"] = "True";       // When "false", all plugins have to be signed with the
                                                       // same certificate as the host application or C-DEngine.DLL.
                                                       // When "true", ignore code signing security check (dev only!)

            ArgList["UseRandomDeviceID"] = "True";     // When "true", assigns a new device ID everytime
                                                       // the host starts. No configuration data retained on disk.
                                                       // When "false", enables persistence between system starts

            ArgList["ScopeUserLevel"] = "255";         // Set the Scope Access Level

            // Create a new Base (C-DEngine IoT) Application
            MyBaseApplication = new TheBaseApplication();

            // Start the C-DEngine Host Application.
            // If a PluginService class is added DIRECTLY to the host project you can
            // instantiate the Service here. Replace null with "new cdePluginService1()"
            if (!MyBaseApplication.StartBaseApplication(null, ArgList))
            {
                // If the Application fails to start, quit the app.
                // StartBaseApplication returns very fast because all
                // C-DEngine code is running asynchronously
                return;
            }

            // (Optional) Whether to use Universal Plug
            // and Play (UPnP) to find devices.
            // MyBaseApplication.MyCommonDisco.RegisterUPnPUID("*", null);

            // Set up URL for our node.
            string strStationURL = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false);
            strStationURL = String.Format("{0}/lnmi", strStationURL);

            // Set up messaging (for basic sample)
            TheCDEngines.RegisterPubSubTopic("MyTestEngine");                    // The engine for MyTestHost
            IBaseEngine eng = TheCDEngines.RegisterPubSubTopic("MyTestEngine2"); // The engine for THIS host
            eng.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);

            #region Waiting for ESC Key pressed
            try
            {
                // User input loop
                while (true)
                {
                    Console.WriteLine("\r\nStation URL: " + strStationURL);
                    Console.WriteLine("\r\nScope ID: " + strScope);
                    Console.WriteLine("\r\n[Esc] key to quit. 'B' (or 'b') to launch browser");

                    // Loop until (1) C-DEngine master switch, or (2) Keyboard input
                    while (TheBaseAssets.MasterSwitch && Console.KeyAvailable == false) // Console.KeyAvailable throws exception in Docker
                    {
                        Thread.Sleep(250);
                    }

                    // Check C-DEngine master switch.
                    if (!TheBaseAssets.MasterSwitch)
                    {
                        // Exit user input loop.
                        break;
                    }

                    ConsoleKeyInfo key = Console.ReadKey();
                    if (key.Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                    if (key.KeyChar == 'b' || key.KeyChar == 'B')
                    {
                        try
                        {
                            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                strStationURL = strStationURL.Replace("&", "^&");
                                Process.Start(new ProcessStartInfo("cmd.exe", $"/c start {strStationURL}")
                                {
                                    CreateNoWindow = true
                                });
                            }
                            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                            {
                                System.Diagnostics.Process.Start("xdg-open", strStationURL);
                            }
                            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                            {
                                System.Diagnostics.Process.Start("open", strStationURL);
                            }
                            else
                            {
                                Console.WriteLine($"Error launching browser for URL {strStationURL}");
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"Error launching browser for URL {strStationURL}");
                            Console.WriteLine($"Exception details: {e.ToString()}");
                        }
                    }
                } // while (true)
            }
            catch (InvalidOperationException)
            {
                TheBaseAssets.MasterSwitchCancelationToken.WaitHandle.WaitOne();
            }

            MyBaseApplication.Shutdown(true);
            #endregion
        }
        /// <summary>
        /// Processes incoming Messages
        /// If a Batch comes in, only the first message must have a valid NPA Path
        /// </summary>
        internal static void ProcessClientDeviceMessage(TheQueuedSender MyQSender, TheRequestData pRequestData, List <TheDeviceMessage> tDevList)
        {
            var toRemove = new List <TheDeviceMessage>();

            foreach (TheDeviceMessage tDev in tDevList)
            {
                if (string.IsNullOrEmpty(tDev.NPA))
                {
                    return; // CODE REVIEW: Really stop processing all subsequent TDMs here (malformed TDM -> security)?
                }
                string NPA = tDev.NPA.Substring(4);
                if (NPA.EndsWith(".ashx", StringComparison.OrdinalIgnoreCase))
                {
                    NPA = NPA.Substring(0, NPA.Length - 5);
                }
                if (TheBaseAssets.MyScopeManager.ParseISBPath(NPA, out Guid? ttSessionID, out cdeSenderType tSenderType, out long tFID, out string tVersion))
                {
                    Guid tSessionID = TheCommonUtils.CGuid(ttSessionID);
                    Guid tDeviceID  = TheCommonUtils.CGuid(tDev.DID);
                    lock (TheBaseAssets.MySession.GetLock())    //CODE-REVIEW: VERY expensive lock! Really necessary?
                    {
                        var myTargetNodeChannel = MyQSender.MyTargetNodeChannel;
                        if (MyQSender.IsConnected && myTargetNodeChannel.MySessionState != null) //!=null new in 3.2
                        {
                            if (!tSessionID.Equals(myTargetNodeChannel.MySessionState.cdeMID))
                            {
                                Guid tOldID = myTargetNodeChannel.MySessionState.cdeMID;
                                myTargetNodeChannel.MySessionState = TheBaseAssets.MySession.ValidateSEID(tSessionID);    //Measure Frequency
                                if (myTargetNodeChannel.MySessionState == null)
                                {
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", $"No exiting session for remote node found. Using new session (possible reason: fast cloud reconnect) ...new: {tSessionID} old: {tOldID}", eMsgLevel.l2_Warning), true);
                                    myTargetNodeChannel.MySessionState = pRequestData.SessionState;
                                }
                                else
                                {
                                    TheBaseAssets.MySession.RemoveSessionByID(tOldID);
                                }
                            }
                        }
                        if (tDeviceID != Guid.Empty && tDeviceID != myTargetNodeChannel.cdeMID)
                        {
                            if (myTargetNodeChannel.SenderType == cdeSenderType.CDE_CUSTOMISB)
                            {
                                if (myTargetNodeChannel.TruDID != tDeviceID)
                                {
                                    myTargetNodeChannel.TruDID = tDeviceID;
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"Custom ISB sets TruDID to: {TheCommonUtils.GetDeviceIDML(tDeviceID)} for MTNC: {myTargetNodeChannel.ToMLString()}", eMsgLevel.l4_Message), true);
                                }
                            }
                            else
                            {
                                TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"Different DeviceIDs received ...new: {TheCommonUtils.GetDeviceIDML(tDeviceID)} old: {TheCommonUtils.GetDeviceIDML(myTargetNodeChannel.cdeMID)} {(myTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE ? "For CloudRoute and Service normal" : "")}", eMsgLevel.l2_Warning), true);
                                TheBaseAssets.MySession.RemoveSessionsByDeviceID(myTargetNodeChannel.cdeMID, Guid.Empty);
                                TheQueuedSenderRegistry.UpdateQSenderID(myTargetNodeChannel.cdeMID, tDeviceID);
                                myTargetNodeChannel.cdeMID = tDeviceID;
                                if (pRequestData.DeviceID != tDeviceID)
                                {
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Different DeviceIDs in DID and Request ...DID: {TheCommonUtils.GetDeviceIDML(tDeviceID)} Request: {TheCommonUtils.GetDeviceIDML(myTargetNodeChannel.cdeMID)}", eMsgLevel.l2_Warning), true);
                                    pRequestData.DeviceID = tDeviceID;
                                }
                                switch (pRequestData.ResponseMimeType)
                                {
                                case "cde/mini":
                                    myTargetNodeChannel.SenderType = cdeSenderType.CDE_MINI;
                                    break;
                                }
                            }
                        }
                        if (myTargetNodeChannel.MySessionState == null)
                        {
                            myTargetNodeChannel.MySessionState = TheBaseAssets.MySession.GetOrCreateSessionState(tSessionID, pRequestData);
                        }
                        myTargetNodeChannel.MySessionState.SiteVersion = tVersion;
                        myTargetNodeChannel.MySessionState.cdeMID      = tSessionID;
                        myTargetNodeChannel.MySessionState.CurrentURL  = myTargetNodeChannel.TargetUrl;
                        // Keep the RSA public key of the other party, so we can use it to encrypt data when sending to that party in the future
                        if (!String.IsNullOrEmpty(tDev.RSA))
                        {
                            myTargetNodeChannel.MySessionState.RSAPublicSend = tDev.RSA;
                        }
                        if (MyQSender.IsConnecting && !MyQSender.IsConnected)
                        {
                            MyQSender.IsConnected = true;
                            if (myTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE)
                            {
                                if (TheBaseAssets.MyServiceHostInfo.IsIsolated && TheBaseAssets.MyServiceHostInfo.MasterNode == Guid.Empty)
                                {
                                    TheBaseAssets.MyServiceHostInfo.MasterNode = myTargetNodeChannel.cdeMID;
                                    TheQueuedSenderRegistry.SendMasterNodeQueue();
                                }
                                MyQSender.StartHeartBeat();
                                TheBaseAssets.MySYSLOG.WriteToLog(23055, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", $"Cloud Route is back up to {myTargetNodeChannel.ToMLString()}", eMsgLevel.l4_Message));
                                if (TheQueuedSenderRegistry.eventCloudIsBackUp != null)
                                {
                                    TheCommonUtils.cdeRunAsync("QS-StartEngineNU", true, o =>
                                    {
                                        TheQueuedSenderRegistry.eventCloudIsBackUp(TheCDEngines.MyContentEngine, myTargetNodeChannel);
                                    });
                                }
                            }
                            if (MyQSender.eventConnected != null)
                            {
                                TheCommonUtils.cdeRunAsync("QueueConnected", true, (p) => { MyQSender.eventConnected(MyQSender, myTargetNodeChannel); });
                            }
                            MyQSender.MyISBlock?.FireEvent("Connected");
                        }
                        pRequestData.SessionState = myTargetNodeChannel.MySessionState;
                        MyQSender?.SetLastHeartbeat(myTargetNodeChannel.MySessionState);
                    }
                    if (!string.IsNullOrEmpty(tDev.TOP) && tDev.TOP.StartsWith("CDE_CONNECT"))
                    {
                        string[] tP = TheCommonUtils.cdeSplit(tDev.TOP, ";:;", true, true);
                        if (tP.Length > 1)
                        {
                            string tEngs = tP[1];
                            TheCommonUtils.cdeRunAsync("QS-StartEngineNU", false, o =>
                            {
                                TheCDEngines.StartEngineWithNewUrl(MyQSender?.MyTargetNodeChannel, tEngs);
                            });
                        }
                        if (tDevList.Count > 1)
                        {
                            if (toRemove == null)
                            {
                                toRemove = new List <TheDeviceMessage>();
                            }
                            toRemove.Add(tDev);
                            continue;
                        }
                        else
                        {
                            return;
                        }
                    }
                    if (string.IsNullOrEmpty(tDev.TOP) || tDev.TOP.StartsWith("CDE_PICKUP") || tDev.TOP.StartsWith("CDE_WSINIT"))
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(23056, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Heartbeat received {MyQSender?.MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l4_Message));
                        if (tDevList.Count > 1)
                        {
                            if (toRemove == null)
                            {
                                toRemove = new List <TheDeviceMessage>();
                            }
                            toRemove.Add(tDev);
                            continue;
                        }
                        else
                        {
                            return;
                        }
                    }
                    break; //Found valid path and can go out
                }
            }
            if (toRemove != null)
            {
                foreach (var tDev in toRemove)
                {
                    tDevList.Remove(tDev);
                }
            }
            TheCommonUtils.cdeRunAsync("QS-UpCo2Exec", false, o =>
            {
                pRequestData.ResponseBuffer = null;
                DoExecuteCommand(null, MyQSender, false, pRequestData, tDevList);
            }, tDevList);
        }
Example #9
0
 public override bool Init()
 {
     TT.SetSafePropertyNumber(MyBaseThing, "ManufacturingCarbonFootprint", 0.001); //1KG if not specified
     TheCDEngines.RegisterNewMiniRelay("EnergyMessages");
     return(base.Init());
 }
Example #10
0
        private IEnumerable <TheThing> GetMatchingThings(Subscription subscription)
        {
            var things = new List <TheThing>();

            if (_thingReference.ThingMID.HasValue && _thingReference.ThingMID != Guid.Empty)
            {
                var thing = TheThingRegistry.GetThingByMID(_thingReference.ThingMID.Value, true);
                if (thing != null)
                {
                    things.Add(thing);
                }
                return(things);
            }

            IBaseEngine     baseEngine     = null;
            List <TheThing> matchingThings = null;

            if (!string.IsNullOrEmpty(_thingReference.EngineName))
            {
                baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName);
                if (baseEngine == null)
                {
                    TheCDEngines.RegisterNewMiniRelay(_thingReference.EngineName);
                    baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName);
                }
                if (baseEngine != null)
                {
                    subscription?.AddSubscription(baseEngine, this);
                    matchingThings = TheThingRegistry.GetThingsOfEngine(_thingReference.EngineName, true, true);
                }
            }
            else
            {
                object deviceTypeObj = null;
                if (_thingReference.PropertiesToMatch?.TryGetValue("DeviceType", out deviceTypeObj) == true)
                {
                    var deviceType = TheCommonUtils.CStr(deviceTypeObj);
                    if (!string.IsNullOrEmpty(deviceType))
                    {
                        matchingThings = TheThingRegistry.GetThingsByFunc("*", t => t.DeviceType.Equals(deviceType, StringComparison.Ordinal), true);
                    }
                }
            }

            if (matchingThings != null)
            {
                foreach (var thing in matchingThings)
                {
                    if (Matches(thing))
                    {
                        if (baseEngine == null)
                        {
                            subscription?.AddSubscription(thing.GetBaseEngine(), this);
                        }
                        things.Add(thing);
                    }
                }
            }

            return(things);
        }
Example #11
0
        /// <summary>
        /// Shutsdown the C-DEngine and all plugins
        /// Applications can override this function to add custom shutdown code
        /// </summary>
        /// <param name="ForceExit">If True and the C-DEngine will Stop or restart the hosting application. If it is hosted in IIS, the Application Pool hosting the app will be Stopped or Restarted depending on the next parameter</param>
        /// <param name="waitIfPending">Waits in case The shutdown is already initiated</param>
        public virtual void Shutdown(bool ForceExit, bool waitIfPending = false)
        {
            if (!waitIfPending)
            {
                if (!TheBaseAssets.MasterSwitch || TheCommonUtils.cdeIsLocked(ShutdownLock))
                {
                    return;                                                                                                            //Make sure we dont do this twice
                }
            }
            lock (ShutdownLock)
            {
                if (TheBaseAssets.MasterSwitch)
                {
                    if (TheBaseAssets.IsStarting)
                    {
                        TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished. Waiting for startup to finish.", eMsgLevel.l3_ImportantMessage));
                        // Ensure we wait for user manager so CUOFS first-run-only settings are applied
                        var sw = System.Diagnostics.Stopwatch.StartNew();
                        while (TheBaseAssets.IsStarting && sw.ElapsedMilliseconds < 60000)
                        {
                            Thread.Sleep(100);
                        }
                        if (TheBaseAssets.IsStarting)
                        {
                            TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished after wait time (60 seconds). Shutting down regardless. Some first-run-only settings may not have been applied.", eMsgLevel.l1_Error));
                        }
                    }
                    if (TheBaseAssets.MyServiceHostInfo.PreShutDownDelay > 0)
                    {
                        var tcsPreHandlers = new TaskCompletionSource <bool>();
                        TheCommonUtils.cdeRunAsync("PreShutdownHandlers", true, (o) =>
                        {
                            TheCDEngines.MyContentEngine?.FireEvent(eEngineEvents.PreShutdown, null, TheBaseAssets.MyServiceHostInfo.PreShutDownDelay, false);
                            tcsPreHandlers.TrySetResult(true);
                        });
                        tcsPreHandlers.Task.Wait(TheBaseAssets.MyServiceHostInfo.PreShutDownDelay);
                    }
                    while (Interlocked.Read(ref TheBaseAssets.DelayShutDownCount) > 0)
                    {
                        TheCommonUtils.SleepOneEye(100, 100);
                    }
                    TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Initiating shutdown at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug));
                    TheBaseAssets.MasterSwitch  = false;
                    TheBaseAssets.ForceShutdown = ForceExit;
                    TheCDEngines.StopAllEngines();
                    TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Engines stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug));

                    TheCommCore.StopCommunication();
                    TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Communications stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug));
                    if (MyCommonDisco != null)
                    {
                        MyCommonDisco.ShutdownDiscoService();
                        TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Discovery Service stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug));
                    }
                    if (TheBaseAssets.MySYSLOG != null)
                    {
                        string iis = "";
                        switch (TheBaseAssets.MyServiceHostInfo.cdeHostingType)
                        {
                        case cdeHostType.IIS: iis = " (Hosted in IIS)"; break;

                        case cdeHostType.ASPCore: iis = " (Hosted in ASP.NET Core)"; break;
                        }
                        TheBaseAssets.MySYSLOG.WriteToLog(3, new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + iis + " Stopped at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l4_Message)); //Log Entry that service has been started
                        TheBaseAssets.MySYSLOG.Shutdown();
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// Override to initalize the app with custom values but still call the base!
        /// </summary>
        /// <param name="pPlugInLst">List if ICDEPlugin instances</param>
        /// <param name="ArgList">Additional Parameters of the Application</param>
        /// <returns>True if all went well during startup</returns>
        public virtual bool StartBaseApplication2(List <ICDEPlugin> pPlugInLst, IDictionary <string, string> ArgList)
        {
            if (TheBaseAssets.MasterSwitch)
            {
                return(false);                              //SECURITY REVIEW: do not allow to call StartBaseApplication twice
            }
            TheBaseAssets.MasterSwitch = true;
            if (TheBaseAssets.MyServiceHostInfo == null)
            {
                TheBaseAssets.MasterSwitch = false;
                TheSystemMessageLog.ToCo("MyServiceHostInfo is not set! Exiting...");   //Will becalled because if MyServiceHostInfo==null TOCO will be called
                return(false);
            }
            if (TheBaseAssets.CryptoLoadMessage != null)
            {
                TheBaseAssets.MasterSwitch = false;
                TheSystemMessageLog.ToCo($"Security initialization failed with {TheBaseAssets.CryptoLoadMessage}. Exiting...");
                return(false);
            }
            try
            {
                TheBaseAssets.IsStarting = true;

                //AppDomain.CurrentDomain.UnhandledException += MyUnhandledExceptionHandler;

                if (ArgList == null)
                {
                    ArgList = new Dictionary <string, string>();    //DIC-Allowed!
                }
                if (!TheBaseAssets.MySettings.ReadAllAppSettings(ref ArgList))
                {
                    TheSystemMessageLog.ToCo("Not reading app.config: not supported by platform."); //Will never be called!
                }
                if (!TheBaseAssets.MasterSwitch)
                {
                    return(false);
                }
                TheBaseAssets.MyCmdArgs = ArgList; //MyCmdArgs ONLY contains "public" settings coming from app.config or via the host

                MyUserManager = new TheUserManager();
                TheBaseAssets.InitAssets(this);
                if (!TheBaseAssets.MasterSwitch)
                {
                    return(false);
                }
                TheBaseAssets.MyScopeManager.RegisterScopeChanged(EventScopeChanged);
                TheBaseAssets.MySYSLOG.WriteToLog(4140, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Assets and SystemLog Initialized", eMsgLevel.l3_ImportantMessage));

                int minWorker = -1, minCompletionPort = -1, maxWorker = -1, maxCompletionPort = -1;
                try
                {
                    System.Threading.ThreadPool.GetMinThreads(out minWorker, out minCompletionPort);
                    System.Threading.ThreadPool.GetMaxThreads(out maxWorker, out maxCompletionPort);
                }
                catch { };

#if CDE_STANDARD
                var largeObjectHeapCompactionMode = System.Runtime.GCSettings.LargeObjectHeapCompactionMode;
#else
                const string largeObjectHeapCompactionMode = "n/a";
#endif
                TheBaseAssets.MySYSLOG.WriteToLog(4144, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(eEngineName.ContentService, $"CLR Info", eMsgLevel.l4_Message, $"Server GC: {System.Runtime.GCSettings.IsServerGC}. GC Latency Mode: {System.Runtime.GCSettings.LatencyMode}. LOHC Mode: {largeObjectHeapCompactionMode}. Bitness: {System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) * 8}. Threads Min W/CP, Max W/CP: {minWorker}/{minCompletionPort},{maxWorker}/{maxCompletionPort}. GC TotalMemory: {GC.GetTotalMemory(false)}"));

                if (!TheBaseAssets.MyActivationManager.InitializeLicenses())
                {
                    Shutdown(true);
                    TheBaseAssets.MySYSLOG.WriteToLog(4145, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Licensing error", eMsgLevel.l3_ImportantMessage));
                    return(false);
                }

                //4.304: Workitem #2289 - Removed from OSS Release (as CheckLicense is always returning true in the CoreCrypto Lib
                if (!TheBaseAssets.MyActivationManager.CheckLicense(new Guid("{5737240C-AA66-417C-9B66-3919E18F9F4A}"), "", null, 1, false))
                {
                    if (TheBaseAssets.MyServiceHostInfo.ShutdownOnLicenseFailure)
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(4146, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Licensing error: no activated license for Thing Service. Shutting down immediately as configured.", eMsgLevel.l2_Warning));
                        return(false);
                    }
                    else
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(4147, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Licensing error: no activated license for Thing Service. Will shut down in 60 minutes if not activated.", eMsgLevel.l2_Warning));
                        TheCommonUtils.cdeRunAsync("LicenseCheck", true, (o) =>
                        {
                            TheCommonUtils.TaskDelayOneEye(60 * 60 * 1000, 100).ContinueWith((t) =>
                            {
                                if (TheBaseAssets.MasterSwitch)
                                {
                                    if (!TheBaseAssets.MyActivationManager.CheckLicense(new Guid("{5737240C-AA66-417C-9B66-3919E18F9F4A}"), "", null, 1, false))
                                    {
                                        TheBaseAssets.MySYSLOG.WriteToLog(4148, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Licensing error: no activated license for Thing Service. Shutting down.", eMsgLevel.l1_Error));
                                        if (TheBaseAssets.IsInAgentStartup)
                                        {
                                            MyISMRoot?.Restart(true);
                                        }
                                        else
                                        {
                                            Shutdown(true);
                                        }
                                    }
                                }
                            });
                        });
                    }
                }


                TheCommCore.MyHttpService = new TheHttpService();
                TheBaseAssets.MySYSLOG.WriteToLog(4141, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "HttpService created", eMsgLevel.l3_ImportantMessage));

                if (TheBaseAssets.MyServiceHostInfo.StartISM && MyISMRoot == null && !string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.BaseDirectory))
                {
                    MyISMRoot = new TheISMManager {
                        eventShutdownRequired = sinkAppShutdown
                    };
                    MyISMRoot.InitISM("", "", "", TheBaseAssets.MyServiceHostInfo.CurrentVersion, TheBaseAssets.MyServiceHostInfo.ISMScanForUpdatesOnUSB, TheBaseAssets.MyServiceHostInfo.ISMScanOnStartup);
                    TheBaseAssets.MySYSLOG.WriteToLog(4142, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "ISM Started", eMsgLevel.l3_ImportantMessage));
                }
                else
                {
                    TheBaseAssets.MyServiceHostInfo.StartISM = false;
                }
                if (!TheBaseAssets.MasterSwitch)
                {
                    return(false);
                }

                if (MyCommonDisco == null)
                {
                    if (!TheBaseAssets.MyServiceHostInfo.IsIsolated && (TheCommonUtils.IsHostADevice() || TheBaseAssets.MyServiceHostInfo.cdeNodeType == cdeNodeType.Active))
                    {
                        TheBaseAssets.MySettings.SetSetting("DISCO_IsClientOnly", "True");
                    }
                    MyCommonDisco = new TheCommonDisco(); // Initialized the Discovery Service
                }

                TheCDEngines.eventAllEnginesStarted += sinkEnginesStarted;
                if (!TheCDEngines.StartEngines(pPlugInLst, null))                                           //Starts all SubEngines and Plugins. MyCmdArgs is a copy of the tParas sent to the Init Assets Function and can be used to set parameters for each engine during startup
                {
                    Shutdown(true);
                    TheBaseAssets.MySYSLOG.WriteToLog(4149, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("TheBaseApplication", "Failed to start engines", eMsgLevel.l3_ImportantMessage));
                    return(false);
                }
                return(true);
            }
            finally
            {
                TheBaseAssets.IsStarting = false;
            }
        }
Example #13
0
        private async Task RunPlaybackAsync(IEnumerable <cdeP> allProperties, IEnumerable <object> thingUpdates, TimeSpan startupDelayRange, bool bFromAutoStart, double propCountBefore)
        {
            for (int j = 1; j <= ReplayCount; j++)
            {
                playbackCancel?.Cancel();
                playbackCancel = new CancellationTokenSource();
                var cancelCombined = CancellationTokenSource.CreateLinkedTokenSource(playbackCancel.Token, TheBaseAssets.MasterSwitchCancelationToken);
                IsStarted = true;
                MyBaseThing.StatusLevel = 1;
                MyBaseThing.LastMessage = $"Playback started: {ItemCount} items. {ParallelPlaybackCount} things.";
                for (int i = 1; i <= ParallelPlaybackCount; i++)
                {
                    TheThing tThingOverride = null;
                    if (!string.IsNullOrEmpty(PlaybackEngineName))
                    {
                        if (TheThingRegistry.GetBaseEngine(PlaybackEngineName) == null)
                        {
                            TheCDEngines.RegisterNewMiniRelay(PlaybackEngineName);
                        }

                        var thingName = $"{MyBaseThing.FriendlyName}{i:D6}";
                        tThingOverride = TheThingRegistry.GetThingByID(PlaybackEngineName, thingName, true);
                        if (tThingOverride == null)
                        {
                            tThingOverride = new TheThing
                            {
                                FriendlyName = thingName,
                                ID           = thingName,
                                EngineName   = PlaybackEngineName,
                                DeviceType   = PlaybackDeviceType,
                            };

                            foreach (var prop in allProperties)
                            {
                                tThingOverride.SetProperty(prop.Name, prop.Value, prop.cdeT);
                            }
                            TheThingRegistry.RegisterThing(tThingOverride);
                        }
                        // This only works if the plug-in is actually installed, not with mini relay
                        //var createThingInfo = new TheThingRegistry.MsgCreateThingRequestV1
                        //{
                        //    EngineName = PlaybackEngineName,
                        //    DeviceType = PlaybackDeviceType,
                        //    InstanceId = thingName,
                        //    FriendlyName = thingName,
                        //    CreateIfNotExist = true,
                        //    DoNotModifyIfExists = true,
                        //    OwnerAddress = MyBaseThing,
                        //    Properties = new Dictionary<string, object> { { "ID", thingName } },
                        //};
                        //tThingOverride = await TheThingRegistry.CreateOwnedThingAsync(createThingInfo, new TimeSpan(0, 1, 0));
                        if (tThingOverride == null)
                        {
                            MyBaseThing.LastMessage = "Error creating playback thing";
                            break;
                        }
                    }
                    var playbackTask = TheCommonUtils.cdeRunTaskChainAsync($"Playback{i}", o => PlaybackLoop(tThingOverride, cancelCombined.Token, thingUpdates, startupDelayRange, bFromAutoStart), true);
                    playbackTasks.Add(playbackTask);
                }

                _ = await TheCommonUtils.TaskWhenAll(playbackTasks).ContinueWith(async(t) =>
                {
                    try
                    {
                        PlaybackDuration = sw.Elapsed;
                        sw.Stop();
                        OnKpiUpdate(null);
                        var propCount = Gen_Stats_PropertyCounter - propCountBefore;
                        var message   = $"Playback done. {propCount} props in {PlaybackDuration}. {propCount / PlaybackDuration.TotalSeconds} props/s. {ItemCount * ParallelPlaybackCount / PlaybackDuration.TotalSeconds} items/s.";
                        //MyBaseThing.LastMessage = message;
                        TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, message, eMsgLevel.l6_Debug));
                        await StopPlaybackAsync(message);
                        _ = new CDMyMeshManager.Contracts.MsgReportTestStatus
                        {
                            NodeId           = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID,
                            PercentCompleted = (j * 1.0 / ReplayCount) * 100,
                            SuccessRate      = 100,
                            Status           = j == ReplayCount ? CDMyMeshManager.Contracts.eTestStatus.Success : CDMyMeshManager.Contracts.eTestStatus.Running,
                            TestRunId        = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")),
                            Timestamp        = DateTimeOffset.Now,
                            ResultDetails    = new Dictionary <string, object>
                            {
                                { "Message", message },
                                { "PropertyCount", propCount },
                                { "DurationInSeconds", PlaybackDuration.TotalSeconds }
                            },
                        }.Publish().Result;
                    }
                    catch { }
                }, TaskContinuationOptions.OnlyOnRanToCompletion);
            }
        }
Example #14
0
 public override bool Init()
 {
     TheCDEngines.RegisterNewMiniRelay("EnergyMessages");
     return(base.Init());
 }
Example #15
0
        public override void HandleMessage(ICDEThing sender, object pIncoming)
        {
            if (TheCDEngines.MyIStorageService == null)
            {
                return;                                         //No processing if Storage is not active
            }
            TheProcessMessage pMsg = pIncoming as TheProcessMessage;

            if (pMsg == null)
            {
                return;
            }
            if (!mIsInitialized)
            {
                //InitializeStores(); //V4.106: we dont allow this anymore during runtime - the store is either initialized during startup or never available
                return;
            }
            if (MyBaseEngine.GetEngineState().IsService)
            {
                var tCmd = pMsg.Message.TXT.Split(':');
                switch (tCmd[0])
                {
                case "NEW_SENSOR_VALUE":
                    TheSensorValue tData = TheCommonUtils.DeserializeJSONStringToObject <TheSensorValue>(pMsg.Message.PLS);
                    if (tData != null && MySensorStore != null)
                    {
                        //TODO: tCmd[1] has the "ChartToken" that allows to put the value into different tables/charts. For now just one table for all charts
                        MySensorStore.AddAnItem(tData);
                    }
                    break;

                default:
                    ProcessStorageServiceCommands(pMsg.Message, pMsg.LocalCallback, false);
                    break;
                }
                return;
            }

            //CM: Next section is about Remote Storage Services. This will come in a later step
            string[]         reqGuid = pMsg.Message.TXT.Split(':');
            TheTimedCallback tCall   = null;

            if (reqGuid.Length > 1 && (tCall = MyTimedCallbacks.MyMirrorCache.GetEntryByID(TheCommonUtils.CGuid(reqGuid[1]))) != null)
            {
                tCall.MyCallback?.Invoke(pMsg.Message);
                MyTimedCallbacks.RemoveAnItem(tCall, null);
            }
            else
            {
                object tStorageMirror = TheCDEngines.GetStorageMirror(pMsg.Topic); //, out tStorageMirror);
                if (tStorageMirror != null)
                {
                    Type magicType = tStorageMirror.GetType();
#if CDE_STANDARD
                    MethodInfo magicMethod = magicType.GetTypeInfo().GetDeclaredMethod("sinkProcessServiceMessages");
#else
                    MethodInfo magicMethod = magicType.GetMethod("sinkProcessServiceMessages");
#endif
                    if (magicMethod != null)
                    {
                        magicMethod.Invoke(tStorageMirror, new object[] { pMsg.Message }); //object magicValue =
                    }
                }
            }
        }