def _call(addr, context, msg_id, topic, msg, timeout=None): # timeout_response is how long we wait for a response timeout = timeout or CONF.rpc_response_timeout # The msg_id is used to track replies. msg_id = uuid.uuid4().hex # Replies always come into the reply service. reply_topic = "zmq_replies.%s" % CONF.rpc_zmq_host LOG.debug(_("Creating payload")) # Curry the original request into a reply method. mcontext = RpcContext.marshal(context) payload = { 'method': '-reply', 'args': { 'msg_id': msg_id, 'context': mcontext, 'topic': reply_topic, 'msg': [mcontext, msg] } } LOG.debug(_("Creating queue socket for reply waiter")) # Messages arriving async. # TODO(ewindisch): have reply consumer with dynamic subscription mgmt with Timeout(timeout, exception=rpc_common.Timeout): try: msg_waiter = ZmqSocket("ipc://%s/zmq_topic_zmq_replies" % CONF.rpc_zmq_ipc_dir, zmq.SUB, subscribe=msg_id, bind=False) LOG.debug(_("Sending cast")) _cast(addr, context, msg_id, topic, payload) LOG.debug(_("Cast sent; Waiting reply")) # Blocks until receives reply msg = msg_waiter.recv() LOG.debug(_("Received message: %s"), msg) LOG.debug(_("Unpacking response")) responses = _deserialize(msg[-1]) # ZMQError trumps the Timeout error. except zmq.ZMQError: raise RPCException("ZMQ Socket Error") finally: if 'msg_waiter' in vars(): msg_waiter.close() # It seems we don't need to do all of the following, # but perhaps it would be useful for multicall? # One effect of this is that we're checking all # responses for Exceptions. for resp in responses: if isinstance(resp, types.DictType) and 'exc' in resp: raise rpc_common.deserialize_remote_exception(CONF, resp['exc']) return responses[-1]
def test_should_not_ignore_parent_classes_even_for_remote_ones(self): # We want tracebacks cfg.CONF.set_override('debug', True) cfg.CONF.set_override('allowed_rpc_exception_modules', ['heat.tests.test_fault_middleware']) 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( cfg.CONF, serialized) wrapper = fault.FaultWrapper(None) msg = wrapper._error(remote_error) expected_message, expected_traceback = str(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)
def _call(addr, context, msg_id, topic, msg, timeout=None): # timeout_response is how long we wait for a response timeout = timeout or FLAGS.rpc_response_timeout # The msg_id is used to track replies. msg_id = str(uuid.uuid4().hex) # Replies always come into the reply service. reply_topic = "zmq_replies.%s" % FLAGS.rpc_zmq_host LOG.debug(_("Creating payload")) # Curry the original request into a reply method. mcontext = RpcContext.marshal(context) payload = { 'method': '-reply', 'args': { 'msg_id': msg_id, 'context': mcontext, 'topic': reply_topic, 'msg': [mcontext, msg] } } LOG.debug(_("Creating queue socket for reply waiter")) # Messages arriving async. # TODO(ewindisch): have reply consumer with dynamic subscription mgmt with Timeout(timeout, exception=rpc_common.Timeout): try: msg_waiter = ZmqSocket( "ipc://%s/zmq_topic_zmq_replies" % FLAGS.rpc_zmq_ipc_dir, zmq.SUB, subscribe=msg_id, bind=False ) LOG.debug(_("Sending cast")) _cast(addr, context, msg_id, topic, payload) LOG.debug(_("Cast sent; Waiting reply")) # Blocks until receives reply msg = msg_waiter.recv() LOG.debug(_("Received message: %s"), msg) LOG.debug(_("Unpacking response")) responses = _deserialize(msg[-1]) # ZMQError trumps the Timeout error. except zmq.ZMQError: raise RPCException("ZMQ Socket Error") finally: if 'msg_waiter' in vars(): msg_waiter.close() # It seems we don't need to do all of the following, # but perhaps it would be useful for multicall? # One effect of this is that we're checking all # responses for Exceptions. for resp in responses: if isinstance(resp, types.DictType) and 'exc' in resp: raise rpc_common.deserialize_remote_exception(FLAGS, resp['exc']) return responses[-1]
def __call__(self, data): """The consume() callback will call this. Store the result.""" if data["failure"]: failure = data["failure"] self._result = rpc_common.deserialize_remote_exception(self._conf, failure) elif data.get("ending", False): self._got_ending = True else: self._result = data["result"]
def _process_data(self, data): result = None self.msg_id_cache.check_duplicate_message(data) if data["failure"]: failure = data["failure"] result = rpc_common.deserialize_remote_exception(self._conf, failure) elif data.get("ending", False): self._got_ending = True else: result = data["result"] return result
def __call__(self, data): """The consume() callback will call this. Store the result.""" if data['failure']: failure = data['failure'] self._result = rpc_common.deserialize_remote_exception(self._conf, failure) elif data.get('ending', False): self._got_ending = True else: self._result = data['result']
def _process_data(self, data): result = None self.msg_id_cache.check_duplicate_message(data) if data['failure']: failure = data['failure'] result = rpc_common.deserialize_remote_exception( self._conf, failure) elif data.get('ending', False): self._got_ending = True else: result = data['result'] return result
def __call__(self, data): """The consume() callback will call this. Store the result.""" self.msg_id_cache.check_duplicate_message(data) if data['failure']: failure = data['failure'] self._result = rpc_common.deserialize_remote_exception(self._conf, failure) elif data.get('ending', False): self._got_ending = True else: self._result = data['result']
def test_remote_exception(self): 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(cfg.CONF, serialized) wrapper = fault.FaultWrapper(None) msg = wrapper._error(remote_error) expected_message, expected_traceback = str(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(msg, expected)
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(cfg.CONF, serialized) 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)
def test_should_not_ignore_parent_classes_even_for_remote_ones(self): # We want tracebacks cfg.CONF.set_override("debug", True) cfg.CONF.set_override("allowed_rpc_exception_modules", ["heat.tests.test_fault_middleware"]) 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(cfg.CONF, serialized) 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)
def test_should_not_ignore_parent_classes_even_for_remote_ones(self): # We want tracebacks cfg.CONF.set_override('debug', True) cfg.CONF.set_override('allowed_rpc_exception_modules', ['heat.tests.test_fault_middleware']) 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(cfg.CONF, serialized) wrapper = fault.FaultWrapper(None) msg = wrapper._error(remote_error) expected_message, expected_traceback = str(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)
def _call(addr, context, topic, msg, timeout=None, envelope=False): # timeout_response is how long we wait for a response timeout = timeout or CONF.rpc_response_timeout # The msg_id is used to track replies. msg_id = uuid.uuid4().hex # Replies always come into the reply service. reply_topic = "zmq_replies.%s" % CONF.rpc_zmq_host LOG.debug(_("Creating payload")) # Curry the original request into a reply method. mcontext = RpcContext.marshal(context) payload = { 'method': '-reply', 'args': { 'msg_id': msg_id, 'topic': reply_topic, # TODO(ewindisch): safe to remove mcontext in I. 'msg': [mcontext, msg] } } LOG.debug(_("Creating queue socket for reply waiter")) # Messages arriving async. # TODO(ewindisch): have reply consumer with dynamic subscription mgmt with Timeout(timeout, exception=rpc_common.Timeout): try: msg_waiter = ZmqSocket( "ipc://%s/zmq_topic_zmq_replies.%s" % (CONF.rpc_zmq_ipc_dir, CONF.rpc_zmq_host), zmq.SUB, subscribe=msg_id, bind=False ) LOG.debug(_("Sending cast")) _cast(addr, context, topic, payload, envelope) LOG.debug(_("Cast sent; Waiting reply")) # Blocks until receives reply msg = msg_waiter.recv() LOG.debug(_("Received message: %s"), msg) LOG.debug(_("Unpacking response")) if msg[2] == 'cast': # Legacy version raw_msg = _deserialize(msg[-1])[-1] elif msg[2] == 'impl_zmq_v2': rpc_envelope = unflatten_envelope(msg[4:]) raw_msg = rpc_common.deserialize_msg(rpc_envelope) else: raise rpc_common.UnsupportedRpcEnvelopeVersion( _("Unsupported or unknown ZMQ envelope returned.")) responses = raw_msg['args']['response'] # ZMQError trumps the Timeout error. except zmq.ZMQError: raise RPCException("ZMQ Socket Error") except (IndexError, KeyError): raise RPCException(_("RPC Message Invalid.")) finally: if 'msg_waiter' in vars(): msg_waiter.close() # It seems we don't need to do all of the following, # but perhaps it would be useful for multicall? # One effect of this is that we're checking all # responses for Exceptions. for resp in responses: if isinstance(resp, types.DictType) and 'exc' in resp: raise rpc_common.deserialize_remote_exception(CONF, resp['exc']) return responses[-1]
def _call(addr, context, topic, msg, timeout=None, envelope=False): # timeout_response is how long we wait for a response timeout = timeout or CONF.rpc_response_timeout # The msg_id is used to track replies. msg_id = uuid.uuid4().hex # Replies always come into the reply service. reply_topic = "zmq_replies.%s" % CONF.rpc_zmq_host LOG.debug("Creating payload") # Curry the original request into a reply method. mcontext = RpcContext.marshal(context) payload = { 'method': '-reply', 'args': { 'msg_id': msg_id, 'topic': reply_topic, # TODO(ewindisch): safe to remove mcontext in I. 'msg': [mcontext, msg] } } LOG.debug("Creating queue socket for reply waiter") # Messages arriving async. # TODO(ewindisch): have reply consumer with dynamic subscription mgmt with Timeout(timeout, exception=rpc_common.Timeout): try: msg_waiter = ZmqSocket( "ipc://%s/zmq_topic_zmq_replies.%s" % (CONF.rpc_zmq_ipc_dir, CONF.rpc_zmq_host), zmq.SUB, subscribe=msg_id, bind=False ) LOG.debug("Sending cast") _cast(addr, context, topic, payload, envelope) LOG.debug("Cast sent; Waiting reply") # Blocks until receives reply msg = msg_waiter.recv() LOG.debug("Received message: %s", msg) LOG.debug("Unpacking response") if msg[2] == 'cast': # Legacy version raw_msg = _deserialize(msg[-1])[-1] elif msg[2] == 'impl_zmq_v2': rpc_envelope = unflatten_envelope(msg[4:]) raw_msg = rpc_common.deserialize_msg(rpc_envelope) else: raise rpc_common.UnsupportedRpcEnvelopeVersion( _("Unsupported or unknown ZMQ envelope returned.")) responses = raw_msg['args']['response'] # ZMQError trumps the Timeout error. except zmq.ZMQError: raise RPCException("ZMQ Socket Error") except (IndexError, KeyError): raise RPCException(_("RPC Message Invalid.")) finally: if 'msg_waiter' in vars(): msg_waiter.close() # It seems we don't need to do all of the following, # but perhaps it would be useful for multicall? # One effect of this is that we're checking all # responses for Exceptions. for resp in responses: if isinstance(resp, types.DictType) and 'exc' in resp: raise rpc_common.deserialize_remote_exception(CONF, resp['exc']) return responses[-1]