Bug #73968 mysqlfabric event trigger does not handle parameters correctly
Submitted: 18 Sep 2014 13:16 Modified: 12 Dec 2014 22:28
Reporter: Alfranio Tavares Correia Junior Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Utilities Severity:S3 (Non-critical)
Version:1.4.2 OS:Any
Assigned to: CPU Architecture:Any

[18 Sep 2014 13:16] Alfranio Tavares Correia Junior
Description:
The command-line "event trigger" does not handle parameters correctly:

 class Trigger(Command):
    """Trigger an event.
    """
    group_name = "event"
    command_name = "trigger"

 def execute(self, event, locks, *args, **kwargs):
     ....

The problem was exposed by the code pushed to release 1.4.2, in the context
of WL#7528 ("Adding support for optional arguments in Fabric"). After this
patch, MySQL Fabric stopped recognizing args and kwargs as parameters.

Although the args and kwargs were recognized as parameters before the
aforementioned WL, the command did not really had support to an
unbounded number of parameters. The problem stemmed from the fact that
the XML-RPC does not have support to the non-keyworded and keyworded
parameters.

So if you have tried to fire an event that required some parameters
you would get an error. For example,

mysqlfabric -config ../fabric-1.cfg event trigger EVENT my_group 8b1e25db-c8f4-43a2-bd07-79335753f693
Usage:  event trigger event locks   

mysqlfabric: error: Wrong number of parameters were provided for command 'event trigger'.

How to repeat:
Check the code or execute:

mysqlfabric -config ../fabric-1.cfg event trigger EVENT my_group 8b1e25db-c8f4-43a2-bd07-79335753f693
Usage:  event trigger event locks   

mysqlfabric: error: Wrong number of parameters were provided for command 'event trigger'.

Suggested fix:
Make the 'event trigger' command accept non-keyworded and keyworded
parameters:

--- lib/mysql/fabric/services/event.py  revid:alfranio.correia@oracle.com-20140909162546-2titgr69irzhm7ia
+++ lib/mysql/fabric/services/event.py  2014-09-18 11:11:41 +0000
@@ -19,6 +19,7 @@
 necessary means to trigger an event, to get details on a procedure and wait
 until procedures finish their execution.
 """
+import logging
 import uuid as _uuid

 from mysql.fabric import (
@@ -33,13 +34,19 @@
     ResultSet,
 )

+from mysql.fabric.services.utils import (
+    kv_to_dict,
+)
+
+_LOGGER = logging.getLogger(__name__)
+
 class Trigger(Command):
     """Trigger an event.
     """
     group_name = "event"
     command_name = "trigger"

-    def execute(self, event, locks, *args, **kwargs):
+    def execute(self, event, locks=None, args=None, kwargs=None):
         """Trigger the execution of an event.

         :param event: Event's identification.
@@ -49,22 +56,50 @@

         :return: :class:`CommandResult` instance with UUID of the

-
-        lockable_objects = set()
-        for lock in locks.split(","):
-            lockable_objects.add(lock.strip())
-
+        lockable_objects = None
+        if locks:
+            lockable_objects = set()
+            for lock in locks:
+                lockable_objects.add(lock.strip())
+
+        # Prepare list arguments.
+        param_args = []
+        if args is not None:
+            param_args = args
+
+        # Prepare key word arguments.
+        param_kwargs = {}
+        if kwargs is not None:
+           param_kwargs = kv_to_dict(kwargs)
+
+        # Define the resultset format. 
         rset = ResultSet(names=['uuid'], types=[str])

+        _LOGGER.debug(
+            "Triggering event (%s) with arguments: %s, %s.", event,
+            param_args, param_kwargs
+        )
+
         # Trigger the event and add the UUID of all procedures queued
         # to the result.
-        for proc in _events.trigger(event, lockable_objects, *args, **kwargs):
-            rset.append_row([str(proc.uuid)])
+        procedures = _events.trigger(
+            event, lockable_objects, *param_args, **param_kwargs
+        )
+        for procedure in procedures:
+            rset.append_row([str(procedure.uuid)])

         return CommandResult(None, results=rset)

+    def generate_options(self):
+        """Make some options accept multiple values.
+        """
+        super(Trigger, self).generate_options()
+        options = ["locks", "args", "kwargs"]
+        for option in self.command_options:
+            if option['dest'] in options:
+                option['action'] = "append"
[12 Dec 2014 22:28] Philip Olson
Posted by developer:
 
Fixed as of the upcoming MySQL Fabric 1.5.4 release, and here's the changelog entry:

The "mysqlfabric" event trigger did not properly handle arguments.

Thank you for the bug report.