cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1192
Views
0
Helpful
3
Replies

GetIlsConfigReq makes returnedTags mandatory - different from all other "get" requests

Jonathan Els
Level 5
Level 5


Unlike all other "get" calls, GetIlsConfigReq  forces you to explicitly supply returnedTags, like you do with list methods.


  <xsd:complexType name="GetIlsConfigReq">
  <xsd:sequence>
  <xsd:sequence>
  <xsd:element minOccurs="0" name="clusterId" type="xsd:string"/>
  </xsd:sequence>
  <xsd:element name="returnedTags" type="axlapi:NewIlsConfig"/>
  </xsd:sequence>
</xsd:complexType>


If you compare this to any arb. "get" request, returnedTags is missing a minOccurs tag:


<xsd:complexType name="GetSipProfileReq">
  <xsd:sequence>
  <xsd:choice>
  <xsd:element name="name" type="axlapi:String100"/>
  <xsd:element name="uuid" type="axlapi:XUUID"/>
  </xsd:choice>
  <xsd:element minOccurs="0" name="returnedTags" type="axlapi:RSipProfile"/>
  </xsd:sequence>
  <xsd:attribute name="sequence" type="xsd:unsignedLong" use="optional"/>




It just looks to me like this was missed in when the schema was defined...  Here's an example where I didn't supply returnedTags

def main():

  session = Session()

  session.verify = False
   session.auth = HTTPBasicAuth(USERNAME, PASSWORD)

   transport = Transport(cache=SqliteCache(), session=session, timeout=60)

   history = HistoryPlugin()

  client = Client(wsdl=WSDL, transport=transport, plugins=[history])

  axl = client.create_service(BINDING_NAME, ADDRESS)

   try:

   print(axl.getIlsConfig())

   except XMLParseError as parse_error:

   print(parse_error.message)

   print()

   finally:

   try:

   for hist in [history.last_sent, history.last_received]:

   print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))

   except IndexError:

   pass

if __name__ == '__main__':

  main()



Zeep is enforcing it:


  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\elements\element.py", line 191, in render

    self._render_value_item(parent, value, render_path)

  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\elements\element.py", line 215, in _render_value_item

    return self.type.render(node, value, None, render_path)

  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\types\complex.py", line 253, in render

    element.render(parent, element_value, child_path)

  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\elements\indicators.py", line 241, in render

    element.render(parent, element_value, child_path)

  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\elements\element.py", line 185, in render

    self.validate(value, render_path)

  File "C:\Users\jonathan.els\Envs\suds\lib\site-packages\zeep\xsd\elements\element.py", line 236, in validate

    "Missing element %s" % (self.name), path=render_path)

zeep.exceptions.ValidationError: Missing element returnedTags (getIlsConfig.returnedTags)



bug?

3 Replies 3

Jonathan Els
Level 5
Level 5

There's also at least one more bug here with clusterId.  This is not supposed to be a mandatory attribute and is marked as optional:

<xsd:complexType name="GetIlsConfigReq">
  <xsd:sequence>
  <xsd:sequence>
  <xsd:element minOccurs="0" name="clusterId" type="xsd:string"/>
  </xsd:sequence>
  <xsd:element name="returnedTags" type="axlapi:NewIlsConfig"/>
  </xsd:sequence>
</xsd:complexType>

If I do this (axl.getIlsConfig(returnedTags={"clusterUriString": ""}), without a clusterId, it works:



def main():

  session = Session()

  session.verify = False
   session.auth = HTTPBasicAuth(USERNAME, PASSWORD)

  transport = Transport(cache=SqliteCache(), session=session, timeout=60)

  history = HistoryPlugin()

  client = Client(wsdl=WSDL, transport=transport, plugins=[history])

  axl = client.create_service(BINDING_NAME, ADDRESS)

   try:

   print(axl.getIlsConfig(returnedTags={"clusterUriString": ""}))

   except XMLParseError as parse_error:

   print(parse_error.message)

   finally:

   try:

   for hist in [history.last_sent, history.last_received]:

   print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))

   except IndexError:

   pass

if __name__ == '__main__':

  main()

however, as soon as I specify that I want the clusterId as a returned tag, then it fails:

def main():

  session = Session()

  session.verify = False
   session.auth = HTTPBasicAuth(USERNAME, PASSWORD)

  transport = Transport(cache=SqliteCache(), session=session, timeout=60)

  history = HistoryPlugin()

  client = Client(wsdl=WSDL, transport=transport, plugins=[history])

  axl = client.create_service(BINDING_NAME, ADDRESS)

   try:

   print(axl.getIlsConfig(returnedTags={"clusterId": "", "clusterUriString": ""}))

   except XMLParseError as parse_error:

   print(parse_error.message)

   finally:

   try:

   for hist in [history.last_sent, history.last_received]:

   print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))

   except IndexError:

   pass

if __name__ == '__main__':

  main()

Response from CUCM:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">

  <soap-env:Body>

    <ns0:getIlsConfig xmlns:ns0="http://www.cisco.com/AXL/API/11.5">

      <returnedTags>

        <clusterId></clusterId>

        <clusterUriString></clusterUriString>

      </returnedTags>

    </ns0:getIlsConfig>

  </soap-env:Body>

</soap-env:Envelope>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

  <soapenv:Body>

    <soapenv:Fault>

      <faultcode>soapenv:Server</faultcode>

      <faultstring/>

      <detail>

        <axlError>

          <axlcode>-1</axlcode>

          <axlmessage/>

          <request>getIlsConfig</request>

        </axlError>

      </detail>

    </soapenv:Fault>

  </soapenv:Body>

</soapenv:Envelope>

If then I go and specify the clusterId up front, then it works: 

def main():

  session = Session()

  session.verify = False
   session.auth = HTTPBasicAuth(USERNAME, PASSWORD)

  transport = Transport(cache=SqliteCache(), session=session, timeout=60)

  history = HistoryPlugin()

  client = Client(wsdl=WSDL, transport=transport, plugins=[history])

  axl = client.create_service(BINDING_NAME, ADDRESS)

   try:

   print(axl.getIlsConfig(clusterId="StandAloneCluster", returnedTags={"clusterId": "", "clusterUriString": ""}))

   except XMLParseError as parse_error:

   print(parse_error.message)

   finally:

   try:

   for hist in [history.last_sent, history.last_received]:

   print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))

   except IndexError:

   pass

if __name__ == '__main__':

  main()

This really should be consistent with other API calls.  The others usually offer a choice of a name/pattern setc, or the uuid.  If there's no uuid for clusterid, then really the clusterid name should be enforced here.

Hey Jonathon, I am running into the same issue when attempting to pull the ilsconfig via AXL. I get the same error you referenced above "zeep.exceptions.ValidationError: Missing element returnedTags (getIlsConfig.returnedTags)", but it wasn't clear to me on how you resolved it. I also thought it was weird that the returnedTags was needed in a get request, since my other AXL pulls only used this attribute in a list request and this was the only get function that threw a zeep exception on returnedTags.

 

What exactly did you modify to get this working?

I figured it out, based on your notes above. I created this function and was successful in returning the dataset, I just need to remember to pull the Cluster ID from the Enterprise Parameters before running this function:

def get_ils_config(self, clusterId):                                                          
try:
return self.client.getIlsConfig(clusterId=clusterId, returnedTags={"clusterUriString": ""})["return"]
except Fault as e:
return