class ResourceAgent(BaseResourceAgent): """ A resource agent is an ION process of type "agent" that exposes the standard resource agent service interface. """ process_type = "agent" # Override in subclass to publish specific types of events COMMAND_EVENT_TYPE = "ResourceCommandEvent" # Override in subclass to set specific origin type ORIGIN_TYPE = "Resource" def __init__(self, *args, **kwargs): super(ResourceAgent, self).__init__(*args, **kwargs) # The ID of the AgentInstance subtype resource object self.agent_id = None # The ID of the AgentDefinition subtype resource object self.agent_def_id = None # The ID of the target resource object, e.g. a device id self.resource_id = None def _on_init(self): log.debug("Resource Agent initializing. name=%s, resource_id=%s" % (self._proc_name, self.resource_id)) self._event_publisher = EventPublisher() def _on_quit(self): pass def negotiate(self, resource_id="", sap_in=None): pass def execute(self, resource_id="", command=None): return self._execute("rcmd_", command) def execute_agent(self, resource_id="", command=None): return self._execute("acmd_", command) def _execute(self, cprefix, command): if not command: raise iex.BadRequest("execute argument 'command' not present") if not command.command: raise iex.BadRequest("command not set") cmd_res = IonObject("AgentCommandResult", command_id=command.command_id, command=command.command) cmd_func = getattr(self, cprefix + str(command.command), None) if cmd_func: cmd_res.ts_execute = get_ion_ts() try: res = cmd_func(*command.args, **command.kwargs) cmd_res.status = 0 cmd_res.result = res except iex.IonException as ex: # TODO: Distinguish application vs. uncaught exception cmd_res.status = getattr(ex, 'status_code', -1) cmd_res.result = str(ex) log.warn("Agent command %s failed with trace=%s" % (command.command, traceback.format_exc())) else: log.info("Agent command not supported: %s" % (command.command)) ex = iex.NotFound("Command not supported: %s" % command.command) cmd_res.status = iex.NotFound.status_code cmd_res.result = str(ex) sub_type = "%s.%s" % (command.command, cmd_res.status) post_event = self._event_publisher._create_event(event_type=self.COMMAND_EVENT_TYPE, origin=self.resource_id, origin_type=self.ORIGIN_TYPE, sub_type=sub_type, command=command, result=cmd_res) post_event = self._post_execute_event_hook(post_event) success = self._event_publisher._publish_event(post_event, origin=post_event.origin) return cmd_res def _post_execute_event_hook(self, event): """ Hook to add additional values to the event object to be published @param event A filled out even object of type COMMAND_EVENT_TYPE @retval an event object """ return event def get_capabilities(self, resource_id="", capability_types=[]): capability_types = capability_types or ["CONV_TYPE", "AGT_CMD", "AGT_PAR", "RES_CMD", "RES_PAR"] cap_list = [] if "CONV_TYPE" in capability_types: cap_list.extend([("CONV_TYPE", cap) for cap in self._get_agent_conv_types()]) if "AGT_CMD" in capability_types: cap_list.extend([("AGT_CMD", cap) for cap in self._get_agent_commands()]) if "AGT_PAR" in capability_types: cap_list.extend([("AGT_PAR", cap) for cap in self._get_agent_params()]) if "RES_CMD" in capability_types: cap_list.extend([("RES_CMD", cap) for cap in self._get_resource_commands()]) if "RES_PAR" in capability_types: cap_list.extend([("RES_PAR", cap) for cap in self._get_resource_params()]) return cap_list def set_param(self, resource_id="", name='', value=''): if not hasattr(self, "rpar_%s" % name): raise iex.NotFound('Resource parameter not existing: %s' % name) pvalue = getattr(self, "rpar_%s" % name) setattr(self, "rpar_%s" % name, value) return pvalue def get_param(self, resource_id="", name=''): try: return getattr(self, "rpar_%s" % name) except AttributeError: raise iex.NotFound('Resource parameter not found: %s' % name) def set_agent_param(self, resource_id="", name='', value=''): if not hasattr(self, "apar_%s" % name): raise iex.NotFound('Agent parameter not existing: %s' % name) pvalue = getattr(self, "apar_%s" % name) setattr(self, "apar_%s" % name, value) return pvalue def get_agent_param(self, resource_id="", name=''): try: return getattr(self, "apar_%s" % name) except AttributeError: raise iex.NotFound('Agent parameter not found: %s' % name) def _get_agent_conv_types(self): return [] def _get_agent_params(self): return self._get_names(self, "apar_") def _get_agent_commands(self): return self._get_names(self, "acmd_") def _get_resource_params(self): return self._get_names(self, "rpar_") def _get_resource_commands(self): return self._get_names(self, "rcmd_") def _get_names(self, obj, prefix): return [name[len(prefix):] for name in dir(obj) if name.startswith(prefix)]