Asset Manager Web Service via SOAP : how to handcraft xml

  • KM00450597
  • 10-Jun-2013
  • 20-Feb-2014

Summary

How to communicate with AssetManager WebService via handwritten XML

Question

How to communicate with AssetManager WebService via handwritten XML is a common question.

Due to the technologies in use, there is many points to take into account before starting.

This is what this document will present.

Answer

Regarding how to reach this goal, please find below what kind of technology are in use.
AssetManager is a WebService. This mean that the communication follow a specific formatting, and use SOAP messages as underlying data transport.
Soap itself, use XML messages to communicate on the low level.
This means that the xml messages have to be valid XML/SOAP/WebServices messages. Following strict XML is definitely not sufficient to reach this goal.
 
SOAP for example was not designed in any way to be useable by hand, even if it may be with some very simple interfaces. AssetManager is tending on the very complex side of SOAP. (namespaces, extended types, types redefinitions)
As consequence, the AssetManager samples for WSDL is not shipped with XML messages, and "stubs" are used to take care of the WebService/SOAP layer.
This is done via :
 
  •  ANT for java
  • the WebServices wrapper for visual studio
 
As consequence, there is no need to deal with any of the WSDL complexities.
SOAP is a way to serialize full featured objects (i.e. code, classes, properties, etc)  over a wire(xml as media here) , and then to deserialize the object again on the other side, to get an object to deal with.
The WSDL grammar definition that AssetManager return deal with all the internal logic, there don’t have to deal with them when using java/visual studio. That’s all the magic and beauty of WSDL, it was designed to be able to write code as shown below in a couple of minutes.
 
So, using xml is fully outside of the scope of support. It would complexify  a lot the exchange, as the wrapper allow some very small code to be written like :
 
// getting an object for the location (contain default values, etc), in this case, the barcode is already set in the object returned :
    Location newLocation = api.retrieveNewLocation(null);
 
//initializing a new string, and setting it to the proper value:
      ACString name = new ACString();
      name.setValue("myNewLocation");
 
//affecting the name to location freshly returned by AssetManager.
      newLocation.setName(name);
 
//saving the change to the database.
      api.saveLocation(newLocation);
 
 
By using the java sample, similar code can be written. The wrapper is easily generated when any version change occur. By not using it, there is a need to update the code each time a change occur in the database structure that affect the current document or when updating the version of AssetManager (even a minor patch may broke the code).(use a tag, never head for such purposes).
 
Find below an unsupported sample, that show the exact same operation from the xml point of view (fully tested, it really function). Due to the dynamic nature of the exchange, it can’t be played as it is on your database, you have to craft your xml matching the schema that your AssetManager instance return. The following sample give a good canvas to start with. It also demonstrate that handcrafted xml is not the most simple way to do, as there is definitely better ways as : connect-it, import module scheduled on a regular basis, etc.
 
Small general warnings :
 
Take care to the fact that is not supported, and that support won’t answer to any query regarding :
  • How this function.
  • Why this function this way.
  • How to solve a particular error.
  • How to do something specific.
 
As the standard usage is with the help of a WSDL, and allow to rebuild the application easily when there is a change, be also warned that each minor patch has the ability to change the way the internal object behave (ie, this was done recently with the addition of the multitenancy), and may require you to discover again how to exchange with the product with handcrafted xmls. Support won’t help you in this way either. Customers using the WSDL stubs are not tied to this constraint, as the wsdl and the application rebuild process take care of this for them, making the change fully transparent.
 
What is supported is to use a real soap application with the stubs provided, we won’t enter in the product logic/mechanism that is not exposed to customer, what is exposed is soap, and soap is much more than xml, as it mean understanding the schema returned by AssetManager to understand how to phrase an answer (it’s around 100 mb of xml samples to get in head when exchanging with AM, even the smallest function got a huge definition, several mb for a very small interaction)
 
 
 
 
How to create a new location using soap :
 
// getting an object for the location (contain default values, etc), as you will notice, the barcode is already set):
    Location newLocation = api.retrieveNewLocation(null);
 
Is equivalent to the 2 xml files exchanged by am and the soap client :
 
