using System; using ln.application; using System.Threading; using ln.logging; using ln.application.service; using ln.skyscanner.entities; using ln.skyscanner.checks; using System.Collections.Generic; using ln.types.threads; using System.Linq; using ln.snmp; using ln.types.odb.ng; namespace ln.skyscanner.services { public class CheckService : ApplicationServiceBase { public static bool DEBUG = false; Pool checkPool; EntityService entityService; PerformanceValueService performanceValueService; public EntityService EntityService => entityService; public PerformanceValueService PerformanceValueService => performanceValueService; public SNMPEngine SNMPEngine { get; private set; } SkyScanner.Service coreService; CheckServiceRPC RPC; public CheckService() :base("Check Service") { DependOnService(); DependOnService(); DependOnService(); } public override void ServiceMain(IApplicationInterface applicationInterface) { coreService = Dependency(); entityService = Dependency(); performanceValueService = Dependency(); Dictionary checkJobs = new Dictionary(); HashSet currentNodes = new HashSet(); checkPool = new Pool(96); SNMPEngine = new SNMPEngine(); SNMPEngine.Timeout = 2000; long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds(); RPC = new CheckServiceRPC(this); coreService.RPCContainer.Add("CheckService",RPC); Ready(); while (!StopRequested) { Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts"); currentNodes.Clear(); foreach (Node node in entityService.NodeCollection) { currentNodes.Add(node); if (!checkJobs.ContainsKey(node)) { CheckJob checkJob = new CheckJob(this,node); checkJobs.Add(node, checkJob); } } foreach (Node node in checkJobs.Keys.ToArray()) { currentNodes.Remove(node); } if (currentNodes.Count > 0) { foreach (Node node in currentNodes) { checkJobs.Remove(node); } } currentNodes.Clear(); foreach (CheckJob checkJob in checkJobs.Values) { checkJob.Prepare(); } Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): currently knows {0} checks", checkJobs.Count); Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): currently {0} checks alive", checkPool.NumQueuedJobs); Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", checkPool.Enqueue(checkJobs.Values)); while (true) { while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0) nextMinute += 60000; try { Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds())); break; } catch (ThreadInterruptedException) { Logging.Log(LogLevel.INFO, "CheckService: scheduler was interrupted"); if (StopRequested) break; } } } coreService.RPCContainer.Remove("CheckService"); entityService = null; performanceValueService = null; coreService = null; } public SkyCheckState[] GetCheckStates(Node node) { Query stateQuery = Query.Equals("Node", node.ID); SkyCheckState[] skyCheckStates = entityService.SkyCheckStates.SelectQuery(stateQuery).ToArray(); Dictionary checkStates = new Dictionary(); foreach (SkyCheckState checkState in skyCheckStates) { checkStates.Add(checkState.CheckName, checkState); } foreach (SkyCheck check in SkyCheck.SkyChecks) { if (!checkStates.ContainsKey(check.Name) && check.IsValid(node)) { checkStates.Add(check.Name, check.PrepareCheckState(this, node)); entityService.SkyCheckStates.Insert(checkStates[check.Name]); } } return checkStates.Values.ToArray(); } class CheckServiceRPC { CheckService checkService; public CheckServiceRPC(CheckService checkService) { this.checkService = checkService; } public Node[] GetIssueList() { List nodes = new List(); foreach (Node node in checkService.EntityService.NodeCollection) { foreach (SkyCheckState checkState in node.CheckStates) { if (!String.Empty.Equals(node.Vendor) && ((checkState.CheckState != CheckState.OK) || ((checkState.UnchangedTime < TimeSpan.FromMinutes(10)) && (checkState.History.Length > 1)))){ nodes.Add(node); break; } } } return nodes.ToArray(); } } } }