def _get_response(self, ctx, proxy, topic, data):
        """Process a curried message and cast the result to topic."""
        LOG.debug("Running func with context: %s", ctx.to_dict())
        data.setdefault('version', None)
        data.setdefault('args', {})

        try:
            result = proxy.dispatch(ctx, data['version'], data['method'],
                                    data.get('namespace'), **data['args'])
            return ConsumerBase.normalize_reply(result, ctx.replies)
        except greenlet.GreenletExit:
            # ignore these since they are just from shutdowns
            pass
        except rpc_common.ClientException as e:
            LOG.debug("Expected exception during message handling (%s)",
                      e._exc_info[1])
            return {
                'exc':
                rpc_common.serialize_remote_exception(e._exc_info,
                                                      log_failure=False)
            }
        except Exception:
            LOG.error(_("Exception during message handling"))
            return {
                'exc': rpc_common.serialize_remote_exception(sys.exc_info())
            }
Exemple #2
0
    def test_should_not_ignore_parent_classes_even_for_remote_ones(self):
        # We want tracebacks
        cfg.CONF.set_override('debug', True)

        error = StackNotFoundChild(stack_name='a')
        exc_info = (type(error), error, None)
        serialized = rpc_common.serialize_remote_exception(exc_info)
        remote_error = rpc_common.deserialize_remote_exception(
            serialized, ["heat.tests.test_fault_middleware"])

        wrapper = fault.FaultWrapper(None)
        msg = wrapper._error(remote_error)
        expected_message, expected_traceback = six.text_type(
            remote_error).split('\n', 1)
        expected = {
            'code': 404,
            'error': {
                'message': expected_message,
                'traceback': expected_traceback,
                'type': 'StackNotFoundChild'
            },
            'explanation': 'The resource could not be found.',
            'title': 'Not Found'
        }
        self.assertEqual(expected, msg)
Exemple #3
0
 def _to_remote_error(self, error):
     """Converts the given exception to the one with the _Remote suffix.
     """
     exc_info = (type(error), error, None)
     serialized = rpc_common.serialize_remote_exception(exc_info)
     remote_error = rpc_common.deserialize_remote_exception(
         serialized, ["heat.common.exception"])
     return remote_error
Exemple #4
0
 def _to_remote_error(self, error):
     """Converts the given exception to the one with the _Remote suffix.
     """
     exc_info = (type(error), error, None)
     serialized = rpc_common.serialize_remote_exception(exc_info)
     remote_error = rpc_common.deserialize_remote_exception(
         serialized, ["heat.common.exception"])
     return remote_error
Exemple #5
0
def marshal_response(reply=None, failure=None):
    # TODO(grs): do replies have a context?
    msg = proton.Message()
    if failure:
        failure = common.serialize_remote_exception(failure)
        data = {"failure": failure}
    else:
        data = {"response": reply}
    msg.body = jsonutils.dumps(data)
    return msg
