When using pywbem 0.7 with the cimserver on a Cisco MDS Fibre Channel switch, requesting the CreateZone(ZoneName, ZoneType, ZoneSubType) extrinsic method caused the cimserver to crash.
I traced the problem to the ordering of the <PARAMVALUE> elements in the XML request. Apparently, the MDS cimserver is sensitive to the ordering of the parameters to extrinsic methods (for the CreateZone() case, at least). Since pywbem uses **params to pass keyword parameters for the extrinsic parameters, reordering can occur since a dictionary stores the keyword parameters.
I would expect a robust server to handle <PARAMVALUE> in any order, but unfortunately my application cannot choose the CIM servers that it deals with. I worked around the issue by altering the API for InvokeMethod() to user a list of [name, value] pairs instead of a keyword param dictionary. This is obviously not suitable for general use since it breaks API compatibility, but if it seems useful to fix this, perhaps a variant of the InvokeMethod() call could be provided that preserves parameter order.
I've attached the patch that describes the changes I made to pywbem 0.7.
Patch for positional ordering of extrinsic method parameters.
Because the proposed solution breaks backwards compatibility of InvokeMethod(), it cannot be applied as proposed.
I see the following options on how to proceed:
Option 1: Don't change anything. This requires that the deficient CIM server has been fixed, meanwhile. Is that the case, does anyone know?
Option 2: Change PyWBEM to support / use collections.OrderedDict. There is at least the following set of variants of this option:
a) Allow it to be used by the caller of InvokeMethod(). PyWBEM code probably does not need to be changed for that (test is still required), but it would only keep extrinsic method parameters as specified, and would still change the order of any other CIM operation parameters.
b) Change PyWBEM to use OrderedDict as a basis for its NoCaseDict, which would preserve the order of elements in both requests and responses.
Support for collections.OrderedDict is built in to Python 2.7, and has been backported to Python 2.4 - 2.6 with the ordereddict package on PyPi: https://pypi.python.org/pypi/ordereddict
That creates an additional package dependency for these Python versions. For example, Python 2.6 is still the only version available in many current Linux distros.
Option 3: Add a new InvokeMethodFromList() method that takes a list, as proposed by
cim_operations.py.patch. Because this is a new method, it would not break backwards compatibility of the existing method.
-> All, please review these options and let me know your view on where to go. Additional options are of course also welcome.
Andy
I would like to proceed with this bug by implementing option 2.b) described above.
After starting to implement, I found out that the intended solution does not work. i found a new option, which is to add an optional argument to InvokeMethod() before the params keyword parameters. The new argument is 'Params' and is a list of tuples(name,value). It preserves its input parameters, and combines with the input parameters specified via params.
This solution is backwards compatible, because the new argument is optional. I have added test cases that test with and without the new argument.
This solution has been implemented and tested, and test cases have been improved (in test_operations.py). The result has been committed as r703.
Last edit: Andreas Maier 2015-01-16
Here is the patch as committed, in case people want to review that.