def __init__(self): # pragma: NO COVER ''' Components derived from ContainerServices must invoke this constructor! Automatically taken care of in PySimpleClient objects. Parameters: None Raises: Nothing ''' #Name of this component if applicable self.__name = None #Name of this component container if applicable self.__contname = None #Token given to us by manager self.__token = None #Handle give to us by manager self.__handle = None #Logger for this client self.__logger = None #Provides access to the ACS CDB self.__cdb_access = CDBaccess() #The real container/client method(s) invoked by this classes methods. #In doing this, we can hide the container/client completely as long #as it invokes the setAll(...) method. self.activateOffShootMethod = None
def __init__(self, name, charCompRef): ''' Constructor Params: - name is the quite literally the name of the property - charCompRef is the characteristic component object which contains this property Returns: Nothing Raises: Nothing. ''' #just call the superclass constructor Property.__init__(self, name, charCompRef) #setup a default value for all attributes self.cdbDict = {} try: #need access to the CDB to determine characteristics of this property cdbAccess = CDBaccess() #make sure the entry exists first of all... t_xml = cdbAccess.getField( "alma/" + self._get_characteristic_component_name()) #create an xml helper object xml_obj = XmlObject(xmlString=t_xml) #get the top-level element xml_obj = xml_obj.firstChild t_prop_name = self._get_name().split('/')[1] #get the property we're looking for xml_obj = xml_obj.getElementsByTagName(t_prop_name)[0] #setup the CDB dict using attributes found within the CDB for attr in xml_obj.attributes.keys(): self.cdbDict[attr] = xml_obj.getAttribute(attr) except: #print_exc() self.getLogger().logWarning( "Some problem occurred when attempting to retrieve data from the ACS CDB for: alma/" + self._get_characteristic_component_name() + "/" + self._get_name().split('/')[1]) return
def __init__(self, name, charCompRef): ''' Constructor Params: - name is the quite literally the name of the property - charCompRef is the characteristic component object which contains this property Returns: Nothing Raises: Nothing. ''' #just call the superclass constructor Property.__init__(self, name, charCompRef) #setup a default value for all attributes self.cdbDict = {} try: #need access to the CDB to determine characteristics of this property cdbAccess = CDBaccess() #make sure the entry exists first of all... t_xml = cdbAccess.getField("alma/" + self._get_characteristic_component_name()) #create an xml helper object xml_obj = XmlObject(xmlString = t_xml) #get the top-level element xml_obj = xml_obj.firstChild t_prop_name = self._get_name().split('/')[1] #get the property we're looking for xml_obj = xml_obj.getElementsByTagName(t_prop_name)[0] #setup the CDB dict using attributes found within the CDB for attr in xml_obj.attributes.keys(): self.cdbDict[attr] = xml_obj.getAttribute(attr) except: #print_exc() self.getLogger().logWarning("Some problem occurred when attempting to retrieve data from the ACS CDB for: alma/" + self._get_characteristic_component_name() + "/" + self._get_name().split('/')[1]) return
def get_cdb_access(): # pragma: NO COVER ''' This function is only around to fix some problems with pydoc documentation issues. That is, CDBaccess() cannot be called globally or everything NC-related breaks. ''' global _cdb_access if _cdb_access == None: _cdb_access = CDBaccess() return _cdb_access
# later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more # details. # # You should have received a copy of the GNU Library General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning # ALMA should be addressed as follows: # # Internet email: [email protected] #------------------------------------------------------------------------ from Acspy.Common.CDBAccess import CDBaccess print "------------------------------------------------------------------" print "Creating CDBaccess..." g = CDBaccess() print "------------------------------------------------------------------" print "Invoking getField on CDB/alma/MOUNT1" h = g.getField("alma/MOUNT1") if h == None: print "There was some sort of problem getting the XML record" print "------------------------------------------------------------------" print "Invoking getElement on actAz property of CDB/alma/MOUNT1" h = g.getElement("alma/MOUNT1", "MOUNT/actAz") print "Alarm high off is: ", h[0]['alarm_high_off'] print "------------------------------------------------------------------" print "Done!"
class ContainerServices(object): ''' Class ContainerServices provides components and PySimpleClients with ACS and CORBA services. Developers should never instantiate this class directly. That is, ContainerServices is a baseclass and is functionally useless until its setAll method has been invoked properly. ''' #-------------------------------------------------------------------------- def __init__(self): # pragma: NO COVER ''' Components derived from ContainerServices must invoke this constructor! Automatically taken care of in PySimpleClient objects. Parameters: None Raises: Nothing ''' #Name of this component if applicable self.__name = None #Name of this component container if applicable self.__contname = None #Token given to us by manager self.__token = None #Handle give to us by manager self.__handle = None #Logger for this client self.__logger = None #Provides access to the ACS CDB self.__cdb_access = CDBaccess() #The real container/client method(s) invoked by this classes methods. #In doing this, we can hide the container/client completely as long #as it invokes the setAll(...) method. self.activateOffShootMethod = None #-------------------------------------------------------------------------- def getName(self): # pragma: NO COVER ''' Returns our name. Parameters: None Return: name of the component or client derived from ContainerServices. Raises: Nothing ''' return self.__name #-------------------------------------------------------------------------- def getContName(self): # pragma: NO COVER ''' Returns our container name. Parameters: None Return: name of the container the component was started by. Raises: Nothing ''' return self.__contname #-------------------------------------------------------------------------- def getCDBRecord(self, record_name): # pragma: NO COVER ''' Returns the stringified version of an XML record in the ACS configuration database defined by record_name. Parameters: - record_name is the full name of an XML record in the CDB. An example would be "alma/MOUNT1". Return: the stringified XML record Raises: ??? ''' return self.__cdb_access.getField(record_name) #-------------------------------------------------------------------------- def getCDBElement(self, record_name, ele_name): # pragma: NO COVER ''' This method returns all of the attributes in the form of a dictionary for a given XML element within an XML file. Parameters: - record_name is the name of the XML file (e.g., "alma/MOUNT1") - ele_name is the name of the element (e.g, "MOUNT/actAz") - element_name is the name of the element (e.g, "MOUNT/actAz", where acsAz is an XML element contianing all attributes representing the characteristics of a BACI property). Return: a dictionary Raises: ??? ''' return self.__cdb_access.getElement(record_name, ele_name) #-------------------------------------------------------------------------- def getLogger(self): ''' Returns the component/client logger. Parameters: None Return: a logger Raises: Nothing ''' if not self.__logger: self.__logger = getLogger(self.__name) return self.__logger #-------------------------------------------------------------------------- def getComponent(self, comp_name=None, activate=CORBA.TRUE, comp_idl_type=None, comp_code=None, container_name=None, is_dynamic=0): ''' NOTE: all keyword parameters with the exception of comp_name are deprecated! Get a component reference from the Manager. This seemingly simple method is actually quite complicated. First, its important to note that this method narrows the reference for the developer and even imports the proper IDL Python stub. Under certain circumstances though, the IDL Python stub may NOT exist in the correct place which has led some developers to believe this method was broken in the past. So if you see an error message beginning with "Unable to import...", please check that you really CAN import the CORBA stubs for the component you are trying to access using the infamous "python -i" command. The next important thing to realize is this method does not just retrieve named components as its own name implies - based on the parameters passed it could return default and dynamic components also. Parameters: - name is the components name. If not None and the rest of the default parameters are left as-is, this is assumed to be a static component. - activate tells manager whether the component should be activated if it has not already been instantiated. Not too useful. - comp_idl_type is the interface repository IDL location of the component. If not None and the rest of the default parameters are left as-is, it is assumed the developer wants a default component. - comp_code is a shared library implementing component. If not None, it is assumed the developer wants a dynamic component. - container_name is the name of the container to activate component. If not None, it is assumed the developer wants a dynamic component. - is_dynamic states whether a component should be retrieved as default or dynamic. In simple terms, when this parameter and comp_idl_type are the only params that have been changed from their original values, this is the difference between retrieving a reference to a dynamic component or a default component. Returns: a narrowed reference to the component or None if that reference cannot be obtained. Raises: CannotGetComponentExImpl if the component stubs cannot be loaded or found ''' #if the user is trying to get a "normal" static component if (comp_name is not None) and (comp_idl_type is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): #Import the correct Python CORBA stub for the developer. comp_class = self.__importComponentStubs(comp_name, comp_idl_type) #get the component from manager corba_obj = getManager().get_component(self.__handle, comp_name, activate) #return the narrowed reference component = self.__narrowComponentReference(corba_obj, comp_class) #if the user is trying to get a static default component elif (comp_idl_type is not None) and (comp_name is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): component = self.getDefaultComponent(str(comp_idl_type)) #user must be trying to get a dynamic component else: component = self.getDynamicComponent(comp_name, comp_idl_type, comp_code, container_name) try: component.find_characteristic('foo') except CORBA.Exception, ex: component.find_characteristic('foo') return component
class ContainerServices(object): ''' Class ContainerServices provides components and PySimpleClients with ACS and CORBA services. Developers should never instantiate this class directly. That is, ContainerServices is a baseclass and is functionally useless until its setAll method has been invoked properly. ''' #-------------------------------------------------------------------------- def __init__(self): # pragma: NO COVER ''' Components derived from ContainerServices must invoke this constructor! Automatically taken care of in PySimpleClient objects. Parameters: None Raises: Nothing ''' #Name of this component if applicable self.__name = None #Name of this component container if applicable self.__contname = None #Token given to us by manager self.__token = None #Handle give to us by manager self.__handle = None #Logger for this client self.__logger = None #Provides access to the ACS CDB self.__cdb_access = CDBaccess() #The real container/client method(s) invoked by this classes methods. #In doing this, we can hide the container/client completely as long #as it invokes the setAll(...) method. self.activateOffShootMethod = None #-------------------------------------------------------------------------- def getName(self): # pragma: NO COVER ''' Returns our name. Parameters: None Return: name of the component or client derived from ContainerServices. Raises: Nothing ''' return self.__name #-------------------------------------------------------------------------- def getContName(self): # pragma: NO COVER ''' Returns our container name. Parameters: None Return: name of the container the component was started by. Raises: Nothing ''' return self.__contname #-------------------------------------------------------------------------- def getCDBRecord(self, record_name): # pragma: NO COVER ''' Returns the stringified version of an XML record in the ACS configuration database defined by record_name. Parameters: - record_name is the full name of an XML record in the CDB. An example would be "alma/MOUNT1". Return: the stringified XML record Raises: ??? ''' return self.__cdb_access.getField(record_name) #-------------------------------------------------------------------------- def getCDBElement(self, record_name, ele_name): # pragma: NO COVER ''' This method returns all of the attributes in the form of a dictionary for a given XML element within an XML file. Parameters: - record_name is the name of the XML file (e.g., "alma/MOUNT1") - ele_name is the name of the element (e.g, "MOUNT/actAz") - element_name is the name of the element (e.g, "MOUNT/actAz", where acsAz is an XML element contianing all attributes representing the characteristics of a BACI property). Return: a dictionary Raises: ??? ''' return self.__cdb_access.getElement(record_name, ele_name) #-------------------------------------------------------------------------- def getLogger(self): ''' Returns the component/client logger. Parameters: None Return: a logger Raises: Nothing ''' if not self.__logger: self.__logger = getLogger(self.__name) return self.__logger #-------------------------------------------------------------------------- def getComponent(self, comp_name=None, activate=CORBA.TRUE, comp_idl_type=None, comp_code=None, container_name=None, is_dynamic=0): ''' NOTE: all keyword parameters with the exception of comp_name are deprecated! Get a component reference from the Manager. This seemingly simple method is actually quite complicated. First, its important to note that this method narrows the reference for the developer and even imports the proper IDL Python stub. Under certain circumstances though, the IDL Python stub may NOT exist in the correct place which has led some developers to believe this method was broken in the past. So if you see an error message beginning with "Unable to import...", please check that you really CAN import the CORBA stubs for the component you are trying to access using the infamous "python -i" command. The next important thing to realize is this method does not just retrieve named components as its own name implies - based on the parameters passed it could return default and dynamic components also. Parameters: - name is the components name. If not None and the rest of the default parameters are left as-is, this is assumed to be a static component. - activate tells manager whether the component should be activated if it has not already been instantiated. Not too useful. - comp_idl_type is the interface repository IDL location of the component. If not None and the rest of the default parameters are left as-is, it is assumed the developer wants a default component. - comp_code is a shared library implementing component. If not None, it is assumed the developer wants a dynamic component. - container_name is the name of the container to activate component. If not None, it is assumed the developer wants a dynamic component. - is_dynamic states whether a component should be retrieved as default or dynamic. In simple terms, when this parameter and comp_idl_type are the only params that have been changed from their original values, this is the difference between retrieving a reference to a dynamic component or a default component. Returns: a narrowed reference to the component or None if that reference cannot be obtained. Raises: CannotGetComponentExImpl if the component stubs cannot be loaded or found ''' #if the user is trying to get a "normal" static component if (comp_name is not None) and (comp_idl_type is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): #Import the correct Python CORBA stub for the developer. comp_class = self.__importComponentStubs(comp_name, comp_idl_type) #get the component from manager corba_obj = getManager().get_component(self.__handle, comp_name, activate) #return the narrowed reference return self.__narrowComponentReference(corba_obj, comp_class) #if the user is trying to get a static default component elif (comp_idl_type is not None) and (comp_name is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): return self.getDefaultComponent(str(comp_idl_type)) #user must be trying to get a dynamic component else: return self.getDynamicComponent(comp_name, comp_idl_type, comp_code, container_name) #-------------------------------------------------------------------------- def __importComponentStubs(self, comp_name=None, comp_type=None): ''' Helper method tries to automatically import the CORBA stubs for a developer. In the event that this fails, a critical message is logged. Parameters: comp_name - name of the component comp_type - IFR type of the component Notes: at least one of the parameters above has be a string Returns: the component class CORBA stub Raises: CannotGetComponentExImpl if type is unknown or import fails ''' t_idl_type = comp_type if (comp_name is not None) and (comp_type is None): #Get a list of all components components = self.availableComponents(comp_name) #search each Component for component in components: #for the one that has the given name if component.name == comp_name: #get that component's IR location #e.g., "IDL:alma/PS/PowerSupply:1.0" t_idl_type = component.type break if t_idl_type is None: #getting this far means the component was not #found ex = CannotGetComponentExImpl() ex.setReason("Component type unavailable!") self.__logger.logWarning("Unable to import '" + str(comp_name) + "' component's module: " + ex.getReason()) raise ex try: #extract the proper Python module from the type string. #("alma", "PS", "PowerSupply") temp = t_idl_type.split(':')[1].split('/') #component's class name comp_class = temp.pop() #"PowerSupply" #components module name comp_module = temp.pop() #"PS" #Now import the real module comp_module = __import__(comp_module, globals(), locals(), [comp_class]) #import it #get class reference comp_class = comp_module.__dict__.get(comp_class) except Exception, e: #for some reason or another, the module could not be imported. #this is not a total failure so it's just logged. self.__logger.logWarning("Unable to import '" + str(comp_name) + "' component's module: " + str(e)) acsPrintExcDebug() raise CannotGetComponentExImpl(e) return comp_class
class ContainerServices: ''' Class ContainerServices provides components and PySimpleClients with ACS and CORBA services. Developers should never instantiate this class directly. That is, ContainerServices is a baseclass and is functionally useless until its setAll method has been invoked properly. ''' #-------------------------------------------------------------------------- def __init__(self): # pragma: NO COVER ''' Components derived from ContainerServices must invoke this constructor! Automatically taken care of in PySimpleClient objects. Parameters: None Raises: Nothing ''' #Name of this component if applicable self.__name = None #Name of this component container if applicable self.__contname = None #Token given to us by manager self.__token = None #Handle give to us by manager self.__handle = None #Logger for this client self.__logger = None #Provides access to the ACS CDB self.__cdb_access = CDBaccess() #The real container/client method(s) invoked by this classes methods. #In doing this, we can hide the container/client completely as long #as it invokes the setAll(...) method. self.activateOffShootMethod = None #-------------------------------------------------------------------------- def getName(self): # pragma: NO COVER ''' Returns our name. Parameters: None Return: name of the component or client derived from ContainerServices. Raises: Nothing ''' return self.__name #-------------------------------------------------------------------------- def getContName(self): # pragma: NO COVER ''' Returns our container name. Parameters: None Return: name of the container the component was started by. Raises: Nothing ''' return self.__contname #-------------------------------------------------------------------------- def getCDBRecord(self, record_name): # pragma: NO COVER ''' Returns the stringified version of an XML record in the ACS configuration database defined by record_name. Parameters: - record_name is the full name of an XML record in the CDB. An example would be "alma/MOUNT1". Return: the stringified XML record Raises: ??? ''' return self.__cdb_access.getField(record_name) #-------------------------------------------------------------------------- def getCDBElement(self, record_name, ele_name): # pragma: NO COVER ''' This method returns all of the attributes in the form of a dictionary for a given XML element within an XML file. Parameters: - record_name is the name of the XML file (e.g., "alma/MOUNT1") - ele_name is the name of the element (e.g, "MOUNT/actAz") - element_name is the name of the element (e.g, "MOUNT/actAz", where acsAz is an XML element contianing all attributes representing the characteristics of a BACI property). Return: a dictionary Raises: ??? ''' return self.__cdb_access.getElement(record_name, ele_name) #-------------------------------------------------------------------------- def getLogger(self): ''' Returns the component/client logger. Parameters: None Return: a logger Raises: Nothing ''' if not self.__logger: self.__logger = getLogger(self.__name) return self.__logger #-------------------------------------------------------------------------- def getComponent(self, comp_name=None, activate=CORBA.TRUE, comp_idl_type=None, comp_code=None, container_name=None, is_dynamic=0): ''' NOTE: all keyword parameters with the exception of comp_name are deprecated! Get a component reference from the Manager. This seemingly simple method is actually quite complicated. First, its important to note that this method narrows the reference for the developer and even imports the proper IDL Python stub. Under certain circumstances though, the IDL Python stub may NOT exist in the correct place which has led some developers to believe this method was broken in the past. So if you see an error message beginning with "Unable to import...", please check that you really CAN import the CORBA stubs for the component you are trying to access using the infamous "python -i" command. The next important thing to realize is this method does not just retrieve named components as its own name implies - based on the parameters passed it could return default and dynamic components also. Parameters: - name is the components name. If not None and the rest of the default parameters are left as-is, this is assumed to be a static component. - activate tells manager whether the component should be activated if it has not already been instantiated. Not too useful. - comp_idl_type is the interface repository IDL location of the component. If not None and the rest of the default parameters are left as-is, it is assumed the developer wants a default component. - comp_code is a shared library implementing component. If not None, it is assumed the developer wants a dynamic component. - container_name is the name of the container to activate component. If not None, it is assumed the developer wants a dynamic component. - is_dynamic states whether a component should be retrieved as default or dynamic. In simple terms, when this parameter and comp_idl_type are the only params that have been changed from their original values, this is the difference between retrieving a reference to a dynamic component or a default component. Returns: a narrowed reference to the component or None if that reference cannot be obtained. Raises: CannotGetComponentExImpl if the component stubs cannot be loaded or found ''' #if the user is trying to get a "normal" static component if (comp_name is not None) and (comp_idl_type is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): #Import the correct Python CORBA stub for the developer. comp_class = self.__importComponentStubs(comp_name, comp_idl_type) #get the component from manager corba_obj = getManager().get_component(self.__handle, comp_name, activate) #return the narrowed reference return self.__narrowComponentReference(corba_obj, comp_class) #if the user is trying to get a static default component elif (comp_idl_type is not None) and (comp_name is None) and \ (comp_code is None) and (container_name is None) and \ (is_dynamic == 0): return self.getDefaultComponent(str(comp_idl_type)) #user must be trying to get a dynamic component else: return self.getDynamicComponent(comp_name, comp_idl_type, comp_code, container_name) #-------------------------------------------------------------------------- def __importComponentStubs(self, comp_name=None, comp_type=None): ''' Helper method tries to automatically import the CORBA stubs for a developer. In the event that this fails, a critical message is logged. Parameters: comp_name - name of the component comp_type - IFR type of the component Notes: at least one of the parameters above has be a string Returns: the component class CORBA stub Raises: CannotGetComponentExImpl if type is unknown or import fails ''' t_idl_type = comp_type if (comp_name is not None) and (comp_type is None): #Get a list of all components components = self.availableComponents() #search each Component for component in components: #for the one that has the given name if component.name == comp_name: #get that component's IR location #e.g., "IDL:alma/PS/PowerSupply:1.0" t_idl_type = component.type break if t_idl_type is None: #getting this far means the component was not #found ex = CannotGetComponentExImpl() ex.setReason("Component type unavailable!") self.__logger.logWarning("Unable to import '" + str(comp_name) + "' component's module: " + ex.getReason()) raise ex try: #extract the proper Python module from the type string. #("alma", "PS", "PowerSupply") temp = t_idl_type.split(':')[1].split('/') #component's class name comp_class = temp.pop() #"PowerSupply" #components module name comp_module = temp.pop() #"PS" #Now import the real module comp_module = __import__(comp_module, globals(), locals(), [comp_class]) #import it #get class reference comp_class = comp_module.__dict__.get(comp_class) except Exception, e: #for some reason or another, the module could not be imported. #this is not a total failure so it's just logged. self.__logger.logWarning("Unable to import '" + str(comp_name) + "' component's module: " + str(e)) acsPrintExcDebug() raise CannotGetComponentExImpl(e) return comp_class
#storage for "static data" that can be shared between components _GLOBALS = {} #namespace of individual components COMPONENTS_NS = {} COMPONENTS_NS_LIST = {} #described simulated behavior of the components _COMP_PROXIES = {} #maps component names to component instances _COMP_REFS = {} #first get access to the CDB CDB_ACCESS = CDBaccess() #each key in this dictionary consists of the stingified channel and the value #is a supplier object for said channel. _SUPPLIERS_DICT = {} #------------------------------------------------------------------------------ def addComponent(comp_name, comp_ref): ''' Adds a component to the singled dictionary contained within this module. This is in place to be called by the simulator framework and probably isn't of much use to end-users. Parameters: comp_name - name of the component in string format