The majority of my code using NaServer.invoke, which is nice and straight-forward to understand and use.
However some have been forced to use NaServer.invoke_elem due to the additional complexity in the API.
A good example of this is the nfs-exportfs-append-rules-2 api, which has a lot of additional NaElement constructs below it...
However I started to wonder why I couldn't just use the invoke call, whilst also passing the NaElement fields where required.
This lead me to check out the invoke def in the ruby sdk, which initially looks like this:
#A convenience routine which wraps invoke_elem().
#It constructs an NaElement with name $api, and for
#each argument name/value pair, adds a child element
#to it. It's an error to have an even number of
#arguments to this function.
# 'snapshot', 'mysnapshot',
# 'volume', 'vol0');
def invoke(api, *args)
num_parms = args.length
if ((num_parms & 1) != 0)
return self.fail_response(13001, "in Zapi::invoke, invalid number of parameters")
xi = NaElement.new(api)
i = 0
while(i < num_parms)
key = args[i]
i = i + 1
value = args[i]
i = i + 1
So if I try and feed in a NaElement field to invoke, I was getting an error caused by the NaElement construct going into the @contents value rather than the @children value, as shown below:
xi Request looks like:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE netapp SYSTEM 'file:/etc/netapp_filer.dtd'>
<netapp version='1.13' xmlns='http://www.netapp.com/filer/admin'><nfs-exportfs-delete-rules><persistent>true</persistent><pathnames>#<NaElement:0x7f9039195638></pathnames></nfs-exportfs-delete-rules></netapp>Invalid number of pathnames
So looking closer at 'invoke', I can see that it's treating the arguments passed to it as key/value pairs, and is constructing a new NaElement for every key/value pair. Hence the issue I'm seeing above with pathnames containing a NaElement value.
After a few tweaks, I came up with the following:
returnself.fail_response(13001,"in Zapi::invoke, invalid number of parameters")
So, what do people think of the above change? Is this something that could be fed back into the core API SDK?
We have gone through the changes you have proposed.
We can see that the changes will construct NaElement (from simple parameters) and pass it to invoke_elem().
However, for APIs with complex parameters in input (i.e. containing multiple levels in XML hierarchy and sometimes iterative/nested inputs), one has to construct the NaElement structure before passing it to invoke() method. So, it does not relieve the user from creating NaElement structures.
The primary problem that you seem to be trying to solve is to do away with the need of switching between invoke() and invoke_elem() methods [please correct me if my understanding is wrong]. If that is the case, I would recommend you use "invoke_elem()" method all through your scripts and do away with invoke() method.