Create Service Description for Connections REST API

The documentation for the Connections Profile API is very helpful in understanding how it works and what parts you would need to implement for use with HCL Leap.

Modifying the Sample for your Environment

Included here is the entire service description file that implements several of the inputs and outputs that are available with the Connections Profile REST API.  Before you can use this you will have to specify your own server URL.

<?xml version="1.0" encoding="UTF-8"?> <serviceDescription> <id>Connections-Profile-Lookup-Service</id> <defaultLocale>en-us</defaultLocale> <transportId>HTTPServiceTransport</transportId> <name>Connections Profile Lookup Service</name> <description>The Connections Profile Lookup Service information about the specific employee.</description> <inbound> <parameters> <parameter> <id>searchEmail</id> <name>Search Email</name> <description>The employee email to search for.</description> <mandatory>false</mandatory> <type>STRING</type> </parameter> <parameter> <id>searchUID</id> <name>Search UID</name> <description>Unique ID that represents a specific person.</description> <mandatory>false</mandatory> <type>STRING</type> </parameter> <parameter> <id>format</id> <name>Search Format</name> <description>Specifies whether you want a full profile or partial profile to be returned. Options are lite or full. The default value is lite.</description> <mandatory>false</mandatory> <type>STRING</type> </parameter> </parameters> <serviceMapping> <constants> <constant> <id>request-url</id> <value>https://serverURL/profiles/atom/search.do</value> </constant> <constant> <id>request-method</id> <value>GET</value> </constant> <constant> <id>request-ignore-empty-query</id> <value>true</value> </constant> </constants> <mapping xmlns=""> <mapping target="transport:request-url" source="constant:request-url" /> <mapping target="transport:request-query-email" source="parameter:searchEmail" sourceType="STRING" targetType="STRING"/> <mapping target="transport:request-query-userid" source="parameter:searchUID" sourceType="STRING" targetType="STRING"/> <mapping target="transport:request-query-format" source="parameter:format" sourceType="STRING" targetType="STRING"/> <mapping target="transport:request-method" source="constant:request-method" sourceType="NOOP" targetType="STRING"/> <mapping target="transport:request-ignore-empty-query" source="constant:request-ignore-empty-query" sourceType="NOOP" targetType="STRING"/> </mapping> </serviceMapping> </inbound> <outbound> <parameters> <parameter> <id>fullname</id> <name>Employee Full name</name> <description></description> <type>STRING</type> </parameter> <parameter> <id>email</id> <name>Employee Email</name> <description>Employee email address</description> <type>STRING</type> </parameter> <parameter> <id>userid</id> <name>Employee User ID</name> <description></description> <type>STRING</type> </parameter> <parameter> <id>role</id> <name>Role</name> <description></description> <type>STRING</type> </parameter> <parameter> <id>org</id> <name>Organization</name> <description></description> <type>STRING</type> </parameter> <parameter> <id>title</id> <name>Title</name> <description></description> <type>STRING</type> </parameter> <parameter> <id>isMgr</id> <name>Is Manager?</name> <description>Returns "Y" if a manager and "N" if not</description> <type>STRING</type> </parameter> <parameter> <id>notesID</id> <name>Notes ID</name> <description>Returns formatted Notes ID</description> <type>STRING</type> </parameter> <parameter> <id>street-address</id> <name>Street Address</name> <description>Returns street address</description> <type>STRING</type> </parameter> <parameter> <id>street-address2</id> <name>Extended Street Address</name> <description>Returns extended street address</description> <type>STRING</type> </parameter> <parameter> <id>city</id> <name>City</name> <description>Returns City</description> <type>STRING</type> </parameter> <parameter> <id>region</id> <name>Province/State</name> <description>Returns province or state</description> <type>STRING</type> </parameter> <parameter> <id>postal-code</id> <name>Postal Code</name> <description>Returns Postal Code</description> <type>STRING</type> </parameter> <parameter> <id>country</id> <name>Country</name> <description>Returns country</description> <type>STRING</type> </parameter> <parameter> <id>country-code</id> <name>Country Code</name> <description>Returns country code</description> <type>STRING</type> </parameter> <parameter> <id>work-location-code</id> <name>Work Location</name> <description>Returns work location</description> <type>STRING</type> </parameter> </parameters> <serviceMapping xmlns:atom="http://www.w3.org/2005/Atom" xmlns:snx="http://www.ibm.com/xmlns/prod/sn" xmlns:sp_0="http://www.w3.org/1999/xhtml"> <mapping> <mapping source="transport:response-entity" target="parameter:fullname" sourceRef="atom:feed/atom:entry/atom:contributor/atom:name" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:email" sourceRef="atom:feed/atom:entry/atom:contributor/atom:email" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:userid" sourceRef="atom:feed/atom:entry/atom:contributor/snx:userid" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:role" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span/sp_0:div[@class='role']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:org" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span/sp_0:div[@class='org']/sp_0:span[@class='organization-unit']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:title" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span/sp_0:div[@class='title']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:isMgr" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='x-is-manager']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:notesID" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='x-groupwareMail']" sourceType="xml" targetType="STRING"/> <!-- Address Info--> <mapping source="transport:response-entity" target="parameter:street-address" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:div[@class='street-address']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:street-address2" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:div[@class='extended-address x-streetAddress2']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:city" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:span[@class='locality']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:region" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:span[@class='region']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:postal-code" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:span[@class='postal-code']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:country" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:div[@class='country-name']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:country-code" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:div[@class='x-country-code']" sourceType="xml" targetType="STRING"/> <mapping source="transport:response-entity" target="parameter:work-location-code" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span[@class='vcard']/sp_0:div[@class='adr work postal']/sp_0:div[@class='x-worklocation-code']" sourceType="xml" targetType="STRING"/> </mapping> </serviceMapping> </outbound> </serviceDescription>

