PLM Tech Tips

PLM Tech Tips: Agile SOAP Web Services Primer, or, What they don’t tell you about using Agile SOAP Web Services

Oracle does provide documentation for the Agile Web Services.  The documentation, however, assumes you’ll be using Java to connect, building with Ant.  If you’re using another method of building the web service calls, you’ll have difficulty constructing the payload from just the documentation provided.  In this blog, we take the mystery out of calling the web services, provide code you can copy/paste, and hopefully save you some time and teeth-gnashing.

A good tool for testing an xml payload is SoapUI. Download page: https://www.soapui.org/downloads/soapui.html


Table of Contents

Where are the web services?

What are all of the web services?

That’s all I need right?

How do you actually write data?

What does an error response look like?

How can I use the web services with my automatic mapping tools?


Where are the web services?

The documentation says you will find them here: 
http://<host>:<port>/core/services/<serviceName>?wsdl

Unfortunately, they have not been there for a number of releases.  In our 9.3.4 system, our web services are here: http://<host>:<port>/CoreService/services/<serviceName>?wsdl.

Try that, but if it’s not there, do the following:

  1. On your installed Agile server, find your application.ear file
  2. Unzip this file
  3. There you will find META-INF/application.xml

AgileTipsWebServicesPrimer1.png

In this file you will find the CoreService.war web application module configuration.  The context-root mapping tells you where this will be found.  Here you can see our Agile 9.3.4 Agile web services will be mapped to the context root of /CoreServices.
AgileTipsWebServicesPrimer2.png

What are all of the web services?
You can find this in the documentation, but here is a list of the service names you can use when you want to get all of the WSDL for all of the web services:

     • AdminMetadata
     • Attachment
     • BusinessObject
     • Collaboration
     • DocPublishing
     • ECService
     • Folder
     • PC
     • PGC
     • Project
     • Report
     • Search
     • Table
     • UserProfile

Hint: you can find these in the web.xml file of the CoreService WAR file.  CoreService.war is inside the application.ear.  Unzipping CoreService.war will give you a WEB-INF directory.  Inside this WEB-INF directory is the web.xml.  web.xml specifies the url‑pattern for each servlet mapping.
AgileTipsWebServicesPrimer3.png

Note: You should clean up those zip files and not customize the web applications with this knowledge; stick to the published APIs.

That’s all I need right?
In theory, yes; but, there are a few things you’ll need.  First, some of the WSDL files reference special XSD, and some of those reference other XSD.  So if you need to get these local and really understand what is going on, be sure to download the referenced XSD and see what is inside.

In the example WSDL below, from Agile 9.3.4, note the reference to …/BusinesObject?xsd=3
This is the URL for the XSD file.  Download this file.  There, look for further <xsd:import/>
elements identifying further XSD files to be inspected.
AgileTipsWebServicesPrimer4.png

How do you actually write data?
Having the WSDL and content schema, we should be on our way.  Unfortunately, this is the most vexing part.  The provided schemas do not actually have any specifications for the actual attributes in our Agile schema.  Instead, inside the schema where we put our data is <xsd:any/>.  This does not help identify what we need to put into the fields to update Agile objects or tables.

Don’t fear, after much trial and many errors, we’ve picked out the different things you need to do and identified what you need to put into those pesky <any/> elements to update Agile to do a successful update.

Below, we’re updating a title block attribute.  Key to the success of the call are the locations of the namespace callouts, and the “common:type” callout. The wsdl (xsd) for 9.3.5 does not include the xmlns:common url in the Envelope but it is necessary in your request. Otherwise you get an error that “common” is an undeclared prefix.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:biz="http://xmlns.oracle.com/AgileObjects/Core/Business/V1"
      xmlns:common="http://xmlns.oracle.com/AgileObjects/Core/Common/V1">
   <soapenv:Header/>
   <soapenv:Body>
      <biz:updateObject>
         <request>
            <messageId>message_00001</messageId>
            <messageName>sampleUpdateForDennis</messageName>
            <!--Optional:-->
            <sender>myIntegration v1.0</sender>
            <disableAllWarnings>true</disableAllWarnings>
            <requests> <!-- can be repeated for additional objects in one request -->
               <classIdentifier>Part</classIdentifier>
               <objectNumber>P00230</objectNumber>
               <data rowId="0">
                   <itemCategory  common:type="AgileListEntryType">
                       <selection>
                           <value>Software General Offering</value>
                       </selection>
                   </itemCategory>
               </data>
            </requests>
         </request>
      </biz:updateObject>
   </soapenv:Body>
</soapenv:Envelope>

Typical values for “common:type” are:
     • Text and Multi-text: no type necessary
     • AgileListEntryType for single and multi-lists.

        For multi list, include multiple <selection/> elements
     • AgileObjectListEntryType for object reference fields
     • AgileMoneyType for money values
     • dateTime for date/time attributes

That’s all well and good, but for Page 3 or Page 2 attributes you will most likely encounter the following error:

