<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Enhancing the 'NaServer.invoke' call... in Software Development Kit (SDK) and API Discussions</title>
    <link>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52461#M450</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Afternoon all&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I've recently started looking at streamlining some of the code used in my &lt;A href="http://forge.puppetlabs.com/fatmcgav/netapp" target="_blank"&gt;Puppet NetApp network device&lt;/A&gt; module. &lt;/P&gt;&lt;P&gt;The majority of my code using NaServer.invoke, which is nice and straight-forward to understand and use. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However some have been forced to use NaServer.invoke_elem due to the additional complexity in the API. &lt;/P&gt;&lt;P&gt;A good example of this is the &lt;EM&gt;nfs-exportfs-append-rules-2&lt;/EM&gt; api, which has a lot of additional NaElement constructs below it...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However I started to wonder why I couldn't just use the invoke call, whilst also passing the NaElement fields where required. &lt;/P&gt;&lt;P&gt;This lead me to check out the invoke def in the ruby sdk, which initially looks like this:&lt;/P&gt;&lt;PRE __default_attr="ruby" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_13739787320681743" jivemacro_uid="_13739787320681743"&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #A convenience routine which wraps invoke_elem().&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #It constructs an NaElement with name $api, and for&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #each argument name/value pair, adds a child element&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #to it.&amp;nbsp; It's an error to have an even number of&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #arguments to this function.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #Example: myserver-&amp;gt;invoke('snapshot-create',&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'snapshot', 'mysnapshot',&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'volume', 'vol0');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; def invoke(api, *args)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; num_parms = args.length&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((num_parms &amp;amp; 1) != 0)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return self.fail_response(13001, "in Zapi::invoke, invalid number of parameters")&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xi = NaElement.new(api)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = 0&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(i &amp;lt; num_parms)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key = args[i]&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = args[i]&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xi.child_add(NaElement.new(key, value))&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return invoke_elem(xi)&lt;/P&gt;&lt;P&gt;&amp;nbsp; end&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;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:&lt;/P&gt;&lt;PRE __default_attr="plain" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_1373978813892921" jivemacro_uid="_1373978813892921" modifiedtitle="true"&gt;&lt;P&gt;xi Request looks like:&lt;/P&gt;&lt;P&gt;#&amp;lt;NaElement:0x7f9039184b08&lt;/P&gt;&lt;P&gt; @attrkeys=[],&lt;/P&gt;&lt;P&gt; @attrvals=[],&lt;/P&gt;&lt;P&gt; @children=&lt;/P&gt;&lt;P&gt;&amp;nbsp; [#&amp;lt;NaElement:0x7f9039184978&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="true",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="persistent"&amp;gt;,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;lt;NaElement:0x7f90391847e8&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content=&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;lt;NaElement:0x7f9039195638&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [#&amp;lt;NaElement:0x7f9039195520&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="/vol/v_puppet_test1007131448.",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathname"&amp;gt;],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathname-info"&amp;gt;,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathnames"&amp;gt;],&lt;/P&gt;&lt;P&gt; @content="",&lt;/P&gt;&lt;P&gt; @name="nfs-exportfs-delete-rules"&amp;gt;&lt;/P&gt;&lt;P&gt;INPUT&lt;/P&gt;&lt;P&gt; &amp;lt;?xml version='1.0' encoding='utf-8'?&amp;gt;&lt;/P&gt;&lt;P&gt;&amp;lt;!DOCTYPE netapp SYSTEM 'file:/etc/netapp_filer.dtd'&amp;gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;&amp;lt;netapp version='1.13' xmlns='&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://www.netapp.com/filer/admin" target="_blank"&gt;http://www.netapp.com/filer/admin&lt;/A&gt;&lt;SPAN&gt;'&amp;gt;&amp;lt;nfs-exportfs-delete-rules&amp;gt;&amp;lt;persistent&amp;gt;true&amp;lt;/persistent&amp;gt;&amp;lt;pathnames&amp;gt;#&amp;amp;lt;NaElement:0x7f9039195638&amp;amp;gt;&amp;lt;/pathnames&amp;gt;&amp;lt;/nfs-exportfs-delete-rules&amp;gt;&amp;lt;/netapp&amp;gt;Invalid number of pathnames&lt;/SPAN&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;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. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;After a few tweaks, I came up with the following:&lt;/P&gt;&lt;PRE __default_attr="ruby" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_13739789622903902" jivemacro_uid="_13739789622903902" modifiedtitle="true"&gt;&lt;P class="line" id="file-patched-invoke-rb-LC11"&gt;&amp;nbsp; &lt;SPAN class="k"&gt;def&lt;/SPAN&gt; &lt;SPAN class="nf"&gt;invoke&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;api&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="o"&gt;*&lt;/SPAN&gt;&lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC13"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;length&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC14"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;if&lt;/SPAN&gt; &lt;SPAN class="p"&gt;((&lt;/SPAN&gt;&lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt; &lt;SPAN class="o"&gt;&amp;amp;&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt; &lt;SPAN class="o"&gt;!=&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;0&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC15"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;return&lt;/SPAN&gt; &lt;SPAN class="nb"&gt;self&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;fail_response&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="mi"&gt;13001&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="s2"&gt;"in Zapi::invoke, invalid number of parameters"&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC16"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC18"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;api&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC19"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;0&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC20"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;while&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;&amp;lt;&lt;/SPAN&gt; &lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC21"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;key&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;[&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt;&lt;SPAN class="o"&gt;]&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC22"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;+&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC23"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;[&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt;&lt;SPAN class="o"&gt;]&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC26"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;+&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC27"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;if&lt;/SPAN&gt; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;class&lt;/SPAN&gt; &lt;SPAN class="o"&gt;==&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC29"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;x&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;key&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC30"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;x&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC31"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;x&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC32"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;else&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC34"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;key&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="p"&gt;))&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC35"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC36"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC39"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;return&lt;/SPAN&gt; &lt;SPAN class="n"&gt;invoke_elem&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC40"&gt;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So, what do people think of the above change? Is this something that could be fed back into the core API SDK? &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Cheers&lt;/P&gt;&lt;P&gt;Gavin &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 05 Jun 2025 05:58:32 GMT</pubDate>
    <dc:creator>NETAPPACT</dc:creator>
    <dc:date>2025-06-05T05:58:32Z</dc:date>
    <item>
      <title>Enhancing the 'NaServer.invoke' call...</title>
      <link>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52461#M450</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Afternoon all&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I've recently started looking at streamlining some of the code used in my &lt;A href="http://forge.puppetlabs.com/fatmcgav/netapp" target="_blank"&gt;Puppet NetApp network device&lt;/A&gt; module. &lt;/P&gt;&lt;P&gt;The majority of my code using NaServer.invoke, which is nice and straight-forward to understand and use. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However some have been forced to use NaServer.invoke_elem due to the additional complexity in the API. &lt;/P&gt;&lt;P&gt;A good example of this is the &lt;EM&gt;nfs-exportfs-append-rules-2&lt;/EM&gt; api, which has a lot of additional NaElement constructs below it...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However I started to wonder why I couldn't just use the invoke call, whilst also passing the NaElement fields where required. &lt;/P&gt;&lt;P&gt;This lead me to check out the invoke def in the ruby sdk, which initially looks like this:&lt;/P&gt;&lt;PRE __default_attr="ruby" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_13739787320681743" jivemacro_uid="_13739787320681743"&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #A convenience routine which wraps invoke_elem().&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #It constructs an NaElement with name $api, and for&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #each argument name/value pair, adds a child element&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #to it.&amp;nbsp; It's an error to have an even number of&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #arguments to this function.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #Example: myserver-&amp;gt;invoke('snapshot-create',&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'snapshot', 'mysnapshot',&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'volume', 'vol0');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; def invoke(api, *args)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; num_parms = args.length&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((num_parms &amp;amp; 1) != 0)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return self.fail_response(13001, "in Zapi::invoke, invalid number of parameters")&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xi = NaElement.new(api)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = 0&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(i &amp;lt; num_parms)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key = args[i]&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = args[i]&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i + 1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xi.child_add(NaElement.new(key, value))&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return invoke_elem(xi)&lt;/P&gt;&lt;P&gt;&amp;nbsp; end&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;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:&lt;/P&gt;&lt;PRE __default_attr="plain" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_1373978813892921" jivemacro_uid="_1373978813892921" modifiedtitle="true"&gt;&lt;P&gt;xi Request looks like:&lt;/P&gt;&lt;P&gt;#&amp;lt;NaElement:0x7f9039184b08&lt;/P&gt;&lt;P&gt; @attrkeys=[],&lt;/P&gt;&lt;P&gt; @attrvals=[],&lt;/P&gt;&lt;P&gt; @children=&lt;/P&gt;&lt;P&gt;&amp;nbsp; [#&amp;lt;NaElement:0x7f9039184978&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="true",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="persistent"&amp;gt;,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; #&amp;lt;NaElement:0x7f90391847e8&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content=&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;lt;NaElement:0x7f9039195638&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [#&amp;lt;NaElement:0x7f9039195520&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrkeys=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @attrvals=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @children=[],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="/vol/v_puppet_test1007131448.",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathname"&amp;gt;],&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @content="",&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathname-info"&amp;gt;,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @name="pathnames"&amp;gt;],&lt;/P&gt;&lt;P&gt; @content="",&lt;/P&gt;&lt;P&gt; @name="nfs-exportfs-delete-rules"&amp;gt;&lt;/P&gt;&lt;P&gt;INPUT&lt;/P&gt;&lt;P&gt; &amp;lt;?xml version='1.0' encoding='utf-8'?&amp;gt;&lt;/P&gt;&lt;P&gt;&amp;lt;!DOCTYPE netapp SYSTEM 'file:/etc/netapp_filer.dtd'&amp;gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;&amp;lt;netapp version='1.13' xmlns='&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://www.netapp.com/filer/admin" target="_blank"&gt;http://www.netapp.com/filer/admin&lt;/A&gt;&lt;SPAN&gt;'&amp;gt;&amp;lt;nfs-exportfs-delete-rules&amp;gt;&amp;lt;persistent&amp;gt;true&amp;lt;/persistent&amp;gt;&amp;lt;pathnames&amp;gt;#&amp;amp;lt;NaElement:0x7f9039195638&amp;amp;gt;&amp;lt;/pathnames&amp;gt;&amp;lt;/nfs-exportfs-delete-rules&amp;gt;&amp;lt;/netapp&amp;gt;Invalid number of pathnames&lt;/SPAN&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;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. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;After a few tweaks, I came up with the following:&lt;/P&gt;&lt;PRE __default_attr="ruby" __jive_macro_name="code" class="jive_text_macro jive_macro_code _jivemacro_uid_13739789622903902" jivemacro_uid="_13739789622903902" modifiedtitle="true"&gt;&lt;P class="line" id="file-patched-invoke-rb-LC11"&gt;&amp;nbsp; &lt;SPAN class="k"&gt;def&lt;/SPAN&gt; &lt;SPAN class="nf"&gt;invoke&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;api&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="o"&gt;*&lt;/SPAN&gt;&lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC13"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;length&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC14"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;if&lt;/SPAN&gt; &lt;SPAN class="p"&gt;((&lt;/SPAN&gt;&lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt; &lt;SPAN class="o"&gt;&amp;amp;&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt; &lt;SPAN class="o"&gt;!=&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;0&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC15"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;return&lt;/SPAN&gt; &lt;SPAN class="nb"&gt;self&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;fail_response&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="mi"&gt;13001&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="s2"&gt;"in Zapi::invoke, invalid number of parameters"&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC16"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC18"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;api&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC19"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;0&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC20"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;while&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;&amp;lt;&lt;/SPAN&gt; &lt;SPAN class="n"&gt;num_parms&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC21"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;key&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;[&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt;&lt;SPAN class="o"&gt;]&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC22"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;+&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC23"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;args&lt;/SPAN&gt;&lt;SPAN class="o"&gt;[&lt;/SPAN&gt;&lt;SPAN class="n"&gt;i&lt;/SPAN&gt;&lt;SPAN class="o"&gt;]&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC26"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;i&lt;/SPAN&gt; &lt;SPAN class="o"&gt;+&lt;/SPAN&gt; &lt;SPAN class="mi"&gt;1&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC27"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;if&lt;/SPAN&gt; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;class&lt;/SPAN&gt; &lt;SPAN class="o"&gt;==&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC29"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;x&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;key&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC30"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;x&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC31"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;x&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC32"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;else&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC34"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;child_add&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="no"&gt;NaElement&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;new&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;key&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="n"&gt;value&lt;/SPAN&gt;&lt;SPAN class="p"&gt;))&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC35"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC36"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC39"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="k"&gt;return&lt;/SPAN&gt; &lt;SPAN class="n"&gt;invoke_elem&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;xi&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P class="line" id="file-patched-invoke-rb-LC40"&gt;&amp;nbsp; &lt;SPAN class="k"&gt;end&lt;/SPAN&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So, what do people think of the above change? Is this something that could be fed back into the core API SDK? &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Cheers&lt;/P&gt;&lt;P&gt;Gavin &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 05 Jun 2025 05:58:32 GMT</pubDate>
      <guid>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52461#M450</guid>
      <dc:creator>NETAPPACT</dc:creator>
      <dc:date>2025-06-05T05:58:32Z</dc:date>
    </item>
    <item>
      <title>Re: Enhancing the 'NaServer.invoke' call...</title>
      <link>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52466#M451</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Gavin,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks for showing such interest in NMSDK (Ruby).&lt;/P&gt;&lt;P&gt;We have gone through the changes you have proposed.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;We can see that the changes will construct NaElement (from simple parameters) and pass it to invoke_elem().&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Sen.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Jul 2013 10:30:13 GMT</pubDate>
      <guid>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52466#M451</guid>
      <dc:creator>sens</dc:creator>
      <dc:date>2013-07-26T10:30:13Z</dc:date>
    </item>
    <item>
      <title>Re: Enhancing the 'NaServer.invoke' call...</title>
      <link>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52471#M452</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Sen&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Cheers for taking the time to respond. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Yes, the fundamental driver behind my changes was to remove the need for me to use invoke_elem(). &lt;/P&gt;&lt;P&gt;This is due to functionality in my NetApp Puppet module to create wrapper defs around the various api calls required. This can be seen here: &lt;A href="https://github.com/fatmcgav/fatmcgav-netapp/blob/master/lib/puppet/provider/netapp.rb#L27-58" target="_blank"&gt;https://github.com/fatmcgav/fatmcgav-netapp/blob/master/lib/puppet/provider/netapp.rb#L27-58&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;And yes, it does still require some NAElement elements to be constructed prior to submitting to the invoke call, however as would be doing that anyway for invoke_elem, it's no further effort. &lt;/P&gt;&lt;P&gt;A good example of this is: &lt;A href="https://github.com/fatmcgav/fatmcgav-netapp/blob/master/lib/puppet/provider/netapp_export/netapp_export.rb#L141-195" target="_blank"&gt;https://github.com/fatmcgav/fatmcgav-netapp/blob/master/lib/puppet/provider/netapp_export/netapp_export.rb#L141-195&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Currently, i've got this bundled as a patch which users need to apply to the SDK in order to use it with Puppet. So it's no major issue if this doesn't get incorporated back into the SDK... &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;Gavin &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Jul 2013 12:25:56 GMT</pubDate>
      <guid>https://community.netapp.com/t5/Software-Development-Kit-SDK-and-API-Discussions/Enhancing-the-NaServer-invoke-call/m-p/52471#M452</guid>
      <dc:creator>NETAPPACT</dc:creator>
      <dc:date>2013-07-26T12:25:56Z</dc:date>
    </item>
  </channel>
</rss>

