def override_clients(self, new_clients): """ Replaces the service clients with a new set of them... and makes sure they go to the right places """ #shortcut names for the import sub-services if hasattr(self.clients, "resource_registry"): self.RR = self.clients.resource_registry if hasattr(self.clients, "instrument_management"): self.IMS = self.clients.instrument_management #farm everything out to the impls self.org = OrgImpl(self.clients) self.observatory = ObservatoryImpl(self.clients) self.subsite = SubsiteImpl(self.clients) self.platform_site = PlatformSiteImpl(self.clients) self.instrument_site = InstrumentSiteImpl(self.clients) self.instrument_device = InstrumentDeviceImpl(self.clients) self.platform_device = PlatformDeviceImpl(self.clients)
def override_clients(self, new_clients): """ Replaces the service clients with a new set of them... and makes sure they go to the right places """ #shortcut names for the import sub-services # we hide these behind checks even though we expect them so that # the resource_impl_metatests will work if hasattr(self.clients, "resource_registry"): self.RR = self.clients.resource_registry if hasattr(self.clients, "data_acquisition_management"): self.DAMS = self.clients.data_acquisition_management if hasattr(self.clients, "data_product_management"): self.DPMS = self.clients.data_product_management #farm everything out to the impls self.instrument_agent = InstrumentAgentImpl(self.clients) self.instrument_agent_instance = InstrumentAgentInstanceImpl(self.clients) self.instrument_model = InstrumentModelImpl(self.clients) self.instrument_device = InstrumentDeviceImpl(self.clients) self.platform_agent = PlatformAgentImpl(self.clients) self.platform_agent_instance = PlatformAgentInstanceImpl(self.clients) self.platform_model = PlatformModelImpl(self.clients) self.platform_device = PlatformDeviceImpl(self.clients) self.sensor_model = SensorModelImpl(self.clients) self.sensor_device = SensorDeviceImpl(self.clients) #TODO: may not belong in this service self.data_product = DataProductImpl(self.clients) self.data_producer = DataProducerImpl(self.clients) self.logical_instrument = LogicalInstrumentImpl(self.clients)
class InstrumentManagementService(BaseInstrumentManagementService): """ @brief Service to manage instrument, platform, and sensor resources, their relationships, and direct access """ def on_init(self): #suppress a few "variable declared but not used" annoying pyflakes errors IonObject("Resource") log self.override_clients(self.clients) def override_clients(self, new_clients): """ Replaces the service clients with a new set of them... and makes sure they go to the right places """ #shortcut names for the import sub-services # we hide these behind checks even though we expect them so that # the resource_impl_metatests will work if hasattr(self.clients, "resource_registry"): self.RR = self.clients.resource_registry if hasattr(self.clients, "data_acquisition_management"): self.DAMS = self.clients.data_acquisition_management if hasattr(self.clients, "data_product_management"): self.DPMS = self.clients.data_product_management #farm everything out to the impls self.instrument_agent = InstrumentAgentImpl(self.clients) self.instrument_agent_instance = InstrumentAgentInstanceImpl(self.clients) self.instrument_model = InstrumentModelImpl(self.clients) self.instrument_device = InstrumentDeviceImpl(self.clients) self.platform_agent = PlatformAgentImpl(self.clients) self.platform_agent_instance = PlatformAgentInstanceImpl(self.clients) self.platform_model = PlatformModelImpl(self.clients) self.platform_device = PlatformDeviceImpl(self.clients) self.sensor_model = SensorModelImpl(self.clients) self.sensor_device = SensorDeviceImpl(self.clients) #TODO: may not belong in this service self.data_product = DataProductImpl(self.clients) self.data_producer = DataProducerImpl(self.clients) self.logical_instrument = LogicalInstrumentImpl(self.clients) ########################################################################## # # INSTRUMENT AGENT INSTANCE # ########################################################################## def create_instrument_agent_instance(self, instrument_agent_instance=None): """ create a new instance @param instrument_agent_instance the object to be created as a resource @retval instrument_agent_instance_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.instrument_agent_instance.create_one(instrument_agent_instance) def update_instrument_agent_instance(self, instrument_agent_instance=None): """ update an existing instance @param instrument_agent_instance the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.instrument_agent_instance.update_one(instrument_agent_instance) def read_instrument_agent_instance(self, instrument_agent_instance_id=''): """ fetch a resource by ID @param instrument_agent_instance_id the id of the object to be fetched @retval InstrumentAgentInstance resource """ return self.instrument_agent_instance.read_one(instrument_agent_instance_id) def delete_instrument_agent_instance(self, instrument_agent_instance_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param instrument_agent_instance_id the id of the object to be deleted @retval success whether it succeeded """ return self.instrument_agent_instance.delete_one(instrument_agent_instance_id) def find_instrument_agent_instances(self, filters=None): """ """ return self.instrument_agent_instance.find_some(filters) ########################################################################## # # INSTRUMENT AGENT # ########################################################################## def create_instrument_agent(self, instrument_agent=None): """ create a new instance @param instrument_agent the object to be created as a resource @retval instrument_agent_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.instrument_agent.create_one(instrument_agent) def update_instrument_agent(self, instrument_agent=None): """ update an existing instance @param instrument_agent the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.instrument_agent.update_one(instrument_agent) def read_instrument_agent(self, instrument_agent_id=''): """ fetch a resource by ID @param instrument_agent_id the id of the object to be fetched @retval InstrumentAgent resource """ return self.instrument_agent.read_one(instrument_agent_id) def delete_instrument_agent(self, instrument_agent_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param instrument_agent_id the id of the object to be deleted @retval success whether it succeeded """ return self.instrument_agent.delete_one(instrument_agent_id) def find_instrument_agents(self, filters=None): """ """ return self.instrument_agent.find_some(filters) ########################################################################## # # INSTRUMENT MODEL # ########################################################################## def create_instrument_model(self, instrument_model=None): """ create a new instance @param instrument_model the object to be created as a resource @retval instrument_model_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.instrument_model.create_one(instrument_model) def update_instrument_model(self, instrument_model=None): """ update an existing instance @param instrument_model the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.instrument_model.update_one(instrument_model) def read_instrument_model(self, instrument_model_id=''): """ fetch a resource by ID @param instrument_model_id the id of the object to be fetched @retval InstrumentModel resource """ return self.instrument_model.read_one(instrument_model_id) def delete_instrument_model(self, instrument_model_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param instrument_model_id the id of the object to be deleted @retval success whether it succeeded """ return self.instrument_model.delete_one(instrument_model_id) def find_instrument_models(self, filters=None): """ """ return self.instrument_model.find_some(filters) ########################################################################## # # PHYSICAL INSTRUMENT # ########################################################################## def setup_data_production_chain(self, instrument_device_id=''): """ create a data product (L0) for the instrument, and establish provenance between the corresponding data producers """ #get instrument object and instrument's data producer inst_obj = self.instrument_device.read_one(instrument_device_id) inst_pducers = self.instrument_device.find_stemming_data_producer(instrument_device_id) inst_pducer_id = inst_pducers[0] log.debug("instrument data producer id='%s'" % inst_pducer_id) #create a new data product dpms_pduct_obj = IonObject(RT.DataProduct, name=str(inst_obj.name + " L0 Product"), description=str("L0 DataProduct for " + inst_obj.name)) pduct_id = self.DPMS.create_data_product(dpms_pduct_obj) #TODO: DPMS isn't creating a data producer for new data products. not sure why. # prod_pducer_id = self.data_producer.create_one(IonObject(RT.DataProducer, name=str(inst_obj.name + " L0 Producer"), description=str("L0 DataProducer for " + inst_obj.name))) self.data_product.link_data_producer(pduct_id, prod_pducer_id) # get data product's data producer (via association) #TODO: this belongs in DPMS prod_pducers = self.data_product.find_stemming_data_producer(pduct_id) # (TODO: there should only be one assoc_id. what error to raise?) # TODO: what error to raise if there are no assoc ids? prod_pducer_id = prod_pducers[0] # instrument data producer is the parent of the data product producer #TODO: this belongs in DAMS self.data_producer.link_input_data_producer(prod_pducer_id, inst_pducer_id) #TODO: error checking def create_instrument_device(self, instrument_device=None): """ create a new instance @param instrument_device the object to be created as a resource @retval instrument_device_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ instrument_device_id = self.instrument_device.create_one(instrument_device) self.DAMS.register_instrument(instrument_device_id) #TODO: create data producer and product self.setup_data_production_chain(instrument_device_id) return instrument_device_id def update_instrument_device(self, instrument_device=None): """ update an existing instance @param instrument_device the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.instrument_device.update_one(instrument_device) def read_instrument_device(self, instrument_device_id=''): """ fetch a resource by ID @param instrument_device_id the id of the object to be fetched @retval InstrumentDevice resource """ return self.instrument_device.read_one(instrument_device_id) def delete_instrument_device(self, instrument_device_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param instrument_device_id the id of the object to be deleted @retval success whether it succeeded """ return self.instrument_device.delete_one(instrument_device_id) def find_instrument_devices(self, filters=None): """ """ return self.instrument_device.find_some(filters) ## ## ## DIRECT ACCESS ## ## def request_direct_access(self, instrument_device_id=''): """ """ # determine whether id is for physical or logical instrument # look up instrument if not # Validate request; current instrument state, policy, and other # Retrieve and save current instrument settings # Request DA channel, save reference # Return direct access channel raise NotImplementedError() pass def stop_direct_access(self, instrument_device_id=''): """ """ # Return Value # ------------ # {success: true} # raise NotImplementedError() pass ########################################################################## # # PLATFORM AGENT INSTANCE # ########################################################################## def create_platform_agent_instance(self, platform_agent_instance=None): """ create a new instance @param platform_agent_instance the object to be created as a resource @retval platform_agent_instance_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.platform_agent_instance.create_one(platform_agent_instance) def update_platform_agent_instance(self, platform_agent_instance=None): """ update an existing instance @param platform_agent_instance the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.platform_agent_instance.update_one(platform_agent_instance) def read_platform_agent_instance(self, platform_agent_instance_id=''): """ fetch a resource by ID @param platform_agent_instance_id the id of the object to be fetched @retval PlatformAgentInstance resource """ return self.platform_agent_instance.read_one(platform_agent_instance_id) def delete_platform_agent_instance(self, platform_agent_instance_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param platform_agent_instance_id the id of the object to be deleted @retval success whether it succeeded """ return self.platform_agent_instance.delete_one(platform_agent_instance_id) def find_platform_agent_instances(self, filters=None): """ """ return self.platform_agent_instance.find_some(filters) ########################################################################## # # PLATFORM AGENT # ########################################################################## def create_platform_agent(self, platform_agent=None): """ create a new instance @param platform_agent the object to be created as a resource @retval platform_agent_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.platform_agent.create_one(platform_agent) def update_platform_agent(self, platform_agent=None): """ update an existing instance @param platform_agent the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.platform_agent.update_one(platform_agent) def read_platform_agent(self, platform_agent_id=''): """ fetch a resource by ID @param platform_agent_id the id of the object to be fetched @retval PlatformAgent resource """ return self.platform_agent.read_one(platform_agent_id) def delete_platform_agent(self, platform_agent_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param platform_agent_id the id of the object to be deleted @retval success whether it succeeded """ return self.platform_agent.delete_one(platform_agent_id) def find_platform_agents(self, filters=None): """ """ return self.platform_agent.find_some(filters) ########################################################################## # # PLATFORM MODEL # ########################################################################## def create_platform_model(self, platform_model=None): """ create a new instance @param platform_model the object to be created as a resource @retval platform_model_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.platform_model.create_one(platform_model) def update_platform_model(self, platform_model=None): """ update an existing instance @param platform_model the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.platform_model.update_one(platform_model) def read_platform_model(self, platform_model_id=''): """ fetch a resource by ID @param platform_model_id the id of the object to be fetched @retval PlatformModel resource """ return self.platform_model.read_one(platform_model_id) def delete_platform_model(self, platform_model_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param platform_model_id the id of the object to be deleted @retval success whether it succeeded """ return self.platform_model.delete_one(platform_model_id) def find_platform_models(self, filters=None): """ """ return self.platform_model.find_some(filters) ########################################################################## # # PHYSICAL PLATFORM # ########################################################################## def create_platform_device(self, platform_device=None): """ create a new instance @param platform_device the object to be created as a resource @retval platform_device_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.platform_device.create_one(platform_device) def update_platform_device(self, platform_device=None): """ update an existing instance @param platform_device the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.platform_device.update_one(platform_device) def read_platform_device(self, platform_device_id=''): """ fetch a resource by ID @param platform_device_id the id of the object to be fetched @retval PlatformDevice resource """ return self.platform_device.read_one(platform_device_id) def delete_platform_device(self, platform_device_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param platform_device_id the id of the object to be deleted @retval success whether it succeeded """ return self.platform_device.delete_one(platform_device_id) def find_platform_devices(self, filters=None): """ """ return self.platform_device.find_some(filters) ########################################################################## # # SENSOR MODEL # ########################################################################## def create_sensor_model(self, sensor_model=None): """ create a new instance @param sensor_model the object to be created as a resource @retval sensor_model_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.sensor_model.create_one(sensor_model) def update_sensor_model(self, sensor_model=None): """ update an existing instance @param sensor_model the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.sensor_model.update_one(sensor_model) def read_sensor_model(self, sensor_model_id=''): """ fetch a resource by ID @param sensor_model_id the id of the object to be fetched @retval SensorModel resource """ return self.sensor_model.read_one(sensor_model_id) def delete_sensor_model(self, sensor_model_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param sensor_model_id the id of the object to be deleted @retval success whether it succeeded """ return self.sensor_model.delete_one(sensor_model_id) def find_sensor_models(self, filters=None): """ """ return self.sensor_model.find_some(filters) ########################################################################## # # PHYSICAL SENSOR # ########################################################################## def create_sensor_device(self, sensor_device=None): """ create a new instance @param sensor_device the object to be created as a resource @retval sensor_device_id the id of the new object @throws BadRequest if the incoming _id field is set @throws BadReqeust if the incoming name already exists """ return self.sensor_device.create_one(sensor_device) def update_sensor_device(self, sensor_device=None): """ update an existing instance @param sensor_device the object to be created as a resource @retval success whether we succeeded @throws BadRequest if the incoming _id field is not set @throws BadReqeust if the incoming name already exists """ return self.sensor_device.update_one(sensor_device) def read_sensor_device(self, sensor_device_id=''): """ fetch a resource by ID @param sensor_device_id the id of the object to be fetched @retval SensorDevice resource """ return self.sensor_device.read_one(sensor_device_id) def delete_sensor_device(self, sensor_device_id=''): """ delete a resource, including its history (for less ominous deletion, use retire) @param sensor_device_id the id of the object to be deleted @retval success whether it succeeded """ return self.sensor_device.delete_one(sensor_device_id) def find_sensor_devices(self, filters=None): """ """ return self.sensor_device.find_some(filters) ########################################################################## # # ASSOCIATIONS # ########################################################################## def assign_instrument_model_to_instrument_device(self, instrument_model_id='', instrument_device_id=''): self.instrument_device.link_model(instrument_device_id, instrument_model_id) def unassign_instrument_model_from_instrument_device(self, instrument_model_id='', instrument_device_id=''): self.instrument_device.unlink_model(instrument_device_id, instrument_model_id) def assign_instrument_model_to_instrument_agent(self, instrument_model_id='', instrument_agent_id=''): self.instrument_agent.link_model(instrument_agent_id, instrument_model_id) def unassign_instrument_model_from_instrument_agent(self, instrument_model_id='', instrument_agent_id=''): self.instrument_agent.unlink_model(instrument_agent_id, instrument_model_id) def assign_sensor_model_to_sensor_device(self, sensor_model_id='', sensor_device_id=''): self.sensor_device.link_model(sensor_device_id, sensor_model_id) def unassign_sensor_model_from_sensor_device(self, sensor_model_id='', sensor_device_id=''): self.sensor_device.unlink_model(sensor_device_id, sensor_model_id) def assign_platform_model_to_platform_device(self, platform_model_id='', platform_device_id=''): self.platform_device.link_model(platform_device_id, platform_model_id) def unassign_platform_model_from_platform_device(self, platform_model_id='', platform_device_id=''): self.platform_device.unlink_model(platform_device_id, platform_model_id) def assign_instrument_device_to_platform_device(self, instrument_device_id='', platform_device_id=''): self.platform_device.link_instrument(platform_device_id, instrument_device_id) def unassign_instrument_device_from_platform_device(self, instrument_device_id='', platform_device_id=''): self.platform_device.unlink_instrument(platform_device_id, instrument_device_id) def assign_logical_instrument_to_instrument_device(self, logical_instrument_id='', instrument_device_id=''): self.instrument_device.link_assignment(instrument_device_id, logical_instrument_id) def unassign_logical_instrument_from_instrument_device(self, logical_instrument_id='', instrument_device_id=''): self.instrument_device.unlink_assignment(instrument_device_id, logical_instrument_id) def assign_logical_platform_to_platform_device(self, logical_platform_id='', platform_device_id=''): self.platform_device.link_assignment(platform_device_id, logical_platform_id) def unassign_logical_platform_from_platform_device(self, logical_platform_id='', platform_device_id=''): self.platform_device.unlink_assignment(platform_device_id, logical_platform_id) def assign_platform_agent_instance_to_platform_agent(self, platform_agent_instance_id='', platform_agent_id=''): self.platform_agent.link_instance(platform_agent_id, platform_agent_instance_id) def unassign_platform_agent_instance_from_platform_agent(self, platform_agent_instance_id='', platform_agent_id=''): self.platform_agent.unlink_instance(platform_agent_id, platform_agent_instance_id) def assign_instrument_agent_instance_to_instrument_agent(self, instrument_agent_instance_id='', instrument_agent_id=''): self.instrument_agent.link_instance(instrument_agent_id, instrument_agent_instance_id) def unassign_instrument_agent_instance_from_instrument_agent(self, instrument_agent_instance_id='', instrument_agent_id=''): self.instrument_agent.unlink_instance(instrument_agent_id, instrument_agent_instance_id) # reassigning a logical instrument to an instrument device is a little bit special # TODO: someday we may be able to dig up the correct data products automatically, # but once we have them this is the function that does all the work. def reassign_logical_instrument_to_instrument_device(self, logical_instrument_id='', old_instrument_device_id='', new_instrument_device_id='', logical_data_product_ids=[], old_instrument_data_product_ids=[], new_instrument_data_product_ids=[]): """ associate a logical instrument with a physical one. this involves linking the physical instrument's data product(s) to the logical one(s). the 2 lists of data products must be of equal length, and will map 1-1 @param logical_instrument_id @param instrument_device_id @param logical_data_product_ids a list of data products associated to a logical instrument @param instrument_data_product_ids a list of data products coming from an instrument device """ def verify_dp_origin(supplied_dps, assigned_dps, instrument_id, instrument_label): """ check that the supplied dps (data products) are in the set of what's actually assigned @param supplied_dps list of data product ids @param assigned_dps list of data product ids @param instrument_id a logical or instrument device id """ badones = [] for p in supplied_dps: if not p in assigned_dps: badones.append(p) if 0 < len(badones): raise BadRequest("want to assign %s's data products, but the following were supplied " + "that don't seem to come from %s '%s': [%s]" % (instrument_label, instrument_label, instrument_id, ", ".join(badones))) log.info("Checking consistency of existing logical/instrument assignments") existing_assignments = self.instrument_device.find_having_assignment(logical_instrument_id) if 1 < len(existing_assignments): raise Inconsistent("There is more than 1 instrument device associated with logical instrument '%s'" % logical_instrument_id) log.info("Checking whether supplied logical/instrument arguments are proper") if 0 < len(existing_assignments): if not old_instrument_device_id: raise BadRequest(("Tried to assign logical instrument '%s' for the first time, but it is already " + "assigned to instrument device '%s'") % (logical_instrument_id, existing_assignments[0])) elif old_instrument_device_id != existing_assignments[0]: raise BadRequest(("Tried to reassign logical instrument '%s' from instrument device '%s' but it is " + "actually associated to instrument device '%s'") % (logical_instrument_id, old_instrument_device_id, existing_assignments[0])) # log.info("Checking whether supplied data products are proper") # existing_logical_data_products = self.logical_instrument.find_stemming_data_product(logical_instrument_id) # #TODO: need a check that all the logical data products are being provided for # # log.info("Checking whether all logical data products are provided") # if len(logical_data_product_ids) != len(existing_logical_data_products): # raise BadRequest("tried to assign logical instrument but only provided %d of %d " + # "data products" % (len(logical_data_product_ids), len(existing_logical_data_products))) # # log.info("Checking that supplied logical data products are properly rooted") # verify_dp_origin(logical_data_product_ids, # existing_logical_data_products, # logical_instrument_id, # "logical_instrument") if old_instrument_device_id: log.info("Checking that the data product to be dissociated are properly rooted") verify_dp_origin(old_instrument_data_product_ids, self.find_data_product_by_instrument_device(old_instrument_device_id), old_instrument_device_id, "instrument_device") log.info("Checking that all data products to be dissociated have been supplied") if len(logical_data_product_ids) != len(old_instrument_data_product_ids): raise BadRequest("Can't unmap %d instrument data products from %d logical products" % (len(old_instrument_data_product_ids), len(logical_data_product_ids))) log.info("Checking that supplied instrument data products are properly rooted") verify_dp_origin(new_instrument_data_product_ids, self.find_data_product_by_instrument_device(new_instrument_device_id), new_instrument_device_id, "instrument_device") log.info("Checking that all data products to be associated have been supplied") if len(logical_data_product_ids) != len(new_instrument_data_product_ids): raise BadRequest("Can't map %d instrument data products to %d logical products" % (len(new_instrument_data_product_ids), len(logical_data_product_ids))) log.info("Assigning the instruments themselves") if "" != old_instrument_device_id: self.instrument_device.unlink_assignment(old_instrument_device_id, logical_instrument_id) self.instrument_device.link_assignment(new_instrument_device_id, logical_instrument_id) # functions to link and unlink data products as appropriate def link_logical_dp_to_instrument_dp(logical_dp_id, inst_dp_id): # TODO: this should be a function call, probably to DPMS, # which sets up inst_dp to copy its data stream # directly into the logical_dp pass def unlink_logical_dp_from_instrument_dp(logical_dp_id, inst_dp_id): #TODO: undo the above pass if old_instrument_device_id: log.info("Unlinking existing instrument data product(s) from logical instrument's product(s)") map(unlink_logical_dp_from_instrument_dp, logical_data_product_ids, old_instrument_data_product_ids) log.info("Linking new instrument data products with logical instrument's product(s)") map(link_logical_dp_to_instrument_dp, logical_data_product_ids, new_instrument_data_product_ids) ############################ # # ASSOCIATION FIND METHODS # ############################ def find_instrument_model_by_instrument_device(self, instrument_device_id=''): return self.instrument_device.find_stemming_model(instrument_device_id) def find_instrument_device_by_instrument_model(self, instrument_model_id=''): return self.instrument_device.find_having_model(instrument_model_id) def find_platform_model_by_platform_device(self, platform_device_id=''): return self.platform_device.find_stemming_model(platform_device_id) def find_platform_device_by_platform_model(self, platform_model_id=''): return self.platform_device.find_having_model(platform_model_id) def find_instrument_model_by_instrument_agent(self, instrument_agent_id=''): return self.instrument_agent.find_stemming_model(instrument_agent_id) def find_instrument_agent_by_instrument_model(self, instrument_model_id=''): return self.instrument_agent.find_having_model(instrument_model_id) def find_instrument_device_by_platform_device(self, platform_device_id=''): return self.platform_device.find_stemming_instrument(platform_device_id) def find_platform_device_by_instrument_device(self, instrument_device_id=''): return self.platform_device.find_having_instrument(instrument_device_id) def find_instrument_device_by_logical_instrument(self, logical_instrument_id=''): return self.instrument_device.find_having_assignment(logical_instrument_id) def find_logical_instrument_by_instrument_device(self, instrument_device_id=''): return self.instrument_device.find_stemming_assignment(instrument_device_id) def find_platform_device_by_logical_platform(self, logical_platform_id=''): return self.platform_device.find_having_assignment(logical_platform_id) def find_logical_platform_by_platform_device(self, platform_device_id=''): return self.platform_device.find_stemming_assignment(platform_device_id) ############################ # # SPECIALIZED FIND METHODS # ############################ def find_data_product_by_instrument_device(self, instrument_device_id=''): log.debug("FIND DATA PRODUCT BY INSTRUMENT DEVICE") #init return value, a list of data products data_products = [] seen_data_producers = [] #init working set of data producers to walk data_producers = [] pducers = self.instrument_device.find_stemming_data_producer(instrument_device_id) data_producers += pducers #iterate through all un-processed data producers (could also do recursively) while 0 < len(data_producers): producer_id = data_producers.pop() if producer_id in seen_data_producers: raise Inconsistent("There is a cycle in data producers that includes '%s'" % producer_id) seen_data_producers.append(producer_id) log.debug("Analyzing data producer '%s'" % producer_id) #get any products that are associated with this data producer and return them #TODO: this belongs in DPMS new_data_products = self.data_product.find_having_data_producer(producer_id) #get any producers that receive input from this data producer #TODO: this belongs in DAMS new_data_producers = self.data_producer.find_having_input_data_producer(producer_id) log.debug("Got %d new products, %d new producers" % (len(new_data_products), len(new_data_producers))) data_products += new_data_products data_producers += new_data_producers return data_products def find_instrument_device_by_data_product(self, data_product_id=''): log.debug("FIND INSTRUMENT DEVICE BY DATA PRODUCT") #init return value, a list of instrument devices instrument_devices = [] seen_data_producers = [] #init working set of data producers to walk data_producers = [] #TODO: this belongs in DPMS pducers = self.data_product.find_stemming_data_producer(data_product_id) data_producers += pducers #iterate through all un-processed data producers (could also do recursively) while 0 < len(data_producers): producer_id = data_producers.pop() if producer_id in seen_data_producers: raise Inconsistent("There is a cycle in data producers that includes '%s'" % producer_id) seen_data_producers.append(producer_id) log.debug("Analyzing data producer '%s'" % producer_id) #get any devices that are associated with this data producer and return them new_instrument_devices = self.instrument_device.find_having_data_producer(producer_id) #get any producers that give input to this data producer #TODO: this belongs in DPMS new_data_producers = self.data_producer.find_stemming_input_data_producer(producer_id) log.debug("Got %d new devices, %d new producers" % (len(new_instrument_devices), len(new_data_producers))) instrument_devices += new_instrument_devices data_producers += new_data_producers return instrument_devices def find_data_product_by_platform_device(self, platform_device_id=''): ret = [] for i in self.find_instrument_device_by_platform_device(platform_device_id): data_products = self.find_data_product_by_instrument_device(i) for d in data_products: if not d in ret: ret.append(d) return ret ############################ # # LIFECYCLE TRANSITIONS # ############################ def set_instrument_agent_lifecycle(self, instrument_agent_id="", lifecycle_state=""): """ declare a instrument_agent to be in a given state @param instrument_agent_id the resource id """ return self.instrument_agent.advance_lcs(instrument_agent_id, lifecycle_state) def set_instrument_agent_instance_lifecycle(self, instrument_agent_instance_id="", lifecycle_state=""): """ declare a instrument_agent_instance to be in a given state @param instrument_agent_instance_id the resource id """ return self.instrument_agent_instance.advance_lcs(instrument_agent_instance_id, lifecycle_state) def set_instrument_model_lifecycle(self, instrument_model_id="", lifecycle_state=""): """ declare a instrument_model to be in a given state @param instrument_model_id the resource id """ return self.instrument_model.advance_lcs(instrument_model_id, lifecycle_state) def set_instrument_device_lifecycle(self, instrument_device_id="", lifecycle_state=""): """ declare an instrument_device to be in a given state @param instrument_device_id the resource id """ return self.instrument_device.advance_lcs(instrument_device_id, lifecycle_state) def set_platform_agent_lifecycle(self, platform_agent_id="", lifecycle_state=""): """ declare a platform_agent to be in a given state @param platform_agent_id the resource id """ return self.platform_agent.advance_lcs(platform_agent_id, lifecycle_state) def set_platform_agent_instance_lifecycle(self, platform_agent_instance_id="", lifecycle_state=""): """ declare a platform_agent_instance to be in a given state @param platform_agent_instance_id the resource id """ return self.platform_agent_instance.advance_lcs(platform_agent_instance_id, lifecycle_state) def set_platform_model_lifecycle(self, platform_model_id="", lifecycle_state=""): """ declare a platform_model to be in a given state @param platform_model_id the resource id """ return self.platform_model.advance_lcs(platform_model_id, lifecycle_state) def set_platform_device_lifecycle(self, platform_device_id="", lifecycle_state=""): """ declare a platform_device to be in a given state @param platform_device_id the resource id """ return self.platform_device.advance_lcs(platform_device_id, lifecycle_state) def set_sensor_model_lifecycle(self, sensor_model_id="", lifecycle_state=""): """ declare a sensor_model to be in a given state @param sensor_model_id the resource id """ return self.sensor_model.advance_lcs(sensor_model_id, lifecycle_state) def set_sensor_device_lifecycle(self, sensor_device_id="", lifecycle_state=""): """ declare a sensor_device to be in a given state @param sensor_device_id the resource id """ return self.sensor_device.advance_lcs(sensor_device_id, lifecycle_state)
class ObservatoryManagementService(BaseObservatoryManagementService): def on_init(self): IonObject("Resource") # suppress pyflakes error CFG, log, RT, PRED, LCS, LCE, NotFound, BadRequest, log #suppress pyflakes errors about "unused import" self.override_clients(self.clients) def override_clients(self, new_clients): """ Replaces the service clients with a new set of them... and makes sure they go to the right places """ #shortcut names for the import sub-services if hasattr(self.clients, "resource_registry"): self.RR = self.clients.resource_registry if hasattr(self.clients, "instrument_management"): self.IMS = self.clients.instrument_management #farm everything out to the impls self.org = OrgImpl(self.clients) self.observatory = ObservatoryImpl(self.clients) self.subsite = SubsiteImpl(self.clients) self.platform_site = PlatformSiteImpl(self.clients) self.instrument_site = InstrumentSiteImpl(self.clients) self.instrument_device = InstrumentDeviceImpl(self.clients) self.platform_device = PlatformDeviceImpl(self.clients) ########################################################################## # # CRUD OPS # ########################################################################## def create_marine_facility(self, org=None): """Create an Org (domain of authority) that realizes a marine facility. This Org will have set up roles for a marine facility. Shared resources, such as a device can only be registered in one marine facility Org, and additionally in many virtual observatory Orgs. The marine facility operators will have more extensive permissions and will supercede virtual observatory commands @param org Org @retval org_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ log.debug("ObservatoryManagementService.create_marine_facility(): %s" % org) # create the org org.org_type = OrgTypeEnum.MARINE_FACILITY org_id = self.clients.org_management.create_org(org) #Instantiate initial set of User Roles for this marine facility instrument_operator_role = IonObject(RT.UserRole, name=INSTRUMENT_OPERATOR_ROLE, label='Instrument Operator', description='Marine Facility Instrument Operator') self.clients.org_management.add_user_role(org_id, instrument_operator_role) observatory_operator_role = IonObject(RT.UserRole, name=OBSERVATORY_OPERATOR_ROLE, label='Observatory Operator', description='Marine Facility Observatory Operator') self.clients.org_management.add_user_role(org_id, observatory_operator_role) data_operator_role = IonObject(RT.UserRole, name=DATA_OPERATOR_ROLE, label='Data Operator', description='Marine Facility Data Operator') self.clients.org_management.add_user_role(org_id, data_operator_role) return org_id def create_virtual_observatory(self, org=None): """Create an Org (domain of authority) that realizes a virtual observatory. This Org will have set up roles for a virtual observatory. Shared resources, such as a device can only be registered in one marine facility Org, and additionally in many virtual observatory Orgs. The marine facility operators will have more extensive permissions and will supercede virtual observatory commands @param org Org @retval org_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ log.debug("ObservatoryManagementService.create_virtual_observatory(): %s" % org) # create the org org.org_type = OrgTypeEnum.VIRTUAL_OBSERVATORY org_id = self.clients.org_management.create_org(org) return org_id def create_observatory(self, observatory=None): """Create a Observatory resource. An observatory is coupled with one Org. The Org is created and associated as part of this call. @param observatory Observatory @retval observatory_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ # create the marine facility observatory_id = self.observatory.create_one(observatory) return observatory_id def read_observatory(self, observatory_id=''): """Read a Observatory resource @param observatory_id str @retval observatory Observatory @throws NotFound object with specified id does not exist """ return self.observatory.read_one(observatory_id) def update_observatory(self, observatory=None): """Update a Observatory resource @param observatory Observatory @throws NotFound object with specified id does not exist """ return self.observatory.update_one(observatory) def delete_observatory(self, observatory_id=''): """Delete a Observatory resource @param observatory_id str @throws NotFound object with specified id does not exist """ # find the org for this MF org_ids, _ = self.clients.resource_registry.find_subjects(RT.Org, PRED.hasObservatory, observatory_id, id_only=True) if len(org_ids) == 0: log.warn("ObservatoryManagementService.delete_observatory(): no org for MF " + observatory_id) else: if len(org_ids) > 1: log.warn("ObservatoryManagementService.delete_observatory(): more than 1 org for MF " + observatory_id) # TODO: delete the others and/or raise exception??? # delete the set of User Roles for this marine facility that this service created self.clients.org_management.remove_user_role(org_ids[0], INSTRUMENT_OPERATOR_ROLE) self.clients.org_management.remove_user_role(org_ids[0], OBSERVATORY_OPERATOR_ROLE) self.clients.org_management.remove_user_role(org_ids[0], DATA_OPERATOR_ROLE) # delete the org self.clients.org_management.delete_org(org_ids[0]) return self.observatory.delete_one(observatory_id) def create_subsite(self, subsite=None, parent_id=''): """Create a Subsite resource. A subsite is a frame of reference within an observatory. Its parent is either the observatory or another subsite. @param subsite Subsite @param parent_id str @retval subsite_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ subsite_id = self.subsite.create_one(subsite) if parent_id: self.subsite.link_parent(subsite_id, parent_id) return subsite_id def read_subsite(self, subsite_id=''): """Read a Subsite resource @param subsite_id str @retval subsite Subsite @throws NotFound object with specified id does not exist """ return self.subsite.read_one(subsite_id) def update_subsite(self, subsite=None): """Update a Subsite resource @param subsite Subsite @throws NotFound object with specified id does not exist """ return self.subsite.update_one(subsite) def delete_subsite(self, subsite_id=''): """Delete a subsite resource, removes assocations to parents @param subsite_id str @throws NotFound object with specified id does not exist """ self.subsite.delete_one(subsite_id) def create_platform_site(self, platform_site=None, parent_id=''): """Create a PlatformSite resource. A platform_site is a frame of reference within an observatory. Its parent is either the observatory or another platform_site. @param platform_site PlatformSite @param parent_id str @retval platform_site_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ platform_site_id = self.platform_site.create_one(platform_site) if parent_id: self.platform_site.link_parent(platform_site_id, parent_id) return platform_site_id def read_platform_site(self, platform_site_id=''): """Read a PlatformSite resource @param platform_site_id str @retval platform_site PlatformSite @throws NotFound object with specified id does not exist """ return self.platform_site.read_one(platform_site_id) def update_platform_site(self, platform_site=None): """Update a PlatformSite resource @param platform_site PlatformSite @throws NotFound object with specified id does not exist """ return self.platform_site.update_one(platform_site) def delete_platform_site(self, platform_site_id=''): """Delete a PlatformSite resource, removes assocations to parents @param platform_site_id str @throws NotFound object with specified id does not exist """ self.platform_site.delete_one(platform_site_id) def create_instrument_site(self, instrument_site=None, parent_id=''): """Create a InstrumentSite resource. A instrument_site is a frame of reference within an observatory. Its parent is either the observatory or another instrument_site. @param instrument_site InstrumentSite @param parent_id str @retval instrument_site_id str @throws BadRequest if object does not have _id or _rev attribute @throws NotFound object with specified id does not exist """ instrument_site_id = self.instrument_site.create_one(instrument_site) if parent_id: self.instrument_site.link_parent(instrument_site_id, parent_id) return instrument_site_id def read_instrument_site(self, instrument_site_id=''): """Read a InstrumentSite resource @param instrument_site_id str @retval instrument_site InstrumentSite @throws NotFound object with specified id does not exist """ return self.instrument_site.read_one(instrument_site_id) def update_instrument_site(self, instrument_site=None): """Update a InstrumentSite resource @param instrument_site InstrumentSite @throws NotFound object with specified id does not exist """ return self.instrument_site.update_one(instrument_site) def delete_instrument_site(self, instrument_site_id=''): """Delete a InstrumentSite resource, removes assocations to parents @param instrument_site_id str @throws NotFound object with specified id does not exist """ self.instrument_site.delete_one(instrument_site_id) ############################ # # ASSOCIATIONS # ############################ def assign_site_to_site(self, child_site_id='', parent_site_id=''): """Connects a child site (any subtype) to a parent site (any subtype) @param child_site_id str @param parent_site_id str @throws NotFound object with specified id does not exist """ self.RR.create_association(parent_site_id, PRED.hasSite, child_site_id) #parent_site_obj = self.subsite.read_one(parent_site_id) #parent_site_type = parent_site_obj._get_type() #self.subsite.link_site(parent_site_id, child_site_id) # TODO: MM - Commented out checks - too restrictive #if RT.Subsite == parent_site_type: # self.subsite.link_site(parent_site_id, child_site_id) #elif RT.PlatformSite == parent_site_type: # self.platform_site.link_site(parent_site_id, child_site_id) #else: # raise BadRequest("Tried to assign a child site to a %s resource" % parent_site_type) def unassign_site_from_site(self, child_site_id='', parent_site_id=''): """Disconnects a child site (any subtype) from a parent site (any subtype) @param child_site_id str @param parent_site_id str @throws NotFound object with specified id does not exist """ parent_site_obj = self.subsite.read_one(parent_site_id) parent_site_type = parent_site_obj._get_type() if RT.Subsite == parent_site_type: self.subsite.unlink_site(parent_site_id, child_site_id) elif RT.PlatformSite == parent_site_type: self.platform_site.unlink_site(parent_site_id, child_site_id) else: raise BadRequest("Tried to unassign a child site from a %s resource" % parent_site_type) def assign_instrument_device_to_instrument_site(self, instrument_device_id='', instrument_site_id=''): """Connects a instrument device to instrument site @param instrument_device_id str @param instrument_site_id str @throws NotFound object with specified id does not exist """ self.instrument_site.link_site(instrument_device_id, instrument_site_id) def unassign_instrument_device_from_instrument_site(self, instrument_device_id='', instrument_site_id=''): """Connects a instrument device to instrument site @param instrument_device_id str @param instrument_site_id str @throws NotFound object with specified id does not exist """ self.instrument_site.unlink_site(instrument_device_id, instrument_site_id) def assign_platform_device_to_platform_site(self, platform_device_id='', platform_site_id=''): """Connects a platform device to platform site @param platform_device_id str @param platform_site_id str @throws NotFound object with specified id does not exist """ self.platform_site.link_site(platform_device_id, platform_site_id) def unassign_platform_device_from_platform_site(self, platform_device_id='', platform_site_id=''): """Connects a platform device to platform site @param platform_device_id str @param platform_site_id str @throws NotFound object with specified id does not exist """ self.platform_site.unlink_site(platform_device_id, platform_site_id) def assign_site_to_observatory(self, site_id='', observatory_id=''): self.observatory.link_site(observatory_id, site_id) def unassign_site_from_observatory(self, site_id="", observatory_id=''): self.observatory.unlink_site(observatory_id, site_id) def assign_instrument_model_to_instrument_site(self, instrument_model_id='', instrument_site_id=''): self.instrument_site.link_model(instrument_site_id, instrument_model_id) def unassign_instrument_model_from_instrument_site(self, instrument_model_id='', instrument_site_id=''): self.instrument_site.unlink_model(instrument_site_id, instrument_model_id) def assign_platform_model_to_platform_site(self, platform_model_id='', platform_site_id=''): self.platform_site.link_model(platform_site_id, platform_model_id) def unassign_platform_model_from_platform_site(self, platform_model_id='', platform_site_id=''): self.platform_site.link_model(platform_site_id, platform_model_id) def assign_resource_to_observatory_org(self, resource_id='', org_id=''): if not org_id: raise BadRequest("Org id not given") if not resource_id: raise BadRequest("Resource id not given") log.debug("assign_resource_to_observatory_org: org_id=%s, resource_id=%s " % (org_id, resource_id)) self.clients.org_management.share_resource(org_id, resource_id) def unassign_resource_from_observatory_org(self, resource_id='', org_id=''): if not org_id: raise BadRequest("Org id not given") if not resource_id: raise BadRequest("Resource id not given") self.clients.org_management.unshare_resource(org_id, resource_id) ########################################################################## # # DEPLOYMENTS # ########################################################################## def deploy_instrument_device_to_instrument_site(self, instrument_device_id='', instrument_site_id=''): self.instrument_device.link_deployment(instrument_device_id, instrument_site_id) def undeploy_instrument_device_from_instrument_site(self, instrument_device_id='', instrument_site_id=''): self.instrument_device.unlink_deployment(instrument_device_id, instrument_site_id) def deploy_platform_device_to_platform_site(self, platform_device_id='', platform_site_id=''): self.platform_device.link_deployment(platform_device_id, platform_site_id) def undeploy_platform_device_from_platform_site(self, platform_device_id='', platform_site_id=''): self.platform_device.unlink_deployment(platform_device_id, platform_site_id) def deploy_as_primary_instrument_device_to_instrument_site(self, instrument_device_id='', instrument_site_id=''): self.instrument_device.assign_primary_deployment(instrument_device_id, instrument_site_id) def undeploy_primary_instrument_device_from_instrument_site(self, instrument_device_id='', instrument_site_id=''): self.instrument_device.unassign_primary_deployment(instrument_device_id, instrument_site_id) def deploy_as_primary_platform_device_to_platform_site(self, platform_device_id='', platform_site_id=''): self.platform_device.link_primary_deployment(platform_device_id, platform_site_id) def undeploy_primary_platform_device_from_platform_site(self, platform_device_id='', platform_site_id=''): self.platform_device.unlink_primary_deployment(platform_device_id, platform_site_id) ########################################################################## # # FIND OPS # ########################################################################## def find_observatories(self, filters=None): """ """ return self.observatory.find_some(filters) def find_subsites(self, filters=None): """ """ return self.site.find_some(filters) def find_instrument_sites(self, filters=None): """ """ return self.instrument_site.find_some(filters) def find_platform_sites(self, filters=None): """ """ return self.platform_site.find_some(filters) def find_org_by_observatory(self, observatory_id=''): """ """ orgs,_ = self.RR.find_subjects(RT.Org, PRED.hasResource, observatory_id, id_only=False) return orgs def find_data_product_by_platform_site(self, platform_site_id=''): ret = [] for i in self.find_instrument_device_by_platform_site(platform_site_id): for dp in self.IMS.find_data_product_by_instrument_device(i): if not dp in ret: ret.append(dp) return ret def find_related_frames_of_reference(self, input_resource_id='', output_resource_type_list=None): # the relative depth of each resource type in our tree depth = {RT.InstrumentSite: 4, RT.PlatformSite: 3, RT.Subsite: 2, RT.Observatory: 1, } input_obj = self.RR.read(input_resource_id) input_type = input_obj._get_type() #input type checking if not input_type in depth: raise BadRequest("Input resource type (got %s) must be one of %s" % (input_type, str(depth.keys()))) for t in output_resource_type_list: if not t in depth: raise BadRequest("Output resource types (got %s) must be one of %s" % (str(output_resource_type_list), str(depth.keys()))) subordinates = [x for x in output_resource_type_list if depth[x] > depth[input_type]] superiors = [x for x in output_resource_type_list if depth[x] < depth[input_type]] acc = {} acc[input_type] = [input_obj] if subordinates: # figure out the actual depth we need to go deepest_type = input_type #initial value for output_type in output_resource_type_list: if depth[deepest_type] < depth[output_type]: deepest_type = output_type log.debug("Deepest level for search will be '%s'" % deepest_type) acc = self._traverse_entity_tree(acc, input_type, deepest_type, True) if superiors: highest_type = input_type #initial value for output_type in output_resource_type_list: if depth[highest_type] > depth[output_type]: highest_type = output_type log.debug("Highest level for search will be '%s'" % highest_type) acc = self._traverse_entity_tree(acc, highest_type, input_type, False) # Don't include input type in response #TODO: maybe just remove the input resource id if input_type in acc: acc.pop(input_type) return acc def _traverse_entity_tree(self, acc, top_type, bottom_type, downward): call_list = self._build_call_list(top_type, bottom_type, downward) # reverse the list and start calling functions if downward: call_list.reverse() for (p, c) in call_list: acc = self._find_subordinate(acc, p, c) else: for (p, c) in call_list: acc = self._find_superior(acc, p, c) return acc def _build_call_list(self, top_type, bottom_type, downward): # the possible parent types that a resource can have hierarchy_dependencies = { RT.InstrumentSite: [RT.PlatformSite], RT.PlatformSite: [RT.PlatformSite, RT.Subsite], RT.Subsite: [RT.Subsite, RT.Observatory], } call_list = [] target_type = bottom_type while True: if downward and (target_type == top_type): return call_list if (not downward) and (target_type == top_type): if not (target_type in hierarchy_dependencies and target_type in hierarchy_dependencies[target_type]): return call_list for requisite_type in hierarchy_dependencies[target_type]: #should cause errors if they stray from allowed inputs call_list.append((requisite_type, target_type)) if not downward and top_type == requisite_type == target_type: return call_list #latest solved type is the latest result target_type = requisite_type def _find_subordinate(self, acc, parent_type, child_type): #acc is an accumulated dictionary if not child_type in acc: acc[child_type] = [] find_fn = { (RT.Observatory, RT.Subsite): self.observatory.find_stemming_site, (RT.Subsite, RT.Subsite): self.subsite.find_stemming_subsite, (RT.Subsite, RT.PlatformSite): self.subsite.find_stemming_platform_site, (RT.PlatformSite, RT.PlatformSite): self.platform_site.find_stemming_platform_site, (RT.PlatformSite, RT.InstrumentSite): self.platform_site.find_stemming_instrument_site, }[(parent_type, child_type)] log.debug("Subordinates: '%s'x%d->'%s'" % (parent_type, len(acc[parent_type]), child_type)) #for all parents in the acc, add all their children for parent_obj in acc[parent_type]: parent_id = parent_obj._id for child_obj in find_fn(parent_id): acc[child_type].append(child_obj) return acc def _find_superior(self, acc, parent_type, child_type): # acc is an accumualted dictionary if not parent_type in acc: acc[parent_type] = [] #log.debug("Superiors: '%s'->'%s'" % (parent_type, child_type)) #if True: # return acc find_fn = { (RT.Observatory, RT.Subsite): self.observatory.find_having_site, (RT.Subsite, RT.Subsite): self.subsite.find_having_site, (RT.Subsite, RT.PlatformSite): self.subsite.find_having_site, (RT.PlatformSite, RT.PlatformSite): self.platform_site.find_having_site, (RT.PlatformSite, RT.InstrumentSite): self.platform_site.find_having_site, }[(parent_type, child_type)] log.debug("Superiors: '%s'->'%s'x%d" % (parent_type, child_type, len(acc[child_type]))) #for all children in the acc, add all their parents for child_obj in acc[child_type]: child_id = child_obj._id for parent_obj in find_fn(child_id): acc[parent_obj._get_type()].append(parent_obj) return acc