Bug #72511 Return string is not easy to use it.
Submitted: 2 May 2014 4:30 Modified: 5 May 2014 8:15
Reporter: Martin Arrieta (OCA) Email Updates:
Status: Duplicate Impact on me:
Category:MySQL Fabric Severity:S3 (Non-critical)
Version:1.4.2 OS:Any
Assigned to: CPU Architecture:Any
Tags: json, Output

[2 May 2014 4:30] Martin Arrieta
I'm not sure if this is a bug (probably not and maybe is just a feature request), feel free to point me a place to send this kind of comments/request/suggestions.

When you return the value from the fabric server you just print the object...

for example for group health (I have added the address to this command too because otherwise is hard to identify the node that you want to know the status): 

        availability[str(server.uuid)] = {
            "is_alive" : alive,
            "status" : status,
            "threads" : thread_issues,
            "address" : address

    return availability

so the availability objet will be printed and it will be returned with the "dispatch" like this:

Command :
{ success     = True
  return      = {'12f4a168-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}, '1189e6be-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}, '0efa44fb-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}}
  activities  =

This string is very similar to a json string but is not a valid string:

>>> import json
>>> s = " {'12f4a168-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}, '1189e6be-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}, '0efa44fb-d08e-11e3-92cf-08002760fc47': {'status': 'FAULTY', 'is_alive': False, 'threads': {}, 'address': ''}}"
>>> json.loads(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/json/__init__.py", line 307, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.6/json/decoder.py", line 319, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.6/json/decoder.py", line 336, in raw_decode
    obj, end = self._scanner.iterscan(s, **kw).next()
  File "/usr/lib64/python2.6/json/scanner.py", line 55, in iterscan
    rval, next_pos = action(m, context)
  File "/usr/lib64/python2.6/json/decoder.py", line 171, in JSONObject
    raise ValueError(errmsg("Expecting property name", s, end))
ValueError: Expecting property name: line 1 column 2 (char 2)

So if instead of return the objet, we return a json.dumps(object) we will be able to use that string in the dispatch in order to make the output more friendly.

How to repeat:
Just try to use the "return" string as a json string..

Suggested fix:
on Command.generate_output_pattern

    def generate_output_pattern(func, *params):
        """Call the function with the input params and generate a output pattern
        of {success:True/False, message:<for example exception>,
        return:<return values>}.

        :param func: the function that needs to be called
        :param params: The parameters to the function

        :return: {success:True/False, message:<for example exception>,
                return:<return values>}.
            status = func(*params)
        except Exception:
            return [False, traceback.format_exc(), True]
        return [True, "", json.dumps(status)]
[5 May 2014 8:14] Mats Kindahl
Thank you for the bug report! It is probably more of a feature request, and actually it is a duplicate of BUG#71445. As pointed out there, having some sort of generic "formatting" support to provide any kind of output (even a custom one) should probably be supported.