retrievenewlocation-query.xml :
 
   <soapenv:Header/>
   <soapenv:Body>
      <wsdl:retrieveNewLocation> 
      </wsdl:retrieveNewLocation>
   </soapenv:Body>
</soapenv:Envelope>
 
slightly simplified response, but the whole answer has to be used for the next exchange :  27 kb. The content below is a dynamic one, it will not be the same  between each call, as this is full objects that are "serialized" over xml :
 
retrievenewlocation-response.xml  :
 
   <soapenv:Header>
      <AMCustomHeader defaultTenantId="0" defaultTenantName="Shared Data" isSystemTenantOn="true" soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0"/>
   </soapenv:Header>
   <soapenv:Body>
      <retrieveNewLocationResponse xmlns="http://schemas.hp.com/AssetManager/Custom/Head/Extended/Wsdl">
         <retrieveNewLocationResponse xsi:type="ExtendedTypes:Location" xmlns:cmdb="http://schemas.hp.com/ActiveCMDB/R2/Common" xmlns:acbase="http://schemas.hp.com/AssetManager/R501/ACBaseTypes" xmlns:acdoc="http://schemas.hp.com/AssetManager/R501/ACDocumentBaseTypes" xmlns:ExtendedTypes="http://schemas.hp.com/AssetManager/Custom/Head/Extended/Types">
            <acdoc:InternalSelfDescription xsi:type="xsd:string"/>
           <acdoc:InternalState>rO0ABXcEAAAAA3VyAAJbQqzzF/gGCFTgAgAAeHAAAAD7rO0ABXcEAAAACHNyABFqYXZhLmxhbmcuQm9vbGVhbs0gcoDVnPruAgABWgAFdmFsdWV4cAFzcgAOamF2YS51dGlsLkRhdGVoaoEBS1l0GQMAAHhwdwgAAAE595Q5UHh0AAhFeHRlbmRlZHQACExvY2F0aW9ucHQACkFDQmVhbkJhc2VzcgAjY29tLnBlcmVncmluZS5hYy5kYXRhLkVEb2N1bWVudFR5cGUAAAAAAAAAMgIAAkkAB2ZpVmFsdWVMAAlmc3RyVmFsdWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAAJ0AAhEb2N1bWVudHQAB1dyYXBwZWR1cQB+AAAAAAHkrO0ABXcEAAAACHQAOGNvbS5wZXJlZ3JpbmUuYWMuZGF0YS53cy5BQ0RhdGFiYXNlRG9jdW1lbnRJbnRlcm5hbFN0YXRlcHNyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlc
 
 
From the response of AM :
 
//initializing a new string, and setting it to the proper value:
      ACString name = new ACString();
      name.setValue("myNewLocation");
 
//affecting the name to location freshly returned by AssetManager.
      newLocation.setName(name);
 
This is equivalent to the xml exchange below, slightly reduced. Take care to the fact that the envelope was fully changed to match the type needed, as this make the exchange simpler (ie, don’t have to rename each node namespace to match the default one )
slightly simplified here, but the whole answer content  27 kb has to be used.)
Again, this is a dynamic content, this will never be twice the same : 
 
savelocation-query.xml :
 
   <soapenv:Header/>
   <soapenv:Body>
      <wsdl:saveLocation>
         <wsdl:bean>
                      <acdoc:InternalSelfDescription xsi:type="xsd:string"/>
            <acdoc:InternalState>rO0ABXcEAAAAA3VyAAJbQqzzF/gGCFTgAgAAeHAAAAD7rO0ABXcEAAAACHNyABFqYXZhLmxhbmcuQm9vbGVhbs0gcoDVnPruAgABWgAFdmFsdWV4cAFzcgAOamF2YS51dGlsLkRhdGVoaoEBS1l0GQMAAHhwdwgAAAE595Q5UHh0AAhFeHRlbmRlZHQACExvY2F0aW9ucHQACkFDQmVhbkJhc2VzcgAjY29tLnBlcmVncmluZS5hYy5kYXRhLkVEb2N1bWVudFR5cGUAAAAAAAAAMgIAAkkAB2ZpVmFsdWVMAAlmc3RyVmFsdWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAAJ0AAhEb2N1bWVudHQAB