Exemple #6
0
def marshal_response(reply=None, failure=None):
    # TODO(grs): do replies have a context?
    msg = proton.Message()
    if failure:
        failure = common.serialize_remote_exception(failure)
        data = {"failure": failure}
    else:
        data = {"response": reply}
    msg.body = jsonutils.dumps(data)
    return msg
    def reply(self, reply=None, failure=None, log_failure=True):
        marconi = _marconi_client_with_conf()

        if failure:
            failure = rpc_common.serialize_remote_exception(failure,
                                                            log_failure)

        envelope = {
            'in_reply_to': self.msg_id,
            'body': reply,
            'failure': failure,
            'reply_q': self.reply_q,
        }

        _post_envelope(marconi, envelope, self.reply_q)
    def _get_response(self, ctx, proxy, topic, data):
        """Process a curried message and cast the result to topic."""
        LOG.debug("Running func with context: %s", ctx.to_dict())
        data.setdefault('version', None)
        data.setdefault('args', {})

        try:
            result = proxy.dispatch(
                ctx, data['version'], data['method'],
                data.get('namespace'), **data['args'])
            return ConsumerBase.normalize_reply(result, ctx.replies)
        except greenlet.GreenletExit:
            # ignore these since they are just from shutdowns
            pass
        except rpc_common.ClientException as e:
            LOG.debug("Expected exception during message handling (%s)",
                      e._exc_info[1])
            return {'exc':
                    rpc_common.serialize_remote_exception(e._exc_info,
                                                          log_failure=False)}
        except Exception:
            LOG.error(_("Exception during message handling"))
            return {'exc':
                    rpc_common.serialize_remote_exception(sys.exc_info())}
    def remote_exception_helper(self, name, error):
        exc_info = (type(error), error, None)

        serialized = rpc_common.serialize_remote_exception(exc_info)
        remote_error = rpc_common.deserialize_remote_exception(
            serialized, name)
        wrapper = fault.FaultWrapper(None)
        msg = wrapper._error(remote_error)
        expected = {'code': 500,
                    'error': {'message': msg['error']['message'],
                              'traceback': None,
                              'type': 'RemoteError'},
                    'explanation': msg['explanation'],
                    'title': 'Internal Server Error'}
        self.assertEqual(expected, msg)
 def test_remote_exception(self):
     # We want tracebacks
     cfg.CONF.set_override('debug', True)
     error = heat_exc.StackNotFound(stack_name='a')
     exc_info = (type(error), error, None)
     serialized = rpc_common.serialize_remote_exception(exc_info)
     remote_error = rpc_common.deserialize_remote_exception(
         serialized, ["heat.common.exception"])
     wrapper = fault.FaultWrapper(None)
     msg = wrapper._error(remote_error)
     expected_message, expected_traceback = six.text_type(remote_error).\
         split('\n', 1)
     expected = {'code': 404,
                 'error': {'message': expected_message,
                           'traceback': expected_traceback,
                           'type': 'StackNotFound'},
                 'explanation': 'The resource could not be found.',
                 'title': 'Not Found'}
     self.assertEqual(expected, msg)
Exemple #11
0
    def remote_exception_helper(self, name, error):
        exc_info = (type(error), error, None)

        serialized = rpc_common.serialize_remote_exception(exc_info)
        remote_error = rpc_common.deserialize_remote_exception(
            serialized, name)
        wrapper = fault.FaultWrapper(None)
        msg = wrapper._error(remote_error)
        expected = {
            'code': 500,
            'error': {
                'message': msg['error']['message'],
                'traceback': None,
                'type': 'RemoteError'
            },
            'explanation': msg['explanation'],
            'title': 'Internal Server Error'
        }
        self.assertEqual(expected, msg)
Exemple #12
0
    def _send_reply(self, conn, reply=None, failure=None,
                    ending=False, log_failure=True):
        if failure:
            failure = rpc_common.serialize_remote_exception(failure,
                                                            log_failure)

        msg = {'result': reply, 'failure': failure}
        if ending:
            msg['ending'] = True

        rpc_amqp._add_unique_id(msg)

        # If a reply_q exists, add the msg_id to the reply and pass the
        # reply_q to direct_send() to use it as the response queue.
        # Otherwise use the msg_id for backward compatibility.
        if self.reply_q:
            msg['_msg_id'] = self.msg_id
            conn.direct_send(self.reply_q, rpc_common.serialize_msg(msg))
        else:
            conn.direct_send(self.msg_id, rpc_common.serialize_msg(msg))
    def _send_reply(self, conn, reply=None, failure=None,
                    ending=False, log_failure=True):
        if failure:
            failure = rpc_common.serialize_remote_exception(failure,
                                                            log_failure)

        msg = {'result': reply, 'failure': failure}
        if ending:
            msg['ending'] = True

        rpc_amqp._add_unique_id(msg)

        # If a reply_q exists, add the msg_id to the reply and pass the
        # reply_q to direct_send() to use it as the response queue.
        # Otherwise use the msg_id for backward compatibility.
        if self.reply_q:
            msg['_msg_id'] = self.msg_id
            conn.direct_send(self.reply_q, rpc_common.serialize_msg(msg))
        else:
            conn.direct_send(self.msg_id, rpc_common.serialize_msg(msg))
