// Register for history on our Thing public void ConsumeHistory() { if (testThing != null) { TheHistoryParameters historyParameters = new TheHistoryParameters { Properties = properties, SamplingWindow = TimeSpan.FromMilliseconds(5000), // Every 5 seconds ReportUnchangedProperties = true, ReportInitialValues = true, Persistent = true, MaintainHistoryStore = false, ComputeAvg = true, ComputeMax = true, ComputeMin = true }; historyToken = testThing.RegisterForUpdateHistory(historyParameters); TheQueuedSenderRegistry.RegisterHealthTimer((l) => { // Every 6 seconds, log the aggregated values. Sampling window for historian is 5 seconds. if (l % 6 == 0) { LogChanges(true); } }); } }
/// <summary> /// Construtor for network related events /// </summary> /// <param name="onNewInterfaceSink"></param> /// <param name="onDeletedInterfaceSink"></param> public TheNetworkInfo(Action <object, TheIPDef> onNewInterfaceSink, Action <object, TheIPDef> onDeletedInterfaceSink) { TheBaseAssets.MySYSLOG.WriteToLog(138, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("UPnP", "Enter NetworkInfo")); TheQueuedSenderRegistry.RegisterHealthTimer(PollInterface); MyHostName = cdeGetHostName(); TheBaseAssets.MySYSLOG.WriteToLog(139, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("UPnP", "NetworkInfo - HostName :" + MyHostName)); GetLocalIPs(true); if (onNewInterfaceSink != null) { OnNewInterfaceEvent += onNewInterfaceSink; foreach (TheIPDef address in AddressTable.Values) { if (address.IsDnsEnabled) { TheBaseAssets.MySYSLOG.WriteToLog(141, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("UPnP", string.Format("NetworkInfo - Init-Address: {0} of {1}", address, AddressTable.Count), eMsgLevel.l3_ImportantMessage)); OnNewInterfaceEvent?.Invoke(this, address); } } } if (OnInterfaceDisabledEvent != null) { OnInterfaceDisabledEvent += onDeletedInterfaceSink; } TheBaseAssets.MySYSLOG.WriteToLog(144, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("UPnP", "NetworkInfo - All Interfaces Initialized")); }
internal static TheNodeInfoHeader GetInfoHeaderJSON() { var tHead = new TheNodeInfoHeader { CloudRoutes = new List <TheServiceRouteInfo>(), NodeID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, NodeName = TheBaseAssets.MyServiceHostInfo.NodeName, BuildVersion = TheBaseAssets.BuildVersion, CurrentVersion = TheBaseAssets.CurrentVersionInfo, ScopeHash = TheBaseAssets.MyScopeManager.IsScopingEnabled ? TheBaseAssets.MyScopeManager.ScopeID.Substring(0, 4).ToUpper() : "unscoped", OSInfo = TheBaseAssets.MyServiceHostInfo.OSInfo }; var CNs = TheQueuedSenderRegistry.GetCloudNodes(true); if (CNs.Count > 0) { foreach (var tQ in CNs) { var tInfo = new TheServiceRouteInfo { Url = tQ.MyTargetNodeChannel.TargetUrl, IsConnected = tQ.IsConnected, IsConnecting = tQ.IsConnecting, LastError = tQ.GetLastError(), ErrorCode = tQ.GetLastErrorCode(), LastHB = (tQ.GetLastHeartBeat() == DateTimeOffset.MinValue ? "not yet" : $"{TheCommonUtils.GetDateTimeString(tQ.GetLastHeartBeat(), -1)}"), ConnectedSince = (tQ.MyLastConnectTime == DateTimeOffset.MinValue ? "not yet" : $"{TheCommonUtils.GetDateTimeString(tQ.MyLastConnectTime, -1)}"), IsAlive = tQ.IsAlive, UsesWS = tQ.HasWebSockets() }; tInfo.Status = $"{tInfo.Url} (Connected: {(tInfo.IsConnected ? "Yes, all is good" : (tInfo.IsConnecting ? "Not, yet - trying to connect" : "No, and not yet trying to connect again!"))}{(!string.IsNullOrEmpty(tInfo.LastError) ? $" Last Error: {tInfo.LastError}" : "")})"; tHead.CloudRoutes.Add(tInfo); } } return(tHead); }
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(); }
public override bool Init() { if (!mIsInitStarted) { mIsInitStarted = true; MyBaseThing.StatusLevel = 4; MyBaseThing.LastMessage = "Logger Service has started"; MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); MyBaseEngine.RegisterEvent(eEngineEvents.ThingDeleted, OnThingDeleted); cdeP tP = null; if (TheBaseAssets.MyServiceHostInfo.DisableConsole) { TheThing.SetSafePropertyBool(MyBaseThing, "DisableStandardLog", TheBaseAssets.MyServiceHostInfo.DisableConsole); } else { tP = GetProperty("DisableStandardLog", true); } tP.RegisterEvent(eThingEvents.PropertyChanged, sinkDisableChanged); if (TheCommonUtils.CBool(tP.ToString())) { TheBaseAssets.MyServiceHostInfo.DisableConsole = true; } if (TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat) { tP = TheThing.SetSafePropertyBool(MyBaseThing, "UseGELF", TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat); } else { tP = GetProperty("UseGELF", true); } tP.RegisterEvent(eThingEvents.PropertyChanged, sinkGELF); if (TheCommonUtils.CBool(tP.ToString())) { TheBaseAssets.MyServiceHostInfo.UseGELFLoggingFormat = true; } bool DoLogKPIs = TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("LogKPIs")); if (DoLogKPIs) { TheThing.SetSafePropertyBool(MyBaseThing, "LogKPIs", true); } TheQueuedSenderRegistry.RegisterHealthTimer(sinkTimer); // If not lengthy initialized you can remove cdeRunasync and call this synchronously TheCommonUtils.cdeRunAsync(MyBaseEngine.GetEngineName() + " Init Services", true, (o) => { // Perform any long-running initialization (i.e. network access, file access) here InitServices(); MyBaseEngine.ProcessInitialized(); //Set the status of the Base Engine according to the status of the Things it manages mIsInitCompleted = true; }); } return(false); }
/// <summary> /// Connect to the Thing /// </summary> public void Connect() { if (MyIsolator == null) { return; } readBytesSec = new PerformanceCounter("Process", "IO Other Bytes/sec", MyIsolator.ProcessName); TheThing.SetSafePropertyBool(MyBaseThing, "IsConnected", true); TheQueuedSenderRegistry.RegisterHealthTimer(sinkTimer); }
private void sinkRequestMeshInfo(TheRequestData request) { if (request != null) { request.ResponseMimeType = "application/json"; string errorText = ""; Dictionary <string, string> tQ = TheCommonUtils.ParseQueryString(request.RequestUri?.Query); if (tQ != null) { tQ.TryGetValue("MESHINFOTOKEN", out string meshInfoToken); if (tQ.TryGetValue("ORG", out string tOrg)) { Guid requestorMID = TheCommonUtils.CGuid(tOrg); if (requestorMID != Guid.Empty) { TheMeshInfoStatus meshInfoStatus = TheQueuedSenderRegistry.GetMeshInfoForNodeID(requestorMID, meshInfoToken); if (string.IsNullOrEmpty(meshInfoStatus?.StatusMessage)) { request.StatusCode = (int)eHttpStatusCode.OK; request.ResponseBuffer = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(meshInfoStatus.MeshInfo)); } else { request.StatusCode = meshInfoStatus.StatusCode; //Better if meshInfoStatus also defines this as there are different messages (wrong MIT, too frequent tests etc) errorText = meshInfoStatus.StatusMessage; } } else { request.StatusCode = 400; errorText = "Invalid or badly formed ORG parameter."; } } else { request.StatusCode = 400; errorText = "No ORG parameter found for mesh info request."; } } else { request.StatusCode = (int)eHttpStatusCode.AccessDenied; errorText = "Access denied"; } if (!string.IsNullOrEmpty(errorText)) { TheErrorResponse errorResponse = new TheErrorResponse { Error = errorText, CTIM = DateTimeOffset.Now }; request.ResponseBuffer = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(errorResponse)); } } }
/// <summary> /// This event is fired when the scope was changed /// </summary> public virtual void EventScopeChanged(bool SetReq) { if (TheBaseAssets.MyApplication != null && TheBaseAssets.MyApplication.MyCommonDisco != null) { TheBaseAssets.MyApplication.MyCommonDisco.UpdateContextID(); } TheQueuedSenderRegistry.UpdateLocalHostScope(); if (TheBaseAssets.MyServiceHostInfo.AreAllEnginesStarted) { TheQueuedSenderRegistry.ReinitCloudRoutes(); TheUserManager.ResetUserScopes(true); } }
public void ProcessRequest(HttpContext context) { try { var tRequestUri = HttpContext.Current.Request.Url; if (tRequestUri.PathAndQuery.ToLower().StartsWith("/wstest")) { ProcessRequest(new HttpContextWrapper(context)); return; } context.AcceptWebSocketRequest(async wsContext => { TheRequestData tRequestData = new TheRequestData { RequestUri = HttpContext.Current.Request.Url, HttpMethod = HttpContext.Current.Request.HttpMethod, UserAgent = HttpContext.Current.Request.UserAgent, ServerTags = TheCommonUtils.cdeNameValueToDirectory(HttpContext.Current.Request.ServerVariables), Header = TheCommonUtils.cdeNameValueToDirectory(HttpContext.Current.Request.Headers), ResponseMimeType = "cde/ws", ClientCert = HttpContext.Current.Request.ClientCertificate?.Count > 0 ? new System.Security.Cryptography.X509Certificates.X509Certificate2(HttpContext.Current.Request.ClientCertificate?.Certificate) : null //Verified that this works with no private key. Since C-DEngineCloud only works on Windows in IIS and MUST run as Administrator there is no linux check required here }; if (TheCommCore.MyHttpService != null && TheBaseAssets.MyServiceHostInfo.ClientCertificateUsage > 1) //If CDE requires a certificate, terminate all incoming requests before any processing { var err = TheCommCore.MyHttpService.ValidateCertificateRoot(tRequestData); if (TheBaseAssets.MyServiceHostInfo.DisableNMI && !string.IsNullOrEmpty(err)) { var terr = $"WebSocket Access with worng Client Certificate root - access is denied: {err}"; TheBaseAssets.MySYSLOG.WriteToLog(423, new TSM("TheCloudWSockets", terr, eMsgLevel.l1_Error)); return; } } await TheQueuedSenderRegistry.ProcessCloudRequest(wsContext.WebSocket, tRequestData); }); } catch (Exception ex) { TheBaseAssets.MySYSLOG.WriteToLog(423, new TSM("TheCloudWSockets", "Processing Error 500", ex.ToString())); context.Response.StatusCode = 500; context.Response.StatusDescription = ex.Message; context.Response.End(); } }
internal void sinkExpired(TheSessionState pState) { if (pState != null) { if (pState.CID != Guid.Empty) { TheUserManager.RemoveTempUser(pState.CID); } TheQueuedSender tQSend = TheQueuedSenderRegistry.GetSenderBySEID(pState.cdeMID); if (tQSend != null) { tQSend.FireSenderProblem(new TheRequestData() { ErrorDescription = "1500:Session for this QSender expired" }); } } }
public TheHealthMonitor(int pHealthCycle, TheCDMyComputerEngine pEngineName, bool DisableCollection) { if (pEngineName != null) { MyEngineName = pEngineName.GetBaseEngine().GetEngineName(); MyBaseEngine = pEngineName; } if (pHealthCycle > 0) { HealthUpdateCycle = pHealthCycle; } mDisableCollection = DisableCollection; TheBaseEngine.WaitForStorageReadiness(StorageHasStarted, true); InitHealthCollection(); TheQueuedSenderRegistry.RegisterHealthTimer(CheckOnHealthTimer); }
/// <summary> /// Processes the WebSockets request. /// </summary> /// <param name="context">The http context.</param> /// <param name="ws">The incoming WebSockets.</param> public async Task ProcessWSRequest(HttpContext context, WebSocket ws) { try { TheRequestData tRequestData = cdeASPNetCommon.CreateRequest(context); if (tRequestData == null) { return; } tRequestData.ResponseMimeType = "cde/ws"; await TheQueuedSenderRegistry.ProcessCloudRequest(ws, tRequestData); } catch (Exception ex) { TheBaseAssets.MySYSLOG.WriteToLog(423, new TSM("TheCloudWSockets", "Processing Error 500", ex.ToString())); context.Response.StatusCode = 500; } }
public bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; MyBaseThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); if (TheThing.GetSafePropertyString(MyBaseThing, "VisitorCount") == "") { VisitorCount = 0; } MyNodePrintsName = $"NodePrints{TheThing.GetSafeThingGuid(MyBaseThing, "NodePrints")}"; TheBaseEngine.WaitForStorageReadiness(OnStorageReady, true); MyBaseThing.SetPublishThrottle(15000); TheCommCore.RegisterRelayEvents(null, null, sinkNewConnection); if (MyVisitorLog == null) { MyVisitorLog = new TheVisitorLog(MyBaseThing); } TheQueuedSenderRegistry.RegisterHealthTimer(GetSystemInfo); TheCDEngines.MyNMIService.RegisterEvent("NMI_MY_LOCATION", (sender2, para) => { var t = para as TheNMILocationInfo; if (t != null) { var NewEntry = new TheVisitorLogData { cdeN = t.cdeN, latitude = t.Latitude, longitude = t.Longitude, ip = t.ClientInfo?.UserID.ToString(), LastVisit = DateTimeOffset.Now, Description = t.ClientInfo != null && t.ClientInfo.UserID != Guid.Empty ? TheUserManager.GetUserFullName(t.ClientInfo.UserID) : "Unknown user" }; MyVisitorLog.LogVisitor(NewEntry); myGoogleMap?.SetUXProperty(Guid.Empty, $"AddMarker={TheCommonUtils.SerializeObjectToJSONString(NewEntry)}"); } }); TheCommCore.MyHttpService.RegisterHttpInterceptorB4("/cdemeshinfo.aspx", sinkRequestMeshInfo); MyBaseEngine.ProcessInitialized(); MyBaseEngine.SetEngineReadiness(true, null); MyBaseEngine.SetStatusLevel(1); mIsInitialized = true; return(true); }
public bool Init() { if (mIsInitCalled) { return(false); } mIsInitCalled = true; MyBaseThing.StatusLevel = 1; MyBaseThing.Version = TheBaseAssets.MyAppInfo.CurrentVersion.ToString(CultureInfo.InvariantCulture); MyBaseThing.Capabilities = TheBaseAssets.MyAppInfo.Capabilities; MyBaseThing.Address = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false); TheThing.SetSafePropertyString(MyBaseThing, "Description", TheBaseAssets.MyAppInfo.LongDescription); mIsInitialized = true; TheThing.SetSafePropertyBool(MyBaseThing, "EnableKPIs", TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("EnableKPIs"))); if (TheBaseAssets.MyServiceHostInfo.EnableTaskKPIs) { var taskKpiThread = new System.Threading.Thread(() => { TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: NodeHost starting Task KPI thread"); do { 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); var kpis = TheCommonUtils.GetTaskKpis(null); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: {TheCommonUtils.SerializeObjectToJSONString(kpis)}"); } while (TheBaseAssets.MasterSwitch && TheBaseAssets.MyServiceHostInfo.EnableTaskKPIs); TheSystemMessageLog.ToCo($"Tasks {DateTime.Now}: NodeHost ending Task KPI thread"); }); taskKpiThread.Start(); } KPIHarvestInterval = TheCommonUtils.CInt(TheBaseAssets.MySettings.GetAppSetting("KPIHarvestIntervalInSeconds", "5", false, true)); if (KPIHarvestInterval > 0) { TheQueuedSenderRegistry.RegisterHealthTimer(sinkCyclic); } return(true); }
void sinkTimer(long t) { if (MyIsolator == null) { return; } if (MyIsolator.HasExited) { TheQueuedSenderRegistry.UnregisterHealthTimer(sinkTimer); MyBaseThing.StatusLevel = 0; MyBaseThing.LastMessage = "Plugin no longer running"; return; } try { TheThing.SetSafePropertyString(MyBaseThing, "IORead", string.Format("{0:0.00}", readBytesSec?.NextValue())); //if ((t%15)!=0) return; TheThing.SetSafePropertyString(MyBaseThing, "CPUTime", string.Format("{0:0.00}", MyIsolator.TotalProcessorTime.TotalSeconds)); TheThing.SetSafePropertyNumber(MyBaseThing, "WorkingSet", MyIsolator.WorkingSet64 / 1024); TheThing.SetSafePropertyNumber(MyBaseThing, "Handles", MyIsolator.HandleCount); TheThing.SetSafePropertyNumber(MyBaseThing, "Threads", MyIsolator.Threads.Count); TimeSpan ts = DateTime.Now.Subtract(MyIsolator.StartTime); TheThing.SetSafePropertyNumber(MyBaseThing, "UpTime", ts.TotalMinutes); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", $"SELECT * FROM Win32_PerfFormattedData_PerfProc_Process where IDProcess='{MyIsolator.Id}'")) { foreach (ManagementObject queryObj in searcher.Get()) { TheThing.SetSafePropertyString(MyBaseThing, "CPU", queryObj["PercentProcessorTime"].ToString()); MyBaseThing.Value = queryObj["PercentProcessorTime"].ToString(); //foreach (var ttt in queryObj.Properties) //{ // Console.WriteLine($"{ttt.Name}: {ttt.Value}"); //} } } } catch (Exception) { } }
internal static void SetResponseBuffer(TheRequestData pRequestData, TheChannelInfo pChannelInfo, bool pSendPulse, string NopTopic, Guid owner, string pRefreshToken) { if (string.IsNullOrEmpty(NopTopic)) { TheQueuedSender tQ = null; if (pChannelInfo != null && pChannelInfo.cdeMID != Guid.Empty) //Send to Device First { tQ = TheQueuedSenderRegistry.GetSenderByGuid(pChannelInfo.cdeMID); } if (tQ != null) { if (pRequestData.WebSocket != null) { if (tQ.GetQueLength() == 0) { tQ.SendPickupMessage(); } return; } tQ.GetNextBackChannelBuffer(pRequestData); } } if (string.IsNullOrEmpty(NopTopic) && pRequestData.WebSocket != null) { return; //NEW:3.084 && !pSendPulse removed NEW:V3B3:2014-7-22 removed && pRequestData.ResponseBuffer != null } if (pRequestData.ResponseBuffer == null && pChannelInfo != null && (pSendPulse || (pChannelInfo.cdeMID != Guid.Empty || TheQueuedSenderRegistry.IsNodeIdInSenderList(pChannelInfo.cdeMID)))) { TheDeviceMessage tDev = new TheDeviceMessage { CNT = 0 }; //tDev.MET = 0; if (!string.IsNullOrEmpty(NopTopic)) { tDev.MSG = new TSM(); //Can be set without ORG and SID if (owner != Guid.Empty) { tDev.MSG.OWN = owner.ToString(); } if (NopTopic == "CDE_WSINIT") { NopTopic = TheCommCore.SetConnectingBufferStr(pChannelInfo, null); } } if (pChannelInfo.SenderType != cdeSenderType.CDE_JAVAJASON) //4.209: No longer sending SID to Browser; { if (TheBaseAssets.MyServiceHostInfo.EnableFastSecurity) { tDev.SID = pRequestData.SessionState.SScopeID; //SECURITY: All responses will have same Scrambled ScopeID - but ok because this is init telegram or HB } else { tDev.SID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(pRequestData.SessionState.SScopeID, false); //GRSI: high frequency } } else { if (!string.IsNullOrEmpty(pRefreshToken)) { tDev.SID = pRefreshToken; } } tDev.FID = pRequestData.SessionState.GetNextSerial().ToString(); if (TheCommonUtils.IsDeviceSenderType(pChannelInfo.SenderType)) //IDST-OK: Must create RSA for Devices { TheCommonUtils.CreateRSAKeys(pRequestData.SessionState); tDev.RSA = pRequestData.SessionState.RSAPublic; } tDev.NPA = TheBaseAssets.MyScopeManager.GetISBPath(TheBaseAssets.MyServiceHostInfo.RootDir, pChannelInfo.SenderType, TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType, pRequestData.SessionState.FID, pRequestData.SessionState.cdeMID, pRequestData.WebSocket != null); tDev.CNT = pSendPulse ? 1 : 0; tDev.TOP = NopTopic; tDev.DID = pChannelInfo.SenderType == cdeSenderType.CDE_JAVAJASON ? pChannelInfo.cdeMID.ToString() : TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString(); //There will be only one Message here - single poke or Mini Command or NOP Pickup List <TheDeviceMessage> tDevList = new List <TheDeviceMessage> { tDev }; if (pChannelInfo.SenderType == cdeSenderType.CDE_JAVAJASON || TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType == cdeSenderType.CDE_MINI || pChannelInfo.SenderType == cdeSenderType.CDE_MINI || pRequestData.WebSocket != null) { pRequestData.ResponseBuffer = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(tDevList)); pRequestData.ResponseMimeType = "application/json"; } else { pRequestData.ResponseBuffer = TheCommonUtils.cdeCompressString(TheCommonUtils.SerializeObjectToJSONString(tDevList)); pRequestData.ResponseMimeType = "application/x-gzip"; } } if (pRequestData.ResponseBuffer == null && pChannelInfo != null && pChannelInfo.cdeMID != Guid.Empty) { TheBaseAssets.MySYSLOG.WriteToLog(290, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Nothing to Send Back to {pChannelInfo?.ToMLString()}", eMsgLevel.l7_HostDebugMessage)); } }
private void StartUPnPDiscovery(string pLiveEngines) { if (MyUPnPDiscoveryPast != null) { TheBaseAssets.MySYSLOG.WriteToLog(109, new TSM("UPnP", "DISCO aready running!")); return; } MyUPnPDiscoveryPast = new TheStorageMirror <TheUPnPDeviceInfo>(Engines.TheCDEngines.MyIStorageService) { IsRAMStore = true, BlockWriteIfIsolated = true }; MyUPnPDiscoveryPast.SetRecordExpiration(DISCOExpireTime, sinkDeviceExpired); //MyUPnPDiscoveryPast.CacheStoreInterval = 60; //MyUPnPDiscoveryPast.IsStoreIntervalInSeconds = true; //MyUPnPDiscoveryPast.IsCachePersistent = true; MyUPnPDiscoveryPast.InitializeStore(true, true); var tCDEConnectUrl = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false); TheBaseAssets.MySYSLOG.WriteToLog(107, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("UPnP", "Starting Device", eMsgLevel.l3_ImportantMessage)); MyDeviceUPnPInfo = new TheUPnPDeviceInfo() { FriendlyName = TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " at: " + tCDEConnectUrl + " - Services:" + pLiveEngines,// pStationEngines; Manufacturer = TheBaseAssets.MyServiceHostInfo.VendorName, ManufacturerUrl = TheBaseAssets.MyServiceHostInfo.VendorUrl, ModelName = TheBaseAssets.MyServiceHostInfo.ApplicationName, ModelNumber = string.Format("V{0:0.0000}", TheBaseAssets.MyServiceHostInfo.CurrentVersion), SerialNumber = TheBaseAssets.CurrentVersionInfo, PacketString = "", RawMetaXml = "", LocationURL = tCDEConnectUrl, ST = "C-DEngine", CDEConnectUrl = tCDEConnectUrl, CDENodeID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, UUID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString(), USN = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString(), IsCDEngine = true }; if (!TheBaseAssets.MyServiceHostInfo.RequiresConfiguration) { MyDeviceUPnPInfo.CDEContextID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(); //GRSI: rare } if (TheCommonUtils.IsHostADevice()) { MyDeviceUPnPInfo.HasPresentation = false; } else { if (!TheBaseAssets.MyServiceHostInfo.DisableWebSockets && TheBaseAssets.MyServiceHostInfo.MyStationWSPort > 0) { var builder = new UriBuilder(TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false)); builder.Scheme = builder.Scheme == "https" ? "wss" : "ws"; builder.Port = TheBaseAssets.MyServiceHostInfo.MyStationWSPort; MyDeviceUPnPInfo.CDEConnectWsUrl = TheCommonUtils.TruncTrailingSlash(builder.Uri.ToString()); } MyDeviceUPnPInfo.HasPresentation = true; } eventDiscoReady?.Invoke(true); TheQueuedSenderRegistry.RegisterHealthTimer(DoScan4Devices); TheBaseAssets.MySYSLOG.WriteToLog(108, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("UPnP", "DISCO engine ready...")); }
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(); }
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("{AE1F4BBB-B9E3-47D5-B08A-FE71A5697D20}"), // TCP/IP Port Assignments MyStationPort = 8713, // 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 = 8714, // 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 = "MyTestHost", // 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.ESSENTIALS, // 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("MyTestEngine2"); // The engine for MyTestHost2 IBaseEngine eng = TheCDEngines.RegisterPubSubTopic("MyTestEngine"); // The engine for THIS host eng.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage); TheQueuedSenderRegistry.RegisterHealthTimer(SinkTimer); #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 }
private void sinkHeartBeatTimer(long NOTUSED) { try { TheDiagnostics.SetThreadName("HeartbeatTimer", true); mHeartBeatTicker++; TheBaseAssets.MySYSLOG.WriteToLog(2803, TSM.L(eDEBUG_LEVELS.EVERYTHING) ? null : new TSM("QSender", $"Enter HearbeatTimer for ORG:{MyTargetNodeChannel}", eMsgLevel.l7_HostDebugMessage)); TheTimeouts tTO = TheBaseAssets.MyServiceHostInfo.TO; if (!IsHeartBeatAlive(tTO.DeviceCleanSweepTimeout * 2) && TheCommonUtils.IsDeviceSenderType(MyTargetNodeChannel?.SenderType ?? cdeSenderType.NOTSET) && MyTargetNodeChannel?.IsWebSocket == false) //IDST-OK: Remove dead devices that might have hard disconnected (no correct disconnect) i.e. http browsers were just closed { TheBaseAssets.MySYSLOG.WriteToLog(2820, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("QSender", $"Forced Removal of QSender {MyTargetNodeChannel.ToMLString()} due to DeviceCleanSweep", eMsgLevel.l4_Message)); Guid?tTarget = MyTargetNodeChannel?.cdeMID; DisposeSender(true); if (tTarget.HasValue) { TheQueuedSenderRegistry.RemoveOrphan(tTarget.Value); TheCommCore.PublishCentral(new TSM(eEngineName.ContentService, "CDE_DELETEORPHAN", tTarget.ToString())); } return; } if (!IsAlive && !MyTargetNodeChannel?.IsWebSocket == true) { return; //NEW:V3 2013/12/13 allow for cloud reconnect if WebSockets } if ((mHeartBeatTicker % (tTO.HeartBeatRate * 2)) == 0) { if (MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_LOCALHOST) { timerMyHeartbeatTimer(); } if (MyTargetNodeChannel?.SenderType == cdeSenderType.CDE_CLOUDROUTE && ((!IsConnected && !IsConnecting) || !IsAlive) && (mHeartBeatTicker % (tTO.HeartBeatRate * 10)) == 0) //tQ.MyTargetNodeChannel.IsWebSocket && NOW ALWAYS RECONNECT { TheCommonUtils.cdeRunAsync("ReconnectCloud", true, (o) => ReconnectCloud()); } if (MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_LOCALHOST && IsAlive && IsConnected) //!TheBaseAssets.MyServiceHostInfo.IsCloudService && !tQ.MyTargetNodeChannel.IsWebSocket && { if (MyTargetNodeChannel?.IsWebSocket != true) { if (GetQueLength() == 0) { TheBaseAssets.MyServiceHostInfo.TO.MakeHeartPump(); // CODE REVIEW Markus: Isn't this backwards: we should pump faster while we have more work to do? SendPickupMessage(); //Pickup } else { TheBaseAssets.MyServiceHostInfo.TO.MakeHeartNormal(); } } else { SendPickupMessage(); //Pickup } } } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(2821, new TSM("QSRegistry", $"Fatal Error in HealthTimer for QS:{this.cdeMID} and MTNC:{MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error, e.ToString())); } }
/// <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); }
internal static void ToThingProperties(TheThing pThing, bool bReset) { lock (thingHarvestLock) { if (pThing == null) { return; } if (KPIIndexes == null) { CreateKPIIndexes(); } if (KPIs == null) { KPIs = new long[KPIIndexes.Count]; } if (KPIs != null && KPIIndexes != null) { TimeSpan timeSinceLastReset = DateTimeOffset.Now.Subtract(LastReset); bool resetReady = timeSinceLastReset.TotalMilliseconds >= 1000; foreach (var keyVal in KPIIndexes.GetDynamicEnumerable()) { bool donres = doNotReset.Contains(keyVal.Key); long kpiValue; if (bReset && !donres && resetReady) { kpiValue = Interlocked.Exchange(ref KPIs[keyVal.Value], 0); } else { kpiValue = Interlocked.Read(ref KPIs[keyVal.Value]); } // LastReset not set yet - shouldn't happen since it is set in first call to Reset (TheBaseAssets.InitAssets) if (LastReset == DateTimeOffset.MinValue || timeSinceLastReset.TotalSeconds <= 1 || donres) { pThing.SetProperty(keyVal.Key, kpiValue); } else { pThing.SetProperty(keyVal.Key, kpiValue / timeSinceLastReset.TotalSeconds); // Normalize value to "per second" } if (!doNotComputeTotals.Contains(keyVal.Key)) { pThing.SetProperty(keyVal.Key + "Total", TheThing.GetSafePropertyNumber(pThing, keyVal.Key + "Total") + kpiValue); } } if (bReset && resetReady) { LastReset = DateTimeOffset.Now; } // Grab some KPIs from sources - Workaround, this should be computed in the source instead SetKPI(eKPINames.QSenders, TheQueuedSenderRegistry.GetSenderListNodes().Count); SetKPI(eKPINames.QSenderInRegistry, TheQueuedSenderRegistry.Count()); SetKPI(eKPINames.SessionCount, TheBaseAssets.MySession.GetSessionCount()); SetKPI(eKPINames.UniqueMeshes, TheQueuedSenderRegistry.GetUniqueMeshCount()); SetKPI(eKPINames.UnsignedNodes, TheQueuedSenderRegistry.GetUnsignedNodeCount()); SetKPI(eKPINames.KnownNMINodes, Engines.NMIService.TheFormsGenerator.GetNMINodeCount()); SetKPI(eKPINames.StreamsNotFound, Communication.HttpService.TheHttpService.IsStreaming.Count); SetKPI(eKPINames.BlobsNotFound, Engines.ContentService.TheContentServiceEngine.BlobsNotHere.Count); } } }
internal static void DoExecuteCommand(string pInTopicBatch, TheQueuedSender pQSender, bool DoSendBackBuffer, TheRequestData pRequestData, List <TheDeviceMessage> pDevMessageList) { bool SendPulse = false; if (pDevMessageList != null && pDevMessageList.Count > 0) { foreach (TheDeviceMessage pDevMessage in pDevMessageList) { TSM recvMessage = null; string tTopic = ""; try { var tTargetNodeChannel = pQSender?.MyTargetNodeChannel; string pInTopic = pInTopicBatch; if (string.IsNullOrEmpty(pInTopic)) { pInTopic = pDevMessage.TOP; } recvMessage = pDevMessage.MSG; if (pQSender != null && tTargetNodeChannel != null && tTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON && recvMessage != null && string.IsNullOrEmpty(recvMessage.ORG)) { recvMessage.ORG = tTargetNodeChannel.cdeMID.ToString(); } #region ChunkResassembly string[] CommandParts = null; if (!string.IsNullOrEmpty(pInTopic)) { CommandParts = TheCommonUtils.cdeSplit(pInTopic, ":,:", false, false); tTopic = CommandParts[0]; } TheCDEKPIs.IncrementKPI(eKPINames.CCTSMsReceived); if (CommandParts != null && CommandParts.Length == 4 && !CommandParts[2].Equals("1")) { if (!TheCommonUtils.ProcessChunkedMessage(CommandParts, recvMessage)) { SendPulse = true; continue; } } #endregion if (recvMessage != null) { if (((TheBaseAssets.MyServiceHostInfo.RejectIncomingSETP && recvMessage.TXT?.StartsWith("SETP:") == true) || TheBaseAssets.MyServiceHostInfo.DisableNMIMessages) && recvMessage.ENG?.StartsWith(eEngineName.NMIService) == true) { TheCDEKPIs.IncrementKPI(eKPINames.QSSETPRejected); continue; } var tTopicSens = tTopic.Split('@')[0]; //only topic - no ScopeID var tTopicParts = tTopic.Split(';'); if (tTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON) { //4.209: JavaJason does no longer get the scope ID - hence telegrams coming from the browser have to be ammmended with SID here if (string.IsNullOrEmpty(recvMessage.SID) && !string.IsNullOrEmpty(pRequestData?.SessionState?.SScopeID)) { recvMessage.SID = pRequestData?.SessionState?.SScopeID; //Set the ScopeID in the SID of the message if (tTopic.StartsWith("CDE_SYSTEMWIDE")) { tTopic = $"{tTopicParts[0]}@{recvMessage.SID}"; if (tTopicParts.Length > 1) { tTopic += $";{tTopicParts[1]}"; //if a direct address is added use this too } } else if (!tTopic.Contains('@')) { tTopic += $"@{recvMessage.SID}"; } if (recvMessage.TXT == "CDE_SUBSCRIBE" || recvMessage.TXT == "CDE_INITIALIZE") { string MsgNoSID = null; recvMessage.PLS = TheBaseAssets.MyScopeManager.AddScopeID(recvMessage.PLS, recvMessage.SID, ref MsgNoSID, false, false); } } } if (tTopicParts.Length > 1) { tTopicSens += $";{tTopicParts[1]}"; //if a direct address is added use this too } if (TheQueuedSenderRegistry.WasTSMSeenBefore(recvMessage, pRequestData.SessionState.cdeMID, tTopicSens, tTargetNodeChannel?.RealScopeID)) //ATTENTION: RScope should come from pDevMessage { TheBaseAssets.MySYSLOG.WriteToLog(285, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"EnterExecuteCommand: Message was seen before ORG:{TheCommonUtils.GetDeviceIDML(recvMessage?.ORG)} Topic:{tTopicSens}", eMsgLevel.l2_Warning)); //ORG-OK TheCDEKPIs.IncrementKPI(eKPINames.QSRejected); continue; } if (tTargetNodeChannel.cdeMID == Guid.Empty) { tTargetNodeChannel.cdeMID = recvMessage.GetLastRelay(); } if (tTargetNodeChannel.SenderType == cdeSenderType.NOTSET) { TheBaseAssets.MySYSLOG.WriteToLog(285, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", "Sender Type for the QSender is not set! WE SHOULD NEVER GET HERE", eMsgLevel.l1_Error));//ORG-OK //3.218: Processing no longer allowed!!! return; } // Enable upper layers to do RSA decryption. Force overwrite for Browser even if SEID already set (may have been initialized to some other value) if (tTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON || String.IsNullOrEmpty(recvMessage.SEID)) { recvMessage.SEID = pRequestData.SessionState.cdeMID.ToString(); } if (pRequestData.SessionState != null && string.IsNullOrEmpty(pRequestData.SessionState.RemoteAddress)) { pRequestData.SessionState.RemoteAddress = tTargetNodeChannel.cdeMID.ToString(); } //NEW: User ID Management in Message after first node if (string.IsNullOrEmpty(recvMessage.UID) && pRequestData.SessionState != null && pRequestData.SessionState.CID != Guid.Empty) { recvMessage.UID = TheCommonUtils.cdeEncrypt(pRequestData.SessionState.CID.ToByteArray(), TheBaseAssets.MySecrets.GetAI()); //3.083: Must be cdeAI } } } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(319, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", "Execute Command Pre-Parsing Error", eMsgLevel.l1_Error, ee.ToString())); } if (recvMessage == null) { TheBaseAssets.MySYSLOG.WriteToLog(286, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"No Message for Parsing: Topic:{tTopic} - {pRequestData.ResponseBufferStr}", eMsgLevel.l7_HostDebugMessage)); } else { if (recvMessage.PLB != null && recvMessage.PLB.Length > 0 && string.IsNullOrEmpty(recvMessage.PLS)) { try { recvMessage.PLS = TheCommonUtils.cdeDecompressToString(recvMessage.PLB); recvMessage.PLB = null; } catch (Exception) { TheBaseAssets.MySYSLOG.WriteToLog(286, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"PLB to PLS decompress failed - Topic:{tTopic} Node:{pQSender?.MyTargetNodeChannel?.ToMLString()} ORG:{TheCommonUtils.GetDeviceIDML(recvMessage?.ORG)}", eMsgLevel.l7_HostDebugMessage, $"TXT:{recvMessage.TXT}"));//ORG-OK } } TheBaseAssets.MySYSLOG.WriteToLog(286, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"PLB to PLS parsing done - Topic:{tTopic} Node:{pQSender?.MyTargetNodeChannel?.ToMLString()} ORG:{TheCommonUtils.GetDeviceIDML(recvMessage?.ORG)}", eMsgLevel.l7_HostDebugMessage, $"TXT:{recvMessage.TXT}"));//ORG-OK if (!SendPulse) { SendPulse = recvMessage.SendPulse(); } TheCDEKPIs.IncrementKPI(eKPINames.CCTSMsEvaluated); } try { if (recvMessage != null && !string.IsNullOrEmpty(tTopic)) // tTopic != null) { if (!ParseSimplex(tTopic, recvMessage, pQSender)) //NEW:2.06 - No More Local Host processing here { if (TheBaseAssets.MyServiceHostInfo.MaximumHops == 0 || recvMessage.HobCount() < TheBaseAssets.MyServiceHostInfo.MaximumHops) { if (!tTopic.StartsWith("CDE_CONNECT") || !TheBaseAssets.MyServiceHostInfo.AllowMessagesInConnect) // Should never get here if AllowMessagesInConnect is false, but avoid global publish just in case... { TheCDEKPIs.IncrementKPI(eKPINames.CCTSMsRelayed); TheCommCore.PublishCentral(tTopic, recvMessage, false, null, false, pQSender?.MyTargetNodeChannel?.IsTrustedSender ?? false); } else { // Message is part of a CDE_CONNECT: Republish it to enable single-post message sending (i.e. MSB/Service Gateway scenario) TheCDEKPIs.IncrementKPI(eKPINames.CCTSMsRelayed); // TODO SHould we have a separate KPI for this TheCommCore.PublishCentral(recvMessage, true, pQSender.MyTargetNodeChannel.IsTrustedSender); } } } else { if (pQSender?.MyTargetNodeChannel != null && pQSender?.MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_JAVAJASON) { SendPulse = true; } } } } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(319, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", "Execute Command Parsing Error", eMsgLevel.l1_Error, ee.ToString())); } TheBaseAssets.MySYSLOG.WriteToLog(286, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Done with Do Execute Command for Topic:{tTopic}", eMsgLevel.l7_HostDebugMessage)); } } if (pRequestData.WebSocket == null) { if (DoSendBackBuffer) { SetResponseBuffer(pRequestData, pQSender.MyTargetNodeChannel, SendPulse, ""); } else if (SendPulse) { pQSender.SendPickupMessage(); //Pickup next message right away if pulse mode is on } } TheBaseAssets.MySYSLOG.WriteToLog(286, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", "Leave Do Execute Command", eMsgLevel.l7_HostDebugMessage)); }
public void Disconnect() { TheQueuedSenderRegistry.UnregisterHealthTimer(sinkTimer); TheThing.SetSafePropertyBool(MyBaseThing, "IsConnected", false); }
internal static string InfoHeader(bool IsSmall) { //string ret = $"<h3>{TheBaseAssets.MyServiceHostInfo.MyAppPresenter}</h3><h1>{TheBaseAssets.MyServiceHostInfo.ApplicationTitle} V{TheBaseAssets.MyServiceHostInfo.CurrentVersion}</h1><h3>Hosted at: {TheBaseAssets.LocalHostQSender.MyTargetNodeChannel}<br/>NodeName: {TheBaseAssets.MyServiceHostInfo.NodeName}</br>AppName:{TheBaseAssets.MyServiceHostInfo.ApplicationName}<br/>lcd: {TheBaseAssets.MyServiceHostInfo.BaseDirectory}</br>CDE:V{TheBaseAssets.CurrentVersionInfo} Drop: {TheBaseAssets.BuildVersion}</br>Started:{TheCommonUtils.GetDateTimeString(TheBaseAssets.MyServiceHostInfo.cdeCTIM, -1)}"; string ret2 = $"<h3>{TheBaseAssets.MyServiceHostInfo.MyAppPresenter}</h3>"; //<div id=\"mainBox\" style=\"width-fixed:90%;display:flex; flex-flow: column wrap\"> ret2 += $"<h1 id=\"title\">{TheBaseAssets.MyServiceHostInfo.ApplicationTitle} V{TheBaseAssets.MyServiceHostInfo.CurrentVersion}</h1>"; if (TheBaseAssets.MyServiceHostInfo.ShowMarkupInLog) { ret2 += $"<script>var cdeCSOn; function cdeColorSpan(pContent, pColor) {{ var x = document.getElementsByClassName(\"cdeRSHash\");var i;for (i = 0; i < x.length; i++){{ if (!pContent) {{ if (!cdeCSOn) x[i].style.backgroundColor = \"transparent\"; }} else {{ if (pContent.innerText==x[i].innerText && !cdeCSOn) x[i].style.backgroundColor = pColor; }}}}}}</script>"; } ret2 += $"<div class=\"cdeInfoBlock\" style=\"width:750px;\"><div class=\"cdeInfoBlockHeader cdeInfoBlockHeaderText\" id=\"nodeInfo\">Node Info</div><table style=\"margin-left:2%\">"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right; min-width:200px;\">Hosted at:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.LocalHostQSender.MyTargetNodeChannel.ToMLString(true)}</td></tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Node ID:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheCommonUtils.GetDeviceIDML(TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID)}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Node Name:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.MyServiceHostInfo.NodeName}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Station Name:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.MyServiceHostInfo.MyStationName}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Application Name:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.MyServiceHostInfo.ApplicationName}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">OS Info:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left;word-wrap: break-word;max-width:540px \">{TheBaseAssets.MyServiceHostInfo.OSInfo}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Local Dir:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.MyServiceHostInfo.BaseDirectory}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">CDE Info:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.CurrentVersionInfo}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">CDE Drop:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">V{TheBaseAssets.BuildVersion}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">CDE Crypto:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheBaseAssets.MySecrets.CryptoVersion()}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Unique Meshes Connected:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheQueuedSenderRegistry.GetUniqueMeshCount()}</td><tr>"; string tScope = ""; if (TheBaseAssets.MyScopeManager.IsScopingEnabled) { tScope = GetScopeHashML(TheBaseAssets.MyScopeManager.GetScopeHash(null)); } ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Local Node-Scope:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{(TheBaseAssets.MyScopeManager.IsScopingEnabled ? $"A local Scope is set. Hash: {tScope}" : "Scoping is disabled")}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Client Cert Thumbprint:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{(TheBaseAssets.MyServiceHostInfo.ClientCertificateThumb?.Length > 3 ? $"{TheBaseAssets.MyServiceHostInfo.ClientCertificateThumb.Substring(0, 4)}" : $"No client certificate specified")}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Node Started at:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheCommonUtils.GetDateTimeString(TheBaseAssets.MyServiceHostInfo.cdeCTIM, -1)}</td><tr>"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right\">Last Update at:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{TheCommonUtils.GetDateTimeString(DateTimeOffset.Now, -1)}</td><tr>"; ret2 += "</table>"; if (!IsSmall) { ret2 += $"<h2>Service Routes:</h2><table style=\"margin-left:2%\">"; ret2 += $"<tr><th scope=\"rowgroup;\" style=\"background-color:rgba(90,90,90, 0.15); padding:3px; text-align:right; width:200px;\">Configured Routes:</th><td style=\"border-bottom:1px solid rgba(90, 90, 90, 0.25);padding:3px;text-align:left \">{(string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ServiceRoute) ? "No Routes are configured" : $"{TheBaseAssets.MyServiceHostInfo.ServiceRoute}")}</td></tr>";
internal static bool ParseSimplex(string pScopedTopic, TSM pMessage, TheQueuedSender pQSender) //, TheSessionState pSessionState, Action<TSM> pLocalCallback) { if (pMessage == null) { return(false); } #if !JC_COMMDEBUG try { #endif if (pMessage?.TXT?.Equals("CDE_DELETEORPHAN") == true) { TheQueuedSenderRegistry.RemoveOrphan(TheCommonUtils.CGuid(pMessage.PLS)); return(false); } if (pQSender == null) { TheBaseAssets.MySYSLOG.WriteToLog(291, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"QSender not found! Received from ORG:{TheCommonUtils.GetDeviceIDML(pMessage?.ORG)}", eMsgLevel.l1_Error, pMessage?.PLS)); return(false); } //SECURITY-REVIEW: This cannot be permitted without extra tokens and Encryption! otherwise it can be used to change a nodes scope on the fly! //if ("CDE_UPDATESCOPE".Equals(pMessage.TXT)) //{ // pQSender.UpdateSubscriptionScope(TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID)); //GRSI: rare // return true; //} if (pQSender != null && pMessage.ENG?.StartsWith(eEngineName.ContentService) == true && pMessage?.TXT == "CDE_SERVICE_INFO" && pQSender.MyTargetNodeChannel?.RealScopeID == TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID)) { try { pQSender.SetNodeInfo(TheCommonUtils.DeserializeJSONStringToObject <TheNodeInfoClone>(pMessage?.PLS)); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(23056, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Error decoding SystemInfo {pQSender?.MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error, e.ToString())); } } if (pMessage.TXT?.Equals("CDE_SUBSCRIBE") == true || pMessage.TXT?.Equals("CDE_INITIALIZE") == true) //9-9-2012 CDEC Did not work right on CDE_INIT { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Subscribe from {pQSender?.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage?.PLS}", eMsgLevel.l7_HostDebugMessage)); if (pQSender?.MyISBlock != null && !TheBaseAssets.MyServiceHostInfo.IsCloudService) { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", "Parse-Simplex Subscribe rejected for Custom ISBConnect", eMsgLevel.l7_HostDebugMessage)); return(true); } ParseSubscribe(pMessage.PLS, pQSender); if (pMessage.ENG.Equals("CLOUDSYNC")) { string[] tTopics = pMessage.PLS.Split(';'); foreach (string t in tTopics) { TSM.GetScrambledIDFromTopic(t, out string tEng); if (TheThingRegistry.IsEngineRegistered(tEng)) { IBaseEngine tsBase = TheThingRegistry.GetBaseEngine(tEng); tsBase?.GetBaseThing()?.FireEvent(eEngineEvents.NewSubscription, tsBase.GetBaseThing(), pQSender.MyTargetNodeChannel, true); } } return(true); } else { TheThing tBase2 = TheThingRegistry.GetBaseEngineAsThing(pMessage.ENG); if (tBase2 != null) { tBase2.FireEvent(eEngineEvents.NewSubscription, tBase2, pQSender.MyTargetNodeChannel, true); } } if (pMessage.TXT.Equals("CDE_SUBSCRIBE")) //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node { return(true); } else { return(false); } } if (pMessage.TXT?.Equals("CDE_UNSUBSCRIBE") == true) { TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Unsubscribe from {pQSender.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage.PLS}", eMsgLevel.l7_HostDebugMessage)); ParseUnsubscribe(pMessage.PLS, pQSender); return(true); //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node } #if !JC_COMMDEBUG } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(316, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", "Parse-Simplex", eMsgLevel.l1_Error, ee.ToString())); } #endif return(false); }