Parcourir la source

[1924] Send the errors about missing recipient

If the msgq finds no recipient to send to and the sender wants an
answer, provide an error as the answer. Also check the error messages
look sane in tests.
Michal 'vorner' Vaner il y a 12 ans
Parent
commit
3e94ba20d5
2 fichiers modifiés avec 48 ajouts et 5 suppressions
  1. 27 3
      src/bin/msgq/msgq.py.in
  2. 21 2
      src/bin/msgq/tests/msgq_test.py

+ 27 - 3
src/bin/msgq/msgq.py.in

@@ -548,9 +548,33 @@ class MsgQ:
             # Don't bounce to self
             sockets.remove(sock)
 
-        # TODO: The place to create an undeliverable error, if requested
-        for socket in sockets:
-            self.send_prepared_msg(socket, msg)
+        if sockets:
+            for socket in sockets:
+                self.send_prepared_msg(socket, msg)
+        elif routing.get("wants_reply") and "reply" not in routing:
+            # We have no recipients. But the sender insists on a reply
+            # (and the message isn't a reply itself). We need to send
+            # an error to satisfy the senders hurger for response, since
+            # nobody else will do that.
+
+            # The real errors would be positive, 1 most probably. We use
+            # negative errors for delivery errors to distinguish them a
+            # little. We probably should have a way to provide more data
+            # in the error message.
+            payload = isc.config.ccsession.create_answer(-1,
+                                                         "No such recipient")
+            # We create the header based on the current one. But we don't
+            # want to mangle it for the caller, so we get a copy. A shallow
+            # one should be enough, we modify the dict only.
+            header = routing.copy()
+            header["reply"] = routing["seq"]
+            # The other headers can just stay the same. They are not used
+            # in the recipient and we know where to send it, so we don't
+            # need the "to" header. We don't know the sender's lname
+            # in this part of code anyway.
+            errmsg = self.preparemsg(header, payload)
+            # Send it back.
+            self.send_prepared_msg(sock, errmsg)
 
     def process_command_subscribe(self, sock, routing, data):
         group = routing["group"]

+ 21 - 2
src/bin/msgq/tests/msgq_test.py

@@ -194,7 +194,16 @@ class MsgQTest(unittest.TestCase):
         routing["wants_reply"] = True
         self.__msgq.process_command_send(sender, routing, data)
         self.assertEqual(1, len(sent_messages))
-        # TODO: Parse the message and check it looks correct. It should contain
+        self.assertEqual(1, sent_messages[0][0])
+        self.assertEqual(({
+                              'group': 'group',
+                              'instance': '*',
+                              'reply': 42,
+                              'seq': 42,
+                              'to': '*',
+                              'wants_reply': True
+                          }, {'result': [-1, "No such recipient"]}),
+                          self.parse_msg(sent_messages[0][1]))
         # the reply header too.
         sent_messages = []
         # If the message is a reply itself, we never generate the errors, even
@@ -220,7 +229,17 @@ class MsgQTest(unittest.TestCase):
         routing["to"] = "lname"
         self.__msgq.process_command_send(sender, routing, data)
         self.assertEqual(1, len(sent_messages))
-        # TODO: Parse the errors
+        self.assertEqual(1, sent_messages[0][0])
+        self.assertEqual(({
+                              'group': 'group',
+                              'instance': '*',
+                              'reply': 42,
+                              'seq': 42,
+                              'to': 'lname',
+                              'wants_reply': True
+                          }, {'result': [-1, "No such recipient"]}),
+                          self.parse_msg(sent_messages[0][1]))
+        sent_messages = []
         # But when the recipient is there, it is delivered and no error is
         # generated.
         self.__msgq.lnames["lname"] = recipient