“HelpDesk_QueryList_Service” with “3” argument(s): “There is an error in XML document (3, 4).


I wrote before some posts about getting tickets from BMC Remedy ITSM system. Recently i had to check for tickets on a different environments , and got stuck. It was ‘weird’, as i would thought that since it was working on previous environment it will work on new one. This post is not about how to query itsm tickets in general… it’s about how to make it working if you encounter issue like:


“HelpDesk_QueryList_Service” with “3” argument(s): “There is an error in XML document (3, 4).


I was investigating this issue first myself, then i was googling for about 3-4 hours… And, nothing. Found few places where this error was mentioned, but no working answers were posted. I do not want to write too much here, as my ITSM system knowledge is like… huh.. ok i have no knowledge of that 😉 I just want to get some tickets info 😉 Therefore, i will not comment much on what i have done , as i do not feel too comfortable about what i wrote 😉


While googling about this, i saw opinions like : “There is something wrong with New-WebServicePRoxy …” or “There is something wrong with the ITSM instance” or “the criteria is wrong” or “Authorization did not complete”. I can’t tell what exactly it is, well sort of… but since i am not an expert in this matter i shall keep it to myself 😉 For sure, there is no problem with logging in, or criteria query. It all comes down to what we are receiving from our itsm service, and i think this is problematic. Even if we are seeing on the powershell console the:
“”HelpDesk_QueryList_Service” with “3” argument(s): “There is an error in XML document (3, 4).”


It does not have to mean that we did not get our tickets back. We have put a proxy between powershell and the itsm service, and were checking the soap requests and replies. ITSM service was sending the tickets back, it’s just that powershell cmdlet New-WebserviceProxy decided that is something wrong with it, and decided not to “give it back to us”. I really do not know the details about it, please excuse me for not writing this.
Anyway… i even thought that there is something wrong with the new-webserviceproxy (it’s not the case) , and then i started to google if somebody has wrote his own function for sending receiving soap requests/answers.
Fortunately i found this website : http://iislogs.com/steveschofield/2010/01/17/execute-a-soap-request-from-powershell/ where Steve Schofield has written a function for that.
There are still few things that i don’t know about web services and soap and so on.. so i wanted just to see if it is even possible to get those tickets. For that i used soap ui. I managed to receive tickets from soap ui, so that has to be doable. Then it was just a matter of tries to do it in powershell.

itsma1

So i knew for sure that is possible to do it, as i was receiving tickets out of that call. If you know more about soap, xml , xsd maybe you will know the answer to why powershell keeps throwing that error. Feel free to share your thoughts. Ok, never mind the issues now. Let’s start making it working. So we got the function from Steve Schofield.

