def __ReadCollector(self,node,objNamespace,IsInGroup): objCollector = None attributes = node.attributes if None == attributes: Log.getLogger().error("Collector defined with no ID") return None else: if not IsInGroup: Frequency = None else: Frequency = 0 if "ID" in attributes.keys(): MinionID = Alias.Alias(attributes["ID"].nodeValue) objCollector = self.__CreateCollectorObject(node,objNamespace,MinionID,IsInGroup) if None == objCollector: return None else: Log.getLogger().error("Collector without ID attribute!") return None if "OverrideID" in attributes.keys(): AltID = Alias.Alias(attributes["OverrideID"].nodeValue) if not objCollector.SetOverrideID(AltID): return None if "Frequency" in attributes.keys(): if not IsInGroup: Frequency = Alias.Alias(attributes["Frequency"].nodeValue) else: Log.getLogger().warning("Collector [" + MinionID + "] specified a frequency. Ignoring since it is in a group.") if "OnlySendOnChange" in attributes.keys(): # only sends if data changes strBool = Alias.Alias(attributes["OnlySendOnChange"].nodeValue) if strBool.lower() == "true" : objCollector._SendOnlyOnDelta = True elif "SendOnlyOnChange" in attributes.keys(): # only sends if data changes strBool = Alias.Alias(attributes["SendOnlyOnChange"].nodeValue) if strBool.lower() == "true" : objCollector._SendOnlyOnDelta = True if "DoNotSend" in attributes.keys(): # Collect, but do not send strBool = Alias.Alias(attributes["DoNotSend"].nodeValue) if strBool.lower() == "true" : objCollector._DoNotSend = True if "Scale" in attributes.keys(): #Scale the data strVal = Alias.Alias(attributes["Scale"].nodeValue) if not objCollector.SetScaleValue(strVal): return None if "ProcessThread" in attributes.keys(): objCollector.SetProcessThreadID(Alias.Alias(attributes["ProcessThread"].nodeValue)) if not self.__ReadBounds(node,objCollector): return None try: _Which = 'Normalize' try: objCollector._NormalizeValue = float(Alias.Alias(node.getElementsByTagName(_Which)[0].firstChild.nodeValue)) objCollector._Normalize = True normNode = node.getElementsByTagName(_Which)[0] normAttributes = normNode.attributes if "SyncFile" in normAttributes.keys(): objCollector._SyncFile = Alias.Alias(normAttributes["SyncFile"].nodeValue) except Exception: pass _Which = 'Precision' try: strPrecision = Alias.Alias(node.getElementsByTagName(_Which)[0].firstChild.nodeValue) try: objCollector.Precision = float(strPrecision) Log.getLogger().info("Setting " + MinionID + " precision to " + strPrecision) except Exception as Ex: self.HandleInvalidXML("Invalid <Precision>: " + strPrecision + " for " + MinionID) return None except Exception: pass _Which = 'Frequency' try: objCollector._PollingInterval = int(Frequency) except Exception: if str(Frequency).lower() == "ondemand": objCollector._OnDemand = True Log.getLogger().debug("On Demand Collector Found") else: if str(Frequency).lower() == "runonce": objCollector._RunOnce = True objCollector._PollingInterval = int(objNamespace._DefaultInterval) if not IsInGroup and not objCollector.IsOnDemand() and objCollector._PollingInterval < 1: Log.getLogger().error("Collector with invalid Polling Interval: " + str(objCollector._PollingInterval)) return None except Exception as ex: self.HandleInvalidXML("Error Parsing " + _Which + " for " + MinionID + ": " + str(ex)) objCollector = None return objCollector
def __ReadBounds(self,nodeParent,objCollector): # <Bound Max="20000" Min="15555" Action="set"/> try: node = nodeParent.getElementsByTagName('Bound')[0] except: node = None if node != None: attributes = node.attributes Action = None Min = None Max = None if None == attributes: Log.getLogger().error("Collector [" + objCollector.GetID() + "] has a <Bound>, however it is empty.") return False if "Min" in attributes.keys(): Min = Alias.Alias(attributes["Min"].nodeValue) try: Min = float(Min) except: Log.getLogger().error("Collector [" + objCollector.GetID() + "] has a <Bound>, with non numeric Min specified.") return False if "Max" in attributes.keys(): Max = Alias.Alias(attributes["Max"].nodeValue) try: Max = float(Max) except: Log.getLogger().error("Collector [" + objCollector.GetID() + "] has a <Bound>, with non numeric Max specified.") return False if "Action" in attributes.keys(): Action = Alias.Alias(attributes["Action"].nodeValue) if Min == None and Max == None: Log.getLogger().error("Collector [" + objCollector.GetID() + "] has a <Bound>, with no Min or Max specified.") return False if None == Action: Action = Collector.BoundAction.Set # Make it a default elif Action.lower() == "drop": Action = Collector.BoundAction.Drop elif Action.lower() == "set": Action = Collector.BoundAction.Set elif Action.lower() == "repeatlast": Action = Collector.BoundAction.RepeatLast else: Log.getLogger().error("Collector [" + objCollector.GetID() + "] has a <Bound>, with invalid Action: " + Action) return False objCollector._Bound_Min = Min objCollector._Bound_Max = Max objCollector._Bound_Action = Action return True
def __CreateCollectorObject(self,node,objNamespace,MinionID,IsInGroup): objCollector = None try: ScriptName = Alias.Alias(node.getElementsByTagName('Executable')[0].firstChild.nodeValue) objCollector = Collector.Collector(objNamespace,MinionID,IsInGroup) objCollector._ScriptName = ScriptName try: _Which = 'Param' for param in node.getElementsByTagName(_Which): # Make an array of the params for the script strParam = Alias.Alias(param.firstChild.nodeValue) Param = CollectorParam.CheckForCollectorAsParam(strParam,objNamespace) objCollector._Parameters.append(Param) except Exception: pass try: OperatorType = Alias.Alias(node.getElementsByTagName('Operator')[0].firstChild.nodeValue) if OperatorType.lower() != "userdefined": # want to keep going if userdefined return objCollector except Exception as Ex: return objCollector except Exception: # OK, wasn't a traditional collector, let's see if it is an operator pass try: OperatorType = Alias.Alias(node.getElementsByTagName('Operator')[0].firstChild.nodeValue) if OperatorType.lower() == "addition": objCollector = Operator.Operator_Addition(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "average": objCollector = Operator.Operator_Average(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "makelist": objCollector = Operator.Operator_MakeList(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "duplicate": objCollector = Operator.Operator_Duplicate(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_eq": objCollector = Operator.Operator_Compare_EQ(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_ne": objCollector = Operator.Operator_Compare_NE(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_gt": objCollector = Operator.Operator_Compare_GT(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_ge": objCollector = Operator.Operator_Compare_GE(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_lt": objCollector = Operator.Operator_Compare_LT(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "compare_le": objCollector = Operator.Operator_Compare_LE(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "greatest": objCollector = Operator.Operator_Greatest(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "least": objCollector = Operator.Operator_Least(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "maxvalue": objCollector = Operator.Operator_MaxValue(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "minvalue": objCollector = Operator.Operator_MinValue(objNamespace,MinionID,IsInGroup) elif OperatorType.lower() == "userdefined": objCollector = Operator.Operator_UserDefined(objNamespace,MinionID,IsInGroup,objCollector) else: self.HandleInvalidXML("Unknown Operator: " + OperatorType) return None try: retVal = self.__GetOperatorInputs(node,objCollector) if retVal == 0: Log.getLogger().error("Operator Collector [" + MinionID + "] with no <Input>") return None if retVal < 1: return None except Exception as Ex: return None return objCollector except Exception as ex: # OK, wasn't a traditional collector, let's see if it is an operator self.HandleInvalidXML("Executable | Operator") return None
def __ReadShuntInfo(self, domDoc): nodeList = domDoc.getElementsByTagName("Shunt") if None != nodeList and len(nodeList) > 0: for node in nodeList: attributes = node.attributes if "ID" in attributes: ID = Alias.Alias(attributes["ID"].nodeValue) else: Log.getLogger().error("No Shunt ID specified") return False if "Namespace" in attributes: Namespace = Alias.Alias(attributes["Namespace"].nodeValue) else: Log.getLogger().error("No Shunt Namespace specified") return False Historical = False if "Type" in attributes: Type = Alias.Alias(attributes["Type"].nodeValue) if Type.lower() == "history": Historical = True else: Log.getLogger().error( "Unknown Shunt Type file specified ID=" + ID + " Namespace=" + Namespace + ": " + Type) return False ShuntFile = None if 0 != len(node.childNodes): ShuntFile = node.firstChild.nodeValue if None == ShuntFile: Log.getLogger().error("No Shunt file specified ID=" + ID + " Namespace=" + Namespace) return False NamespaceKey = Namespace.lower() IDKey = ID.lower() try: ID_Comp = re.compile(IDKey) except Exception: Log.getLogger().error( "Invalid Shunt regEx expression for ID: " + ID) return False try: _ = re.compile(NamespaceKey) except Exception: Log.getLogger().error( "Invalid Shunt regEx expression for Namespace: " + Namespace) return False if ShuntFile.lower() in self.__ShuntingFiles: if True == Historical: Log.getLogger().warn( "Sending Historical data from more than 1 data source to the same file: " + ShuntFile) else: self.__ShuntingFiles[ShuntFile.lower()] = ShuntFile dataTuple = (Namespace, ID, ShuntFile, ID_Comp, Historical) if NamespaceKey in self.__ShuntMap: IdMap = self.__ShuntMap.get(NamespaceKey) if IDKey in IdMap: Log.getLogger().error("Duplicate Shunt specified ID=" + ID + " Namespace=" + Namespace) return False else: IdMap[IDKey] = dataTuple else: IdMap = {} IdMap[IDKey] = dataTuple self.__ShuntMap[NamespaceKey] = IdMap self.__ShuntMapResolved[NamespaceKey + IDKey] = dataTuple ## Initialize the file ## try: with open(ShuntFile, "w") as sf: sf.write("##### Generated by Oscar Shunt #####\n") except Exception as _: Log.getLogger().error( "Invalid Shunt filename specified: " + ShuntFile) return False Log.getLogger().info("Creating Shunt [" + Namespace + ":" + ID + "] --> " + ShuntFile) return True
def RescanTargets(self): try: if self.GetConfFileModificationInfo( ) == Configuration.modification_date(self.GetConfigFilename()): return filename = self.GetConfigFilename() Log.getLogger().info("Re-scanning config file: " + filename) self.__ConfigFileTimeStamp = Configuration.modification_date( filename) filename = self.GetConfigFilename() #open the xml file for reading: file = open(filename, 'r') #convert to string: data = file.read() #close file because we dont need it anymore: file.close() except: return try: domDoc = xml.dom.minidom.parseString(data) except Exception as ex: self.__HandleInvalidXML("Bad Content - XML error: " + str(ex)) return nodeList = domDoc.getElementsByTagName("TargetConnection") if None != nodeList and len(nodeList) > 0: for node in nodeList: attributes = node.attributes if "IP" in attributes: IP = Alias.Alias(attributes["IP"].nodeValue) else: Log.getLogger().error("No Target IP specified") return False if "PORT" in attributes: try: Port = int(Alias.Alias(attributes["PORT"].nodeValue)) except Exception as Ex: Log.getLogger().error(str(Ex)) Log.getLogger().error( "Invalid Port set for Target Connection") return False else: Log.getLogger().error("No Target IP specified") return False connType = ConnectionType.Unknown objTarget = Target.Target( IP, Port, connType, True) # could be Marvin or another Oscar #Key = socket.gethostbyname(IP) + ":" +str(Port) Key = IP + ":" + str(Port) if not TargetManager.GetTargetManager().GetDownstreamTarget( Key): Log.getLogger().info("Adding new Downstream target: " + Key) TargetManager.GetTargetManager().AddDownstreamTarget( objTarget, Key)
def ReadConfigFile(self): if self.__HasBeenRead == True: return False self.__HasBeenRead = True filename = self.GetConfigFilename() self.__ConfigFileTimeStamp = Configuration.modification_date(filename) #open the xml file for reading: file = open(filename, 'r') #convert to string: data = file.read() #close file because we dont need it anymore: file.close() try: domDoc = xml.dom.minidom.parseString(data) except Exception as ex: self.__HandleInvalidXML("Bad Content - XML error: " + str(ex)) return False self.__ReadAliasList(domDoc) attributes = domDoc.getElementsByTagName('Oscar')[0].attributes if None != attributes: if "ID" in attributes.keys(): ID = Alias.Alias(attributes["ID"].nodeValue) if None == ID: Log.getLogger().error("No ID configured for Oscar") return False else: Log.getLogger().info("Oscar ID = " + ID) self.__ID = ID try: strVal = Alias.Alias( domDoc.getElementsByTagName('SendStatus') [0].firstChild.nodeValue) if strVal.upper() == "TRUE": self.__IsMemorex = True except Exception: pass nodeList = domDoc.getElementsByTagName("IncomingMarvinConnection") if None != nodeList and len(nodeList) > 0: attributes = nodeList[0].attributes if "IP" in attributes: self.__FromDownstreamConnection.IP = Alias.Alias( attributes["IP"].nodeValue) else: Log.getLogger().info( "No Incoming Marvin IP specified, will listen on all interfaces" ) self.__FromDownstreamConnection.IP = "0.0.0.0" if "PORT" in attributes: try: self.__FromDownstreamConnection.Port = int( Alias.Alias(attributes["PORT"].nodeValue)) except Exception as Ex: Log.getLogger().error(str(Ex)) Log.getLogger().error( "Invalid Port set for Incoming Minion Connection") return False else: Log.getLogger().info( "No Incoming Marvin Connection Port specified, will choose one" ) else: Log.getLogger().info( "Incoming Marvin Connection not defined,will choose dynamically" ) self.__FromDownstreamConnection.IP = "0.0.0.0" nodeList = domDoc.getElementsByTagName("IncomingMinionConnection") if None != nodeList and len(nodeList) > 0: attributes = nodeList[0].attributes if "IP" in attributes: self.__FromUpstreamConnection.IP = Alias.Alias( attributes["IP"].nodeValue) else: self.__FromUpstreamConnection.IP = "0.0.0.0" #listen on all interfaces Log.getLogger().info( "No IncomingMinionConnection IP specified, listening on all interfaces" ) if "PORT" in attributes: try: self.__FromUpstreamConnection.Port = int( Alias.Alias(attributes["PORT"].nodeValue)) except Exception as Ex: Log.getLogger().error(str(Ex)) Log.getLogger().error( "Invalid Port set for IncomingMinionConnection ") return False else: Log.getLogger().error( "No IncomingMinionConnection Port specified") return False else: Log.getLogger().error("IncomingMinionConnection not defined") return False OscarNode = nodeList[0].getElementsByTagName("Oscar") if None != OscarNode and len(OscarNode) > 0: Log.getLogger().info("Auto Connect Info found.") oscarAttributes = OscarNode[0].attributes if None == oscarAttributes: Log.getLogger().error("Invalid Auto Connect Configuration.") return False try: autoIP = Alias.Alias(oscarAttributes["IP"].nodeValue) autoPort = Alias.Alias(oscarAttributes["Port"].nodeValue) autoKey = Alias.Alias(oscarAttributes["Key"].nodeValue) self.SendBullHorn(autoIP, autoPort, autoKey) except Exception as Ex: Log.getLogger().error("Invalid Auto Connect Configuration.") return False if False == self.__ReadAutoConnectInfo(domDoc): return False self.__OutgoingDownstreamConnections = self.__ReadDownstreamTargets( domDoc) if None == self.GetOutgoingDownstreamConnections( ): # go read targets, if none, then Houston we have an problemo return False if False == self.__ReadShuntInfo(domDoc): return False if False == self.__ReadBumpInTheWireInfo(domDoc): return False if False == self.ReadProxyConnection(domDoc): return False if False == self.ReadProxyTargetConnection(domDoc): return False if None != self.__IncomingProxyConnection and None != self.__TargetProxyConnection: Log.getLogger().error( "An instance of Oscar for PROXY use can either be a server or client, but not both." ) return False return True
def PerformPlayFileTask(self, Params): #<?xml version="1.0" encoding="utf-8"?> #<Marvin Type="OscarTask"> # <Version>1.0</Version> # <OscarID>DemoOscar</OscarID> # <Task>Playback</Task> # <Param>speed=2</Param> #</Marvin> #<?xml version="1.0" encoding="utf-8"?> #<Marvin Type="OscarTask"> # <Version>1.0</Version> # <OscarID>DemoOscar</OscarID> # <Task>Playback</Task> # <Param>speed=2</Param> # <Param>repeat</Param> #</Marvin> #<?xml version="1.0" encoding="utf-8"?> #<Marvin Type="OscarTask"> # <Version>1.0</Version> # <OscarID>DemoOscar</OscarID> # <Task>Playback</Task> # <Param>loop</Param> # <Param>speed=2</Param> # <Param>start=10</Param> # <Param>end=2400</Param> #</Marvin> speed = 1 start = 0 end = Playback.get().GetDataCount() type = Playback.RepeatMode.NONE file = None for param in Params: tParam = Alias.Alias(param.lower()) if tParam == "repeat": type = Playback.RepeatMode.REPEAT elif tParam == "loop": type = Playback.RepeatMode.LOOP else: parts = tParam.split("=") if len(parts) == 2: if parts[0].lower() == 'start' and Utility.IsNumeric( Alias.Alias(parts[1])): start = int(parts[1]) elif parts[0].lower() == 'end' and Utility.IsNumeric( Alias.Alias(parts[1])): end = int(parts[1]) elif parts[0].lower() == 'speed' and Utility.IsNumeric( Alias.Alias(parts[1])): speed = int(parts[1]) elif parts[0].lower() == 'file': file = parts[1] if False == self.PerformLoadFileTask([file]): return end = Playback.get().GetDataCount() else: Log.getLogger().info( "Received unknown Oscar Play parameter: " + param) return else: Log.getLogger().info( "Received unknown Oscar Play parameter: " + param) return if Playback.get().GetDataCount() == 0: Log.getLogger().info("Oscar Play received - but no file loaded.") return if start >= end: Log.getLogger().info("Oscar Play Loop - but start > end.") return Log.getLogger().info("Performing Oscar task: Start Playback.") GuiMgr.OnStopRecording(True) #drop all recorded packets GuiMgr.OnStopLiveData() GuiMgr.OnSetPlaybackSpeed(speed) GuiMgr.OnSetRepeatMode(type, start, end) GuiMgr.OnStartPlayback()
def PerformInsertBookmark(self, Params): #<?xml version="1.0" encoding="utf-8"?> #<Marvin Type="OscarTask"> # <Version>1.0</Version> # <OscarID>DemoOscar</OscarID> # <UniqueID>1233456</UniqueID> # <Task>InsertBookmark</Task> # <Param>Namespace=foo</Param> # <Param>ID=TestMarker</Param> # <Param>Data=StartTest</Param> # <Param>Propagate=True</Param> -- if True, the data is sent back upstream towards Marvin #</Marvin> if len(Params) >= 3: fPropagate = False for param in Params: parts = param.split("=") if len(parts) == 2: if parts[0].lower() == 'namespace': namespace = Alias.Alias(parts[1]) elif parts[0].lower() == 'id': id = Alias.Alias(parts[1]) elif parts[0].lower() == 'data': data = Alias.Alias(parts[1]) elif parts[0].lower() == 'propagate': propagate = Alias.Alias(parts[1]) if propagate.lower() == "true": fPropagate = True else: Log.getLogger().error( "Received invalid InsertBookmark task parameter: " + str(param)) return else: Log.getLogger().error( "Received invalid InsertBookmark task. Insufficient Parameters." ) return if None == namespace: Log.getLogger().error( "Received invalid InsertBookmark task. Namespace not specified." ) return if None == id: Log.getLogger().error( "Received invalid InsertBookmark task. ID not specified.") return if None == data: Log.getLogger().error( "Received invalid InsertBookmark task. Data not specified.") return eTime = Time.GetCurrMS() objData = MarvinData.MarvinData(namespace, id, data, eTime, 1.0) if None != objData: Recorder.get().AddData(objData) GuiMgr.OnDataPacketSentDownstream(objData, "Minion") if fPropagate: TargetManager.GetTargetManager().BroadcastDownstream( objData.ToXML(), False, None)