Exemple #14
0
    def test_serialize_remote_exception(self):
        errors = []

        def stub_error(msg, *a, **kw):
            if (a and len(a) == 1 and isinstance(a[0], dict) and a[0]):
                a = a[0]
            errors.append(str(msg) % a)

        self.stubs.Set(exceptions.LOG, 'error', stub_error)

        try:
            try:
                raise self.cls(*self.args, **self.kwargs)
            except Exception as ex:
                cls_error = ex
                if self.add_remote:
                    ex = add_remote_postfix(ex)
                raise ex
        except Exception:
            exc_info = sys.exc_info()

        serialized = exceptions.serialize_remote_exception(
            exc_info, log_failure=self.log_failure)

        failure = jsonutils.loads(serialized)

        self.assertEqual(self.clsname, failure['class'], failure)
        self.assertEqual(self.modname, failure['module'])
        self.assertEqual(self.msg, failure['message'])
        self.assertEqual([self.msg], failure['args'])
        self.assertEqual(self.kwargs, failure['kwargs'])

        # Note: _Remote prefix not stripped from tracebacks
        tb = cls_error.__class__.__name__ + ': ' + self.msg
        self.assertIn(tb, ''.join(failure['tb']))

        if self.log_failure:
            self.assertTrue(len(errors) > 0, errors)
        else:
            self.assertEqual(0, len(errors), errors)
    def test_serialize_remote_exception(self):
        errors = []

        def stub_error(msg, *a, **kw):
            if (a and len(a) == 1 and isinstance(a[0], dict) and a[0]):
                a = a[0]
            errors.append(str(msg) % a)

        self.stubs.Set(exceptions.LOG, 'error', stub_error)

        try:
            try:
                raise self.cls(*self.args, **self.kwargs)
            except Exception as ex:
                cls_error = ex
                if self.add_remote:
                    ex = add_remote_postfix(ex)
                raise ex
        except Exception:
            exc_info = sys.exc_info()

        serialized = exceptions.serialize_remote_exception(
            exc_info, log_failure=self.log_failure)

        failure = jsonutils.loads(serialized)

        self.assertEqual(self.clsname, failure['class'], failure)
        self.assertEqual(self.modname, failure['module'])
        self.assertEqual(self.msg, failure['message'])
        self.assertEqual([self.msg], failure['args'])
        self.assertEqual(self.kwargs, failure['kwargs'])

        # Note: _Remote prefix not stripped from tracebacks
        tb = cls_error.__class__.__name__ + ': ' + self.msg
        self.assertIn(tb, ''.join(failure['tb']))

        if self.log_failure:
            self.assertTrue(len(errors) > 0, errors)
        else:
            self.assertEqual(0, len(errors), errors)
Exemple #16
0
def msg_reply(conf, msg_id, reply_q, connection_pool, reply=None,
              failure=None, ending=False, log_failure=True):
    """Sends a reply or an error on the channel signified by msg_id.

    Failure should be a sys.exc_info() tuple.

    """
    with ConnectionContext(conf, connection_pool) as conn:
        if failure:
            failure = rpc_common.serialize_remote_exception(failure,
                                                            log_failure)

        msg = {'result': reply, 'failure': failure}
        if ending:
            msg['ending'] = True
        _add_unique_id(msg)
        # If a reply_q exists, add the msg_id to the reply and pass the
        # reply_q to direct_send() to use it as the response queue.
        # Otherwise use the msg_id for backward compatibility.
        if reply_q:
            msg['_msg_id'] = msg_id
            conn.direct_send(reply_q, rpc_common.serialize_msg(msg))
        else:
            conn.direct_send(msg_id, rpc_common.serialize_msg(msg))
Exemple #17
0
def msg_reply(conf, msg_id, reply_q, connection_pool, reply=None,
              failure=None, ending=False, log_failure=True):
    """Sends a reply or an error on the channel signified by msg_id.

    Failure should be a sys.exc_info() tuple.

    """
    with ConnectionContext(conf, connection_pool) as conn:
        if failure:
            failure = rpc_common.serialize_remote_exception(failure,
                                                            log_failure)

        msg = {'result': reply, 'failure': failure}
        if ending:
            msg['ending'] = True
        _add_unique_id(msg)
        # If a reply_q exists, add the msg_id to the reply and pass the
        # reply_q to direct_send() to use it as the response queue.
        # Otherwise use the msg_id for backward compatibilty.
        if reply_q:
            msg['_msg_id'] = msg_id
            conn.direct_send(reply_q, rpc_common.serialize_msg(msg))
        else:
            conn.direct_send(msg_id, rpc_common.serialize_msg(msg))