diff --git a/SAS/ResourceAssignment/Common/CMakeLists.txt b/SAS/ResourceAssignment/Common/CMakeLists.txt index 79fdc75878fdd10ddea3ad477feb57cc9e5a274f..f91fcb85cb1aaf7e8cedee6adc042288bd517c34 100644 --- a/SAS/ResourceAssignment/Common/CMakeLists.txt +++ b/SAS/ResourceAssignment/Common/CMakeLists.txt @@ -1,6 +1,6 @@ # $Id: CMakeLists.txt 30355 2014-11-04 13:46:05Z loose $ -lofar_package(RACommon 0.1 DEPENDS pyparameterset) +lofar_package(RACommon 0.1 DEPENDS pyparameterset MoMQueryService ResourceAssignmentService) include(PythonInstall) set(USE_PYTHON_COMPILATION Off) diff --git a/SAS/ResourceAssignment/Common/lib/specification.py b/SAS/ResourceAssignment/Common/lib/specification.py index e1c85b1d5d543eab2c0f2729d64ae5629022fe48..d543138287927e22866c19d27aabec579864d7a7 100644 --- a/SAS/ResourceAssignment/Common/lib/specification.py +++ b/SAS/ResourceAssignment/Common/lib/specification.py @@ -29,18 +29,20 @@ from datetime import datetime, timedelta from lofar.common.datetimeutils import parseDatetime from lofar.sas.resourceassignment.resourceassigner.schedulechecker import movePipelineAfterItsPredecessors import pprint +from types import IntType, FloatType, StringTypes """ Prefix that is common to all parset keys, when we get a parset from OTDBRPC. """ INPUT_PREFIX = "ObsSW." """ Prefix that is common to all parset keys, when we need to write a parset to OTDB """ OUTPUT_PREFIX = "LOFAR.ObsSW." -#TODO This class can use a more OO approach, it currenly exposes quite a bit of its internals and depends a bit +# TODO This class can use a more OO approach, it currenly exposes quite a bit of its internals and depends a bit # on the user of the class to enforce consistency. Given the time available, this will need to be done in a further # refactoring. -#TODO There are lot's of hardcoded OTDB key strings and values in here. -#TODO Maybe all/most the static methods should log what they're doing and no longer be static? -#TODO We can do more direct updating of OTDB and MoM from here, especially the MoM sytem spec. +# TODO There are lot's of hardcoded OTDB key strings and values in here. +# TODO Maybe all/most the static methods should log what they're doing and no longer be static? +# TODO We can do more direct updating of OTDB and MoM from here, especially the MoM sytem spec. + class Specification: def __init__(self, logger, otdbrpc, momquery, radbrpc): @@ -102,14 +104,13 @@ class Specification: result["status"] = self.status result["task_type"] = self.type result["task_subtype"] = self.subtype + result["starttime"] = str(self.starttime) + result["endtime"] = str(self.endtime) + result["duration"] = self.duration.total_seconds() result["min_starttime"] = str(self.min_starttime) - #result["max_starttime"] = str(self.max_starttime) result["max_endtime"] = str(self.max_endtime) result["min_duration"] = str(self.min_duration) result["max_duration"] = str(self.max_duration) - result["starttime"] = str(self.starttime) - result["endtime"] = str(self.endtime) - result["duration"] = self.duration.total_seconds() result["cluster"] = self.cluster result["specification"] = self.internal_dict result["specification"]["Observation.startTime"] = str(self.starttime) #TODO set/update these somewhere else? @@ -125,6 +126,28 @@ class Specification: :param input_dict: Serialized version of a Specification and any predecessors. """ + def parse_timedelta(input_value): + if input_value == u"None": + return None + elif input_value == "None": + return None + elif isinstance(input_value, IntType): + return timedelta(seconds = input_value) + elif isinstance(input_value, FloatType): + return timedelta(seconds = input_value) + else: + return input_value + + def parse_datetime(input_value): + if input_value == u"None": + return None + elif input_value == "None": + return None + elif isinstance(input_value, StringTypes): + return parseDatetime(input_value) + else: + return input_value + self.otdb_id = input_dict["otdb_id"] self.mom_id = input_dict["mom_id"] self.radb_id = input_dict["task_id"] @@ -132,12 +155,13 @@ class Specification: self.status = input_dict["status"] self.type = input_dict["task_type"] self.subtype = input_dict["task_subtype"] - self.min_starttime = parseDatetime(input_dict["min_starttime"]) - #self.max_starttime = parseDatetime(input_dict["max_starttime"]) - self.endtime = parseDatetime(input_dict["endtime"]) - self.duration = timedelta(seconds = input_dict["duration"]) - self.min_duration = timedelta(seconds = input_dict["min_duration"]) - self.max_duration = timedelta(seconds = input_dict["max_duration"]) + self.starttime = parse_datetime(input_dict["starttime"]) + self.endtime = parse_datetime(input_dict["endtime"]) + self.duration = parse_timedelta(input_dict["duration"]) + self.min_starttime = parse_datetime(input_dict["min_starttime"]) + self.max_endtime = parse_datetime(input_dict["max_endtime"]) + self.min_duration = parse_timedelta(input_dict["min_duration"]) + self.max_duration = parse_timedelta(input_dict["max_duration"]) self.cluster = input_dict["cluster"] self.internal_dict = input_dict["specification"] self.predecessors = [] @@ -498,7 +522,7 @@ class Specification: parset = parameterset(self.otdbrpc.taskGetSpecification(otdb_id=self.otdb_id)['specification']) self.logger.info('Reading parset from OTDB for task %i was successful' % self.otdb_id) - self.logger.info("parset [%s]: %s" % (self.otdb_id, pprint.pformat(parset))) + self.logger.debug("parset [%s]: %s" % (self.otdb_id, pprint.pformat(parset.dict()))) return parset @@ -526,6 +550,8 @@ class Specification: self.set_status("error") #Not catching an exception here return None self.logger.info('Reading values from OTDB for task %i was successful' % otdb_id) + self.logger.info('type: %s subtype: %s starttime: %s endtime: %s duration: %s mom_id: %s cluster: %s predecessors: %s', + self.type, self.subtype, self.starttime, self.endtime, self.duration, self.mom_id, self.cluster, predecessor_ids) return predecessor_ids @@ -588,9 +614,10 @@ class Specification: """ cluster_name = None - if self.isUnmovable(): #reservation or maintenance + if not self.isUnmovable(): #reservation or maintenance # Only assign resources for task output to known clusters - cluster_name_set =Specification._get_storage_cluster_names_from_parset(parset, PARSET_PREFIX) + cluster_name_set = Specification._get_storage_cluster_names_from_parset(parset, PARSET_PREFIX) + self.logger.info("Found cluster names in parset: %s", cluster_name_set) if str() in cluster_name_set or len(cluster_name_set) != 1: # Empty set or name is always an error.