Attribute "2,020" not found.

(Replace “2,020” with your attribute number)

In this case, you need to include the attribute Base ID and use the “Attribute” nomenclature, as follows.  Use the Agile Java Client to identify the “Base ID” and “Attribute” from the attribute table for the subclass of interest.  For the Attribute, pull just the second portion, excluding the table name.  For example in the following image, choose “list31”, not list01.

This strategy will work for all attributes, including title block attributes.  So it’s safest to just use this all of the time.
AgileTipsWebServicesPrimer5.png


Use the Attribute for the element name and include the Base ID as an XML attribute called “attributeId”.  Here’s an example. 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:biz="http://xmlns.oracle.com/AgileObjects/Core/Business/V1"
      xmlns:common="http://xmlns.oracle.com/AgileObjects/Core/Common/V1">
   <soapenv:Header/>
   <soapenv:Body>
      <biz:updateObject>
         <request>
            <messageId>message_00002</messageId>
            <messageName>sampleUpdateForDennis</messageName>
            <!--Optional:-->
            <sender>myIntegration v1.0</sender>
            <disableAllWarnings>true</disableAllWarnings>
            <requests> <!-- can be repeated for additional objects in one request -->
               <classIdentifier>Consulting Guide</classIdentifier>
               <objectNumber>CG-000113</objectNumber>
               <data rowId="0">
                   <list31 common:type="AgileListEntryType" attributeId="1539">
                       <!-- for a text field, just put in a text node here -->
                       <!-- for a list or multilist: -->
                       <selection>
                           <value>Data Migration</value>
                       </selection>
                   </list31>
               </data>
            </requests>
         </request>
      </biz:updateObject>
   </soapenv:Body>
</soapenv:Envelope>

Following is an example where we set a number of other value types, including an object reference list, a money value, and a date/time. 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:biz="http://xmlns.oracle.com/AgileObjects/Core/Business/V1"
      xmlns:common="http://xmlns.oracle.com/AgileObjects/Core/Common/V1">
   <soapenv:Header/>
   <soapenv:Body>
      <biz:updateObject>
         <request>
            <messageId>message_00004</messageId>
            <messageName>sampleUpdateForDennis</messageName>
            <sender>myIntegration v1.0</sender>
            <disableAllWarnings>true</disableAllWarnings>
            <requests>
               <classIdentifier>Consulting Guide</classIdentifier>
               <objectNumber>CG-000113</objectNumber>
               <data rowId="0">
                   <commodity common:type="AgileObjectListEntryType" attributeId="12938">
                       <selection>
                           <classIdentifier>Commodity</classIdentifier>
                           <objectIdentifier>Connector</objectIdentifier>
                       </selection>
                   </commodity>
                   <IMMoney11 common:type="AgileMoneyType" attributeId="2000019549">
                       <amount>12.50</amount>
                       <currency>USD</currency>
                   </IMMoney11>
                   <date31 common:type="dateTime" attributeId="1534">2001-10-26T21:32:52+02:00</date31>
                   <multiText50 attributeId="1567">App to Generate SOW from Agile Project</multiText50>
               </data>
            </requests>
         </request>
      </biz:updateObject>
   </soapenv:Body>
</soapenv:Envelope>

What does an error response look like?
Also as an example, here’s the response when there’s an error.  For example here is a response from when we’ve attempted to update an object that does not exist.

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns0:updateObjectResponse xmlns:ns0="http://xmlns.oracle.com/AgileObjects/Core/Business/V1">
         <response>
            <messageId>message_00001</messageId>
            <messageName>sampleUpdateForDennis</messageName>
            <statusCode>FAILURE</statusCode>
            <exceptions>
               <id>0</id>
               <exception>
                  <identifier>
                     <id xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                     <name>Part</name>
                     <displayName>P00278</displayName>
                  </identifier>
                  <exceptionId>WS_5</exceptionId>
                  <message>Unknown Number: P00278. Object not found</message>
                  <cause xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
               </exception>
            </exceptions>
         </response>
      </ns0:updateObjectResponse>
   </S:Body>
</S:Envelope>

How can I use the web services with my automatic mapping tools? 
I have an integration tool (think Magic XPI, Informatica, IBM Integration Bus, Oracle ESB, etc).  The tool is supposed to let me easily map fields and columns for my integration, but when I try to connect with the Agile services I get something like the following:
AgileTipsWebServicesPrimer6.png
This is the nettlesome <any/>.  The problem is that the WSDL and XSD for the Agile web services do not include the actual fields you want to map to.  Hence there is nothing for your service to map to.

The simple solution is to hand-generate a custom WSDL including your attributes, that will let your mapping tool do the job it needs.  If you need help with it, please contact us and we’ll be glad to help.

Subscribe to the ZWS Blog

Recent Posts

Never miss a tip
and receive new
blog notifications
in your inbox.
SUBSCRIBE NOW