Repository :
http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
---------------------------------------------------------------
commit 10b90c3185a32d4e10cc105bd579b29b778b0dc7
Author: Peter Hatina <phatina(a)redhat.com>
Date: Mon Aug 5 10:09:07 2013 +0200
fix synchro method calls' return values
---------------------------------------------------------------
cli/lmi/shell/LMIMethod.py | 98 ++++++++++++++++++++++++++++----------------
1 files changed, 63 insertions(+), 35 deletions(-)
diff --git a/cli/lmi/shell/LMIMethod.py b/cli/lmi/shell/LMIMethod.py
index 6b60462..9a93c92 100644
--- a/cli/lmi/shell/LMIMethod.py
+++ b/cli/lmi/shell/LMIMethod.py
@@ -29,10 +29,20 @@ from LMIConstantValues import LMIConstantValuesParamProp
from LMIConstantValues import LMIConstantValuesMethodReturnType
from LMIIndicationListener import LMIIndicationListener
+from LMIJob import lmi_is_job_finished
+from LMIJob import lmi_is_job_completed
+from LMIJob import lmi_is_job_terminated
+from LMIJob import lmi_is_job_killed
+from LMIJob import lmi_is_job_exception
+from LMIJob import JOB_NOT_FINISHED
+from LMIJob import JOB_FINISH_DELAYED
+from LMIJob import JOB_FINISH_EARLY
+
from LMIUtil import LMIPassByRef
from LMIUtil import lmi_raise_or_dump_exception
from LMIUtil import lmi_cast_to_cim
from LMIUtil import lmi_transform_to_lmi
+from LMIUtil import lmi_get_item_or_default
from LMIExceptions import LMIIndicationListenerError
from LMIExceptions import LMIMethodCallError
@@ -93,16 +103,40 @@ class LMIMethod(LMIBaseObject):
if "ValueMap" in self._method.qualifiers:
self._valuemap_parameters.append(self._method.name)
- @staticmethod
- def _is_job_finished(job):
+ def __return_synchro_method_call(self, job_inst, job_refresh=True):
"""
- Checks if a job object is in finished state. The range comes from the standard.
- Returns True, if the job is in the finished state.
+ Returns a LMIReturnValue with Job output parameters set.
Arguments:
- job -- LMIInstance
+ job_inst -- LMIInstance object of the job returned from a synchronous
+ method call
+ job_refresh -- bool flag, which indicates, if the job_inst
+ needs to be refreshed
"""
- return job.JobState in range(7, 11)
+ # Adjust return value from the job object
+ if job_refresh:
+ job_inst.refresh()
+ rparams = dict(zip(job_inst.JobOutParameters.properties.keys(),
+ [x.value for x in job_inst.JobOutParameters.properties.values()]))
+ rval = rparams.pop("__ReturnValue")
+ errorstr = ""
+
+ # Is job in exception state? If so, adjust corresponding error string
+ # from job.GetError() instance
+ if lmi_is_job_exception(job_inst):
+ (refreshed, _, errorstr) = job_inst.refresh()
+ if not refreshed:
+ raise LMISynchroMethodCallError(errorstr)
+ (exc_rval, exc_rparams, exc_errorstr) = job_inst.GetError()
+ error_inst = lmi_get_item_or_default(exc_rparams, "error", None)
+ if not error_inst:
+ raise LMISynchroMethodCallError("Could not get Job error
message")
+ errorstr = error_inst.Message
+ return LMIReturnValue(
+ rval=rval,
+ rparams=rparams,
+ errorstr=errorstr
+ )
def __handle_synchro_method_call_indication(self, job_inst):
"""
@@ -123,29 +157,28 @@ class LMIMethod(LMIBaseObject):
job_inst -- LMIInstance object of the job returned from a synchronous
method call
"""
- def handle_job(ind, cond, cond_variable, job_out_params, job_exception):
+ def handle_job(ind, cond, job_finished, job_exception):
"""
LMIListener handler for synchronous method call, which uses indication means
of waiting for the job. This function is called, when a job changes its
state.
Arguments:
cond -- threading.Condition object used for thread synchronization
- cond_variable -- LMIPassByRef object used for indication, whether the
+ job_finished -- LMIPassByRef object used for indication, whether the
job has finished
- job_out_params -- job output parameters (passed by ref)
- job_exception -- exception object, if any (passed by ref)
+ job_exception -- LMIPassByRef object, which contains an exception
object,
+ if any exception was raised
"""
cond.acquire()
try:
exp_obj = ind.exported_objects()[0]
src_inst = exp_obj["SourceInstance"]
- if src_inst["JobState"] in (7, 8, 9, 10):
- job_out_params.value = src_inst["JobOutParameters"]
+ if lmi_is_job_finished(src_inst):
# Job has just finished
- cond_variable.value = True
+ job_finished.value = JOB_FINISH_DELAYED
except Exception, e:
# Notify main thread, we are not able to work with such objects
- cond_variable.value = True
+ job_finished.value = JOB_FINISH_DELAYED
job_exception.value = e
finally:
# XXX: Let's be defensive, always notify+release main thread
@@ -154,14 +187,13 @@ class LMIMethod(LMIBaseObject):
# Start indication listener
cond = threading.Condition()
- job_finished = LMIPassByRef(False)
- job_out_params = LMIPassByRef(None)
+ job_finished = LMIPassByRef(JOB_NOT_FINISHED)
job_exception = LMIPassByRef(None)
# There needs to be a pattern of at least 8 "X" in a row at the end of
the indication_name
indication_name = "synchro-method-call-XXXXXXXX"
listener = LMIIndicationListener("0.0.0.0",
LMIMethod._INDICATION_DESTINATION_PORT)
indication_name = listener.add_handler(indication_name, handle_job, cond,
job_finished,
- job_out_params, job_exception)
+ job_exception)
if not listener.start():
raise LMIIndicationListenerError("Can not start indication
listener")
@@ -223,9 +255,8 @@ class LMIMethod(LMIBaseObject):
# Check, if the job is not already in finished state,
# while we were subscribing for the indications
job_inst.refresh()
- job_finished.value = LMIMethod._is_job_finished(job_inst)
- if job_finished.value:
- job_out_params.value = job_inst.JobOutParameters
+ if lmi_is_job_finished(job_inst):
+ job_finished.value = JOB_FINISH_EARLY
# Wait for the job to finish
interrupt = False
@@ -251,8 +282,7 @@ class LMIMethod(LMIBaseObject):
if not refreshed:
job_exception.value = LMISynchroMethodCallError(errorstr)
break
- if LMIMethod._is_job_finished(job_inst):
- job_out_params.value = job_inst.JobOutParameters
+ if lmi_is_job_finished(job_inst):
listener.stop()
break
except KeyboardInterrupt:
@@ -266,11 +296,10 @@ class LMIMethod(LMIBaseObject):
self._client._delete_instance(cim_handler.path)
if job_exception.value:
raise job_exception.value
- # TODO: adjust return value from the job object
- return LMIReturnValue(
- rval=0,
- rparams={"out" : job_out_params.value}
- )
+
+ # Return the job return values, refresh the job_inst object, if we got notified
+ # about the job finish state by indication.
+ return self.__return_synchro_method_call(job_inst, job_finished.value ==
JOB_FINISH_DELAYED)
def __handle_synchro_method_call_polling(self, job_inst):
"""
@@ -287,7 +316,7 @@ class LMIMethod(LMIBaseObject):
"""
try:
sleep_time = 1
- while not LMIMethod._is_job_finished(job_inst):
+ while not lmi_is_job_finished(job_inst):
# Sleep, a bit longer in every iteration
time.sleep(sleep_time)
if sleep_time < LMIMethod._POLLING_ADAPT_MAX_WAITING_TIME:
@@ -297,11 +326,10 @@ class LMIMethod(LMIBaseObject):
raise LMISynchroMethodCallError(errorstr)
except pywbem.cim_operations.CIMError, e:
raise LMISynchroMethodCallError(e.message)
- # TODO: adjust return value from the job object
- return LMIReturnValue(
- rval=0,
- rparams={"out" : job_inst.JobOutParameters}
- )
+
+ # Return the job return values. No need to refresh the job instance, we already
+ # have a "fresh" one.
+ return self.__return_synchro_method_call(job_inst, False)
def __call__(self, *args, **kwargs):
"""
@@ -365,7 +393,7 @@ class LMIMethod(LMIBaseObject):
handled_by_indication = False
if not synchro_method_polling:
try:
- (rval, call_rparams, _) =
self.__handle_synchro_method_call_indication(job_inst)
+ (rval, call_rparams, call_errorstr) =
self.__handle_synchro_method_call_indication(job_inst)
handled_by_indication = True
except pywbem.CIMError, e:
lmi_raise_or_dump_exception(e)
@@ -393,7 +421,7 @@ class LMIMethod(LMIBaseObject):
if not handled_by_indication:
# Executed, when LMIListener can not be started
try:
- (rval, call_rparams, _) =
self.__handle_synchro_method_call_polling(job_inst)
+ (rval, call_rparams, call_errorstr) =
self.__handle_synchro_method_call_polling(job_inst)
except LMISynchroMethodCallError, e:
lmi_raise_or_dump_exception(e)
return LMIReturnValue(