def _process_request(self, request, message): """Process request in separate thread and reply back.""" # parse broker message first to get the `reply_to` and the `task_uuid` # parameters to have possibility to reply back try: reply_to, task_uuid = self._parse_message(message) except ValueError as e: LOG.error("Failed to parse broker message: %s" % e) return else: # prepare task progress callback progress_callback = functools.partial( self._on_update_progress, reply_to, task_uuid) # prepare reply callback reply_callback = functools.partial( self._reply, reply_to, task_uuid) # parse request to get task name, action and action arguments try: task, action, action_args = self._parse_request(**request) action_args.update(task_uuid=task_uuid, progress_callback=progress_callback) except ValueError as e: LOG.error("Failed to parse request: %s" % e) reply_callback(result=pu.failure_to_dict(misc.Failure())) return # get task endpoint try: endpoint = self._endpoints[task] except KeyError: LOG.error("The '%s' task endpoint does not exist." % task) reply_callback(result=pu.failure_to_dict(misc.Failure())) return else: reply_callback(state=pr.RUNNING) # perform task action try: result = getattr(endpoint, action)(**action_args) except Exception as e: LOG.error("The %s task execution failed: %s" % (endpoint, e)) reply_callback(result=pu.failure_to_dict(misc.Failure())) else: if isinstance(result, misc.Failure): reply_callback(result=pu.failure_to_dict(result)) else: reply_callback(state=pr.SUCCESS, result=result)
def _format_task_detail(task_detail): return { 'failure': p_utils.failure_to_dict(task_detail.failure), 'meta': task_detail.meta, 'name': task_detail.name, 'results': task_detail.results, 'state': task_detail.state, 'version': task_detail.version, }
def request(self): """Return json-serializable task request, converting all `misc.Failure` objects into dictionaries. """ request = dict(task=self._name, task_name=self._task.name, task_version=self._task.version, action=self._action, arguments=self._arguments) if 'result' in self._kwargs: result = self._kwargs['result'] if isinstance(result, misc.Failure): request['result'] = ('failure', pu.failure_to_dict(result)) else: request['result'] = ('success', result) if 'failures' in self._kwargs: failures = self._kwargs['failures'] request['failures'] = {} for task, failure in failures.items(): request['failures'][task] = pu.failure_to_dict(failure) return request
def test_parse_request_with_failure_result(self): failure = misc.Failure.from_exception(Exception('test')) failure_dict = pu.failure_to_dict(failure) request = self.request(action='revert', result=('failure', failure_dict)) task, action, task_args = server.Server._parse_request(**request) self.assertEqual((task, action, task_args), (self.task_name, 'revert', dict(task_name=self.task_name, arguments=self.task_args, result=utils.FailureMatcher(failure))))
def test_on_message_state_failure(self): failure = misc.Failure.from_exception(Exception('test')) failure_dict = pu.failure_to_dict(failure) response = dict(state=pr.FAILURE, result=failure_dict) ex = self.executor() ex._store_remote_task(self.remote_task_mock) ex._on_message(response, self.message_mock) self.assertEqual(len(ex._remote_tasks), 0) self.assertEqual( self.remote_task_mock.mock_calls, [mock.call.set_result(result=utils.FailureMatcher(failure))]) self.assertEqual(self.message_mock.mock_calls, [mock.call.ack()])
def test_on_message_state_failure(self): failure = misc.Failure.from_exception(Exception('test')) failure_dict = pu.failure_to_dict(failure) response = dict(state=pr.FAILURE, result=failure_dict) ex = self.executor() ex._store_remote_task(self.remote_task_mock) ex._on_message(response, self.message_mock) self.assertEqual(len(ex._remote_tasks), 0) self.assertEqual(self.remote_task_mock.mock_calls, [ mock.call.set_result(result=utils.FailureMatcher(failure)) ]) self.assertEqual(self.message_mock.mock_calls, [mock.call.ack()])
def test_parse_request_with_failures(self): failures = [misc.Failure.from_exception(Exception('test1')), misc.Failure.from_exception(Exception('test2'))] failures_dict = dict((str(i), pu.failure_to_dict(f)) for i, f in enumerate(failures)) request = self.request(action='revert', failures=failures_dict) task, action, task_args = server.Server._parse_request(**request) self.assertEqual( (task, action, task_args), (self.task_name, 'revert', dict(task_name=self.task_name, arguments=self.task_args, failures=dict((str(i), utils.FailureMatcher(f)) for i, f in enumerate(failures)))))
def test_parse_request_with_failures(self): failures = [ misc.Failure.from_exception(Exception('test1')), misc.Failure.from_exception(Exception('test2')) ] failures_dict = dict( (str(i), pu.failure_to_dict(f)) for i, f in enumerate(failures)) request = self.request(action='revert', failures=failures_dict) task, action, task_args = server.Server._parse_request(**request) self.assertEqual((task, action, task_args), (self.task_name, 'revert', dict(task_name=self.task_name, arguments=self.task_args, failures=dict( (str(i), utils.FailureMatcher(f)) for i, f in enumerate(failures)))))
def test_request_with_failures(self): failure = misc.Failure.from_exception(RuntimeError('Woot!')) remote_task = self.remote_task(failures={self.task.name: failure}) request = self.remote_task_request( failures={self.task.name: pu.failure_to_dict(failure)}) self.assertEqual(remote_task.request, request)
def test_request_with_result_failure(self): failure = misc.Failure.from_exception(RuntimeError('Woot!')) remote_task = self.remote_task(result=failure) request = self.remote_task_request( result=('failure', pu.failure_to_dict(failure))) self.assertEqual(remote_task.request, request)
def process_bind_param(self, value, dialect): if value is None: return None return jsonutils.dumps(persistence_utils.failure_to_dict(value))