….
 
    <ExtendedTypes:Name mandatory="true" irrelevant="false" modified="false" writable="true" readable="true" xsi:type="acbase:ACString">
               <cmdb:value>MyNewLocationName</cmdb:value>
            </ExtendedTypes:Name>
<ExtendedTypes:BarCode mandatory="true" irrelevant="false" modified="false" writable="true" readable="true" xsi:type="acbase:ACString">
               <cmdb:value>L001077</cmdb:value>
            </ExtendedTypes:BarCode>
        </wsdl:bean>
      </wsdl:saveLocation>
   </soapenv:Body>
</soapenv:Envelope>
//saving the change to the database.
      api.saveLocation(newLocation);
 
 
To what AssetManager will answer the following if the exchange is correct. This is always the way it will inform of errors (ie, already existing objects, etc) :
 
savelocation-response.xml :
 
   <soapenv:Header>
      <AMCustomHeader defaultTenantId="0" defaultTenantName="Shared Data" isSystemTenantOn="true" soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0"/>
   </soapenv:Header>
   <soapenv:Body>
      <saveLocationResponse xmlns="http://schemas.hp.com/AssetManager/Custom/Head/Extended/Wsdl">
         <saveLocationResponse xsi:type="ExtendedTypes:LocationBase" xmlns:cmdb="http://schemas.hp.com/ActiveCMDB/R2/Common" xmlns:acbase="http://schemas.hp.com/AssetManager/R501/ACBaseTypes" xmlns:acdoc="http://schemas.hp.com/AssetManager/R501/ACDocumentBaseTypes" xmlns:ExtendedTypes="http://schemas.hp.com/AssetManager/Custom/Head/Extended/Types">
            <acdoc:InternalUniqueId xsi:type="xsd:string">AssetCenter/Location/134373</acdoc:InternalUniqueId>
            <acdoc:InternalSelfDescription xsi:type="xsd:string"/>            <acdoc:InternalState>rO0ABXcEAAAAA3VyAAJbQqzzF/gGCFTgAgAAeHAAAAD8rO0ABXcEAAAACHNyABFqYXZhLmxhbmcuQm9vbGVhbs0gcoDVnPruAgABWgAFdmFsdWV4cAFzcgAOamF2YS51dGlsLkRhdGVoaoEBS1l0GQMAAHhwdwgAAAE595Q5UHh0AAhFeHRlbmRlZHQACExvY2F0aW9ucHQACkFDQmVhbkJhc2VzcgAjY29tLnBlcmVncmluZS5hYy5kYXRhLkVEb2N1bWVudFR5cGUAAAAAAAAAMgIAAkkAB2ZpVmFsdWVMAAlmc3RyVmFsdWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAAB0AAlSZWZlcmVuY2V0AAdXcmFwcGVkdXEAfgAAAAAAz6ztAAV3BAAAAAZ0ADhjb20ucGVyZWdyaW5lLmFjLmRhdGEud3MuQUNEYXRhYmFzZURvY3VtZW50SW50ZXJuYWxTdGF0ZXBzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAIM5XNxAH4AAQAAAABzcgARamF2YS5sYW5nLkJvb2xlYW7NIHKA1Zz67gIAAVoABXZhbHVleHABc3EAfgAFAHNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAAdwQAAAAKeA==</acdoc:InternalState>
            <acdoc:IgnoreSysfilter xsi:type="xsd:boolean">false</acdoc:IgnoreSysfilter>
         </saveLocationResponse>
      </saveLocationResponse>
   </soapenv:Body>
</soapenv:Envelope>
 
This answer contain the primary key id in the node : <acdoc:InternalUniqueId xsi:type="xsd:string">AssetCenter/Location/134373</acdoc:InternalUniqueId>
 
Take care to the fact that this may change in future versions/patches, as this is an internal mechanism not usually exposed to customers using the stubs.
 
As demonstrated, SOAP and the underlying technlogies, are the only media fully supported, and this is a really meant to simplify the interfacing process.
AssetManager is a WebSercice, and not an XML listener.