function Execute-SOAPRequest 
( 
        [Xml]    $SOAPRequest, 
        [String] $URL 
) 
{ 
        write-host "Sending SOAP Request To Server: $URL" 
        $soapWebRequest = [System.Net.WebRequest]::Create($URL) 
        $soapWebRequest.Headers.Add("SOAPAction","`"urn:HPD_IncidentInterface_WS/HelpDesk_QueryList_Service`"")  #this i took directly from SoapUI after completing request there

        $soapWebRequest.ContentType = "text/xml;charset=`"utf-8`"" 
        $soapWebRequest.Accept      = "text/xml" 
        $soapWebRequest.Method      = "POST" 
        
        write-host "Initiating Send." 
        $requestStream = $soapWebRequest.GetRequestStream() 
        $SOAPRequest.Save($requestStream) 
        $requestStream.Close() 
        
        write-host "Send Complete, Waiting For Response." 
        $resp = $soapWebRequest.GetResponse() 
        $responseStream = $resp.GetResponseStream() 
        $soapReader = [System.IO.StreamReader]($responseStream) 
        $ReturnXml = [Xml] $soapReader.ReadToEnd() 
        $responseStream.Close() 
        
        write-host "Response Received."

        return $ReturnXml 
}

Then we need the endpoint url:

‘$url = ‘https://XYZ/arsys/services/ARService?server=ABC&webService=HPD_IncidentInterface_WS”
You can also get this from SoapUI request that you have previously made ( or even from (new-webserviceproxy ..).Url)
Now we have to create our SOAP envelope , i just copied what SoapUI has generated for me. So in my case that was:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:HPD_IncidentInterface_WS">
   <soapenv:Header>
      <urn:AuthenticationInfo>
         <urn:userName>Domain\User</urn:userName>
         <urn:password>pwd</urn:password>
         <!--Optional:-->
         <urn:authentication></urn:authentication>
         <!--Optional:-->
         <urn:locale></urn:locale>
         <!--Optional:-->
         <urn:timeZone></urn:timeZone>
      </urn:AuthenticationInfo>
   </soapenv:Header>
   <soapenv:Body>
      <urn:HelpDesk_QueryList_Service>
         <urn:Qualification>'Status' = "Assigned"</urn:Qualification>
         <urn:startRecord>0</urn:startRecord>
         <urn:maxLimit>1</urn:maxLimit>
      </urn:HelpDesk_QueryList_Service>
   </soapenv:Body>
</soapenv:Envelope>

We can push this to a file and call it C:\mes.xml
We can then read it from file:
[xml]$mysoap = gc C:\mes.xml
Once this is done we have to send it using previously created function so:
$answers = Execute-SOAPRequest $mysoap $url

Putting it all together :

function Execute-SOAPRequest 
( 
        [Xml]    $SOAPRequest, 
        [String] $URL 
) 
{ 
        write-host "Sending SOAP Request To Server: $URL" 
        $soapWebRequest = [System.Net.WebRequest]::Create($URL) 
        $soapWebRequest.Headers.Add("SOAPAction","`"urn:HPD_IncidentInterface_WS/HelpDesk_QueryList_Service`"")

        $soapWebRequest.ContentType = "text/xml;charset=`"utf-8`"" 
        $soapWebRequest.Accept      = "text/xml" 
        $soapWebRequest.Method      = "POST" 
        
        write-host "Initiating Send." 
        $requestStream = $soapWebRequest.GetRequestStream() 
        $SOAPRequest.Save($requestStream) 
        $requestStream.Close() 
        
        write-host "Send Complete, Waiting For Response." 
        $resp = $soapWebRequest.GetResponse() 
        $responseStream = $resp.GetResponseStream() 
        $soapReader = [System.IO.StreamReader]($responseStream) 
        $ReturnXml = [Xml] $soapReader.ReadToEnd() 
        $responseStream.Close() 
        
        write-host "Response Received."

        return $ReturnXml 
}

$url = 'https://XYZ/arsys/services/ARService?server=ABC&webService=HPD_IncidentInterface_WS'
[xml]$mysoap = gc C:\mes.xml
$answers = Execute-SOAPRequest $mysoap $url

In the query for ITSM i put maxlimit 1 , so i will receive at the end only 1 ticket. Below is the screenshot while reading it:
itsm3

Which proves that it’s possible to get the ticket. Maybe i can figure it out more in upcoming days. Will update this post if i have something new about this topic.

I think that what is happening is … ( will continue this, once i will gather some more information )
UPDATE:
My colleage Viktor Bocz wrote me some explanation about what is happening there. He has also written for me an altered wsdl file, which i have been reading using new-webserviceproxy instead of connecting to the one from where itsm webservice sits.

The issue is with the definition of the response to the HelpDesk_QueryList_Service call in the wsdl.

original

<xsd:element type="s0:GetListOutputMap" name="HelpDesk_QueryList_ServiceResponse"/>
<xsd:complexType name="GetListOutputMap">
<xsd:sequence><xsd:element type="xsd:string" name="getListValues" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>

The soap response usms returns looks like:

    <ns0:HelpDesk_QueryList_ServiceResponse xmlns:ns0="urn:HPD_IncidentInterface_WS">
       <ns0:getListValues>
          <ns0:Assigned_Group>XYZ</ns0:Assigned_Group>
          <ns0:Assigned_Support_Company>XYZ</ns0:Assigned_Support_Company>
…

The response body is expected to be a string as per the definition, but the xml in the response body it’s not escaped or returned as character data (xml cdata). For this reason the cmdlet tries to unmarshall (not sure if this is the right term here for parsing xml, in java it is) the response, but fails as it encounters an unexpected element. As per the SOAP protocol this behavior is correct, the cmdlet properly verifies the response syntax.

To resolve the issue on the client side (ultimately it should be corrected on the server-side), we need to alter the wsdl to have the proper response type definition. The below complex type was made up by inspecting the response (changed/new in red), so there’s no guarantee that it’s 100% correct, all we know that it works for us.

Altered element and type definition to match the response (s0 is the target namespace):

   <xsd:element name="HelpDesk_QueryList_ServiceResponse" type="s0:GetListOutputMap"/>
   <xsd:complexType name="GetListOutputMap">
    <xsd:sequence>
     <xsd:element maxOccurs="unbounded" name="getListValues" type="s0:GetOutputListMap"/>
    </xsd:sequence>
   </xsd:complexType>

<xsd:complexType name="GetOutputListMap">
    <xsd:sequence>
     <xsd:element name="Assigned_Group" type="xsd:string"  minoccurs="0" maxoccurs="unbounded"/>
     <xsd:element name="Assigned_Support_Company" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>
     <xsd:element name="Assigned_Support_Organization" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>
     <xsd:element name="Assignee" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>
     (...)
     <xsd:element name="Submit_Date" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>
    </xsd:sequence> 
   </xsd:complexType>


So from those remarks from Viktor and new wsdl file, we can get our tickets using the “standard” approach:
finalitsm

Advertisements

9 thoughts on ““HelpDesk_QueryList_Service” with “3” argument(s): “There is an error in XML document (3, 4).

  1. Is it possible to share the updated wsdl? or Highlight exactly the changes that needs to be carried out in the wsdl file.

  2. Thanks so much for posting this, really helped me out after a few hours of choice language and staring aimlessly at the Object Browser in VS…..for clarity, here’s what I ended up doing with the WSDL to get it working as it should.

    […]

  3. Wow, incredibly helpful, and great details. Thanks! So in our case, the ARSYS instance is actual hosted OnBMC service with the bug. Surprising and disappointing. But the revision you suggest made it work great. For those asking for the WSDL, here is the diff (from my specific case, which is OnBMC hosted/SaaS/whatever) so you can make the one edit yourself:
    C:\temp>diff HPD_IncidentInterface_WS_orig.xml HPD_IncidentInterface_WS_Fixed.xml
    178c178
    <

    >

    • Ugh sorry, the diff got munched by wordpress sanitizing. Not sure how to make it display nicely, so i’ll just say replace type=”xsd:string” with type=”s0:GetOutputMap” on that one line. That’s it.

  4. Hi ,

    I am getting o/p as

    Initiating Send.
    Send Complete, Waiting For Response.
    Response Received.

    But after giving $answers.ChildNodes[1].Body.HelpDesk_QueryList_ServiceResponse.getListValue

    i am getting below error:

    $answers.ChildNodes[1].Body.HelpDesk_QueryList_ServiceResponse.getListValues
    Unable to index into an object of type System.Xml.XmlChildNodes.
    At line:1 char:21
    + $answers.ChildNodes[ <<<< 1].Body.HelpDesk_QueryList_ServiceResponse.getListValues
    + CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex

    please suggest.

    Thanks in advance.

    • When i am checking echo $answers i am getting:

      echo $answers

      xml Envelope
      — ——–
      version=”1.0″ encoding=”utf-8″ Envelope

      and write-host $answer is giving different o/p

      write-host $answers
      #document

  5. Hi ,

    Can you help me in fetching audit log details?

    I am able to fetch details like inc number,assignee,group .etc.. and able to send mail also with the help of Powershell script.

    Now i want to fetch audit log details .. so that i can find for how many hours ticket was in progress state.

    I can’t find any webservice related to audit log.

    Regards,
    Nitin

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s