Understanding the Parts

I will not be describing the parts that I explained in the previous article, rather will focus on what is different.  The significant difference is the complex service mapping statements.  These statements are XPath queries that parse the XML into the defined outbound parameters.

 I was able to determine these complex queries by reviewing the XML that was returned by the Connections service, you can review the XML in the Connections documentation.

 The most significant thing to mention is the attention to namespaces.  If you review the XML result from the service you will see:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:fh="http://purl.org/syndication/history/1.0" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:snx="http://www.ibm.com/xmlns/prod/sn" xmlns:thr="http://purl.org/syndication/thread/1.0">

The "xmlns" are all the definitions of the namespaces that are used in the XML that gets returned by the service.  Any of the ones that are used in the elements that we want to retrieve we need to include in our serviceMapping:

<serviceMapping xmlns:atom="http://www.w3.org/2005/Atom" xmlns:snx="http://www.ibm.com/xmlns/prod/sn" xmlns:sp_0="http://www.w3.org/1999/xhtml"> <mapping> . . . <mapping source="transport:response-entity" target="parameter:role" sourceRef="atom:feed/atom:entry/atom:content/sp_0:div/sp_0:span/sp_0:div[@class='role']" sourceType="xml" targetType="STRING"/> . . . </mapping> </serviceMapping>

Then we need to define the sourceRef for the element in the XML that we want to retrieve.  This is as simple as analyzing the XML and then specifying each level till you get to the one you want.  In this example"atom" and "sp_0" are the namespaces that insure we reference the correct element.  The "[@class='role'] is a predicate, which will return the "div" element that has a class attribute that equals "role":

Note: Further detail on all of the parts of this service description file can be found online as part of the HCL Leap Documentation.

Deploying the Service Description file

The completed xml file gets deployed according to the procedure in our documentation.

Testing Your New Connections Profile Service

If the ServiceCatalog/1 directory already existed (before the server was last restarted) then FEB will automatically detect (it takes about 50 seconds) the new XML file and add it to your Services Catalog.

  1.  Create two fields to your form ("email", and "name").

  2. Under Settings...Services...Form 1, Add a service configuration.  Select "Connections Profile Lookup Service" from the list (if it does not appear skip ahead to the troubleshooting section).

  3. On the Inputs tab, link the "Email" item with your email field.

  4. On the Outputs tab, link the "Name" item with the name field.

  5. Click OK to complete the Service Configuration. 

  6. In the properties of the email field, click the Events tab.  Select the onItemChange event, click the check box to call a service and select the service that you created. 

  7. Save and Preview the form.  Enter a valid email address in the email field and tab to the next field.  The name of the person that matches the specified email should appear in the name field.  If it does not then you will have to begin the troubleshooting process.

 Troubleshooting Your Service Configuration

  • You may have a syntactical error in your XML file causing your service to not appear in the list of available services

  • You may have an error in the mapping definition of inputs or outputs causing nothing to happen when the service executes (but it is visible in the list of services).

 Enable the FEB tracing.  Within WebSphere Application Server add the trace string "com.ibm.form.*=finest", then inspect the SystemOut.log and trace.log that gets created to see what it may be saying about the situation.  The log file will tell you if the xml file was loaded successfully and usually will give a brief explanation if it was not.

 The trace also contains detailed information about the input and out parameters that it processed during the service execution:

 It will also indicate when it has refreshed the contents of the files (in case you are making changes and wondering when they have been applied):