diff --git a/tangostationcontrol/tangostationcontrol/toolkit/archiver.py b/tangostationcontrol/tangostationcontrol/toolkit/archiver.py index d30a0aa362881aceb6747ee6419dd6debe00149b..7562e88620c897bbc09c35fce92f87540d9bb04b 100644 --- a/tangostationcontrol/tangostationcontrol/toolkit/archiver.py +++ b/tangostationcontrol/tangostationcontrol/toolkit/archiver.py @@ -9,52 +9,51 @@ import json, os logger = logging.getLogger() -def parse_attribute_name(attribute_name:str): +def attribute_name_from_url(attribute_name:str): """ For some operations Tango attribute must be transformed from the form 'tango://db:port/domain/family/name/attribute' to canonical 'domain/family/name/attribute' """ - chunk_num = len(attribute_name.split('/')) - if (chunk_num==7 and attribute_name.split('/')[0]=='tango:'): + if attribute_name.startswith('tango://'): return '/'.join(attribute_name.split('/')[3:]) - else: - if (chunk_num!=4): - raise AttributeFormatException - else: - return attribute_name -def parse_device_name(device_name:str, tango_host:str = 'databaseds:10000'): + if len(attribute_name.split('/')) != 4: + raise ValueError(f"Expected attribute of format 'domain/family/name/attribute', got {attribute_name}") + + return attribute_name + +def device_name_url(device_name:str, tango_host:str = 'databaseds:10000'): """ For some operations Tango devices must be transformed from the form 'domain/family/name' to 'tango://db:port/domain/family/name' """ - chunk_num = len(device_name.split('/')) - if (chunk_num==3): - return 'tango://'+tango_host+'/'+device_name - elif (chunk_num==6 and device_name.split('/')[0]=='tango:'): + if device_name.startswith('tango://'): return device_name - else: - raise ValueError(f'{device_name} is a wrong device name') + + if len(device_name.split('/')) != 3: + raise ValueError(f"Expected device name of format 'domain/family/name', got {device_name}") + + return f"tango://{tango_host}/{device_name}" def split_tango_name(tango_fqname:str, tango_type:str): """ Helper function to split device or attribute Tango full qualified names into its components """ - if tango_type.lower()=='device': + if tango_type.lower() == 'device': try: domain, family, member = tango_fqname.split('/') return domain, family, member - except: - raise AttributeFormatException(f"Could not parse device name {tango_fqname}. Please provide FQDN, e.g. STAT/Device/1") - elif tango_type.lower()=='attribute': + except ValueError as e: + raise ValueError(f"Could not parse device name {tango_fqname}. Please provide FQDN, e.g. STAT/Device/1") from e + elif tango_type.lower() == 'attribute': try: domain, family, member, name = tango_fqname.split('/') return domain, family, member, name - except: - raise AttributeFormatException(f"Could not parse attribute name {tango_fqname}. Please provide FQDN, e.g. STAT/Device/1/Attribute") + except ValueError as e: + raise ValueError(f"Could not parse attribute name {tango_fqname}. Please provide FQDN, e.g. STAT/Device/1/Attribute") from e else: - raise ValueError(f"Invalid value: {tango_type}. Please set 'device' or 'attribute'") + raise ValueError(f"Invalid value: {tango_type}. Please provide 'device' or 'attribute'.") class Archiver(): """ @@ -190,7 +189,7 @@ class Archiver(): es_state = es.state() # ping the device server if 'FAULT' in str(es_state): raise Exception(f"{es_name} is in FAULT state") - self.cm.ArchiverAdd(parse_device_name(es_name)) + self.cm.ArchiverAdd(device_name_url(es_name)) except Exception as e: if 'already_present' in str(e): logger.warning(f"Subscriber {es_name} already present in Configuration Manager") @@ -204,7 +203,7 @@ class Archiver(): The ConfigurationManager and EventSubscriber devices must be already up and running. The archiving-DBMS must be already properly configured. """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) try: self.cm.write_attribute('SetAttributeName', attribute_name) self.cm.write_attribute('SetArchiver', es_name or self.get_next_subscriber()) @@ -250,7 +249,7 @@ class Archiver(): """ Stops the data archiving of the attribute passed as input, and remove it from the subscriber's list. """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) try: self.cm.AttributeStop(attribute_name) self.cm.AttributeRemove(attribute_name) @@ -291,7 +290,7 @@ class Archiver(): exclude_list = [a.lower() for a in exclude] attrs_list = [a.lower() for a in list(attributes_nok) if a.lower() not in exclude_list] for a in attrs_list: - attr_fullname = parse_attribute_name(a) + attr_fullname = attribute_name_from_url(a) self.remove_attribute_from_archiver(attr_fullname) def start_archiving_attribute(self, attribute_name:str): @@ -299,7 +298,7 @@ class Archiver(): Starts the archiving of the attribute passed as input. The attribute must be already present in the subscriber's list """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) try: self.cm.AttributeStart(attribute_name) except Exception as e: @@ -313,7 +312,7 @@ class Archiver(): Stops the archiving of the attribute passed as input. The attribute must be already present in the subscriber's list """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) try: self.cm.AttributeStop(attribute_name) except Exception as e: @@ -326,7 +325,7 @@ class Archiver(): """ Check if an attribute is in the archiving list """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) attributes = self.cm.AttributeSearch(attribute_name.lower()) if len(attributes)>1: # Handle case same attribute_name r/rw @@ -384,7 +383,7 @@ class Archiver(): """ Return the error related to the attribute """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) errs_dict = self.get_subscriber_errors() for e in errs_dict: if attribute_name in e: @@ -409,7 +408,7 @@ class Archiver(): """ Given an attribute name, return the event subscriber associated with it """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) # If the ConfManager manages more than one subscriber if len(self.get_subscribers())>1: for es_name in self.get_subscribers(): @@ -424,7 +423,7 @@ class Archiver(): """ Return the attribute archiving frequency in events/minute """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) if self.is_attribute_archived(attribute_name): es = DeviceProxy(self.get_attribute_subscriber(attribute_name)) freq_dict = dict((a,r) for a,r in zip(es.AttributeList,es.AttributeRecordFreqList)) @@ -438,7 +437,7 @@ class Archiver(): """ Return the attribute failure archiving frequency in events/minute """ - attribute_name = parse_attribute_name(attribute_name) + attribute_name = attribute_name_from_url(attribute_name) if self.is_attribute_archived(attribute_name): es = DeviceProxy(self.get_attribute_subscriber(attribute_name)) fail_dict = dict((a,r) for a,r in zip(es.AttributeList,es.AttributeFailureFreqList))