def advance_lcs(self, resource_id, new_state): """ attempt to advance the lifecycle state of a resource @resource_id the resource id @new_state the new lifecycle state """ # check that the resource exists resource = self.RR.read(resource_id) resource_type = self._get_resource_type(resource) # check that we've been handed the correct object if not resource_type == self.iontype: raise NotImplementedError("Attempted to change lifecycle of a %s in a %s module" % (resource_type, self.iontype)) # get the workflow that we need restype_workflow = lcs_workflows.get(resource_type, None) if not restype_workflow: restype_workflow = lcs_workflows['Resource'] # check that the transition is possible possible_transitions = restype_workflow.get_predecessors(new_state) if not resource.lcstate in possible_transitions: actions = [] for st, tr in possible_transitions.iteritems(): actions.append("%s -> %s" % (str(st), str(tr))) raise NotImplementedError(("Attempted to change lifecycle of a %s from %s to %s; " + "supported transitions are {%s}->%s") % (self.iontype, resource.lcstate, new_state, ", ".join(actions), new_state)) # check that precondition function exists if not new_state in self.lcs_precondition: raise NotImplementedError( "Lifecycle precondition method '%s' not defined for %s!" % (new_state, self.iontype)) precondition_fn = self.lcs_precondition[new_state] # check that the precondition is met if not precondition_fn(resource_id): raise BadRequest(("Couldn't transition %s to state %s; " + "failed precondition") % (self.iontype, new_state)) # get the transition event that takes us where we want to go transition_event = possible_transitions[resource.lcstate] log.debug("Moving %s resource life cycle to %s with transition event %s" % (self.iontype, new_state, transition_event)) ret = self.RR.execute_lifecycle_transition(resource_id=resource_id, transition_event=transition_event) log.debug("Result of lifecycle transition was %s" % str(ret)) return ret
def execute_lifecycle_transition(self, resource_id='', transition_event='', current_lcstate=''): self.assert_condition(not current_lcstate or current_lcstate in LCS, "Unknown life-cycle state %s" % current_lcstate) res_obj = self.read(resource_id) if current_lcstate and res_obj.lcstate != current_lcstate: raise Inconsistent("Resource id=%s lcstate is %s, expected was %s" % ( resource_id, res_obj.lcstate, current_lcstate)) restype = type(res_obj).__name__ restype_workflow = lcs_workflows.get(restype, None) if not restype_workflow: restype_workflow = lcs_workflows['Resource'] new_state = restype_workflow.get_successor(res_obj.lcstate, transition_event) if not new_state: raise Inconsistent("Resource id=%s, type=%s, lcstate=%s has no transition for event %s" % ( resource_id, restype, res_obj.lcstate, transition_event)) res_obj.lcstate = new_state res_obj.ts_updated = get_ion_ts() updres = self.resource_registry.update(res_obj) return new_state