Universal Description, Discovery, and Integration (UDDI) is a set of APIs that provide a standard framework for electronic and collaborative commerce. Businesses can publish their services and inquire about the services published by other businesses at a UDDI registry.
UDDI has defined two APIs. One is for publishing and the other relates to inquiries. If you want to offer on-line services to your customers, you will use UDDI's Publishing API to publish or advertise your service. On the other hand, if you are looking for a specific service, you will use the Inquiry API to execute a search.
Each of the UDDI APIs contains several methods. The methods of the UDDI Inquiry API allow general to specific (drilled down) searching through the UDDI registry. Once a user has found the details for the products or services/products he is interested in, he can invoke those services using Web Services Description Language (WSDL). UDDI and WSDL together make Web services possible.
For complete technical details of UDDI Inquiry API- and WSDL-based Web services, refer to the articles "Using UDDI as a Search Engine" and "Deploying Web Services with WSDL" (see Resources, right).
In this article, I will develop a UDDI client that invokes services registered in the UDDI. The UDDI client provides a sample implementation of the UDDI Inquiry API methods.
Start with a User
In order to demonstrate or test the functionality of the UDDI client, build a Java applet, with a GUI, to function as the user of the UDDI client. I'll call this user a test container. Neither the test container nor its GUI, is the focus of this article, but its interaction with the UDDI client helps explain the usage model of UDDI clients.
Although the test container is an applet, the UDDI client in this article will work with Java Foundation Classes/Swing, Abstract Window Toolkit, or server-side (for example, an Enterprise JavaBean running inside a container) as well.
A UDDI Client in Four Steps
The UDDI client will participate in four tasks:
- The user asks the UDDI client to invoke the UDDI registry.
- The UDDI client authors a UDDI invocation request and sends it to the registry.
- The registry takes appropriate action upon the invocation request. For example, if it is a search invocation request, the UDDI registry gathers the required data, authors a response, and sends it back to the requesting client.
- The UDDI client processes the response and provides meaningful results to the user.
This UDDI client hides all SOAP-related issues from the user, so no knowledge of SOAP is necessary to use the implementation. The implementation also has a small footprint so it is suitable for downloading as applets or as part of JFC applications. It uses Enhydra's kXML for XML processing. kXML is designed for Micro JAVA (and therefore has a small footprint), but works equally well in J2SE/J2EE environments.
The UDDI Client
Just like the user applet, a UDDI client can be a browser-based application (e.g. JavaScript, Flash, or applet-based client), an independent application (for example, a JFC/AWT-based Java application), or part of the server-side logic. In any of these cases, the client sends an XML message to a UDDI registry, which responds with an XML message. The returned XML messages are UDDI API's. The API I'm working with in this article provides a method called find_business, which searches for a particular business in the registry.
The UDDI client has three tasks:
- Author a UDDI invocation request (step 2).
- Send the authored UDDI invocation request to the UDDI Registry (step 2).
- Process the response from the UDDI Registry to extract meaningful information (step 4).
Tasks (1) and (3) involve simple XML authoring and processing. For task 1, design a Java class that authors XML (the BusinessSpec class in Listing 1). For task 3, another Java class BusinessList (see Listing 2) processes the response from the UDDI registry, from which it extracts information. Task 2 is a transporting task. The usual way of doing this is to let SOAP handle all of the transporting. This will be discussed in more detail laterin this article.
I've created two XML structures. Listing 3 is the XML structure that the UDDI client will authors and sends to the UDDI registry. Listing 4 is the message that the UDDI registry will sends in response. These two XML structures together form one method of the UDDI API called find_business.
UddiAppletGui (Listing 5 is the test container (discussed earlier) that demonstrates the functionality of the other classes. As soon as the applet is initialized, it draws the GUI and is ready to communicate with the server to find the required business information. It displays some text fields for the end user to enter search criteria.
| |
 |
Figure 1. This is the GUI for the find_business method in the applet-based UDDI client.
|
The client-side implementation of the find_Business method is in the form of a reusable Java class called UDDIClient. The UDDIClient (Listing 6 has a method findBusiness() that handles all the UDDI requirements of find_business process.
To invoke the find_business method of UDDI, you need to specify the search criteria. For this, author an API out of XML, like the one in Listing 3 (all API calls in UDDI are XML structures). The API in Listing 1 contains all the information required to run a search for a business. Each element in Listing 3 contains information entered by the user in the applet's GUI.
When the user fills out the fields of the GUI. and presses the Find Business button, the applet runs the ActionEvent method (look at the actionPerformed() method of the UddiAppletGui class in Listing 5). The ActionEvent method creates an instance of the BusinessSpec class, and invokes various Set methods for those text fields that have values present. The BusinessSpec class creates the find_Business XML structure in Listing 3.
Specifying Business Search Criteria
As mentioned above, the findBusiness method in the UDDIClient class takes in a BusinessSpec object and returns a BusinessList object. The BusinessSpec class represents the XML structure that forms the find_Business method call of UDDI's Inquiry API. The BusinessSpec class authors the find_Business XML structure in Listing 1, which completely specifies the business search criteria. The Set methods in the BusinessSpec class set specific XML tags. The ToString() method in this class returns the string representation of the XML markup. All XML authoring is done through kXML, an open source implementation of Document Object Model (DOM).
Use the DOM (Document Object Model) to create the individual nodes in your required XML structure and assemble them into one XML document. The nodes are of type Document, Element, or Attribute. The following list gives details of each element authored. Match the XML elements of the following list with those of Listing 3.
- The Document node doc is the XML document. It holds all child nodes.
- The Element node findBusiness represents the tag named find_Business in the XML structure. Following the start element is an extract from Listing 3. The wax namespace refers to the UDDI API, as specified by xmlns:wax namespace declaration:
<wax:find_business generic="1.0" xmlns:wax="urn:uddi-org:api"_
maxRows="12">
child nodes
</wax:find_business>
- name represents the name of the business tag:
<name>Waxsys</name>
- discoveryURLs represents the discoveryUrls structure:
<discoveryURLs>
<discoveryURL useType="Business entity">_
http://uddi.microsoft.com/inquire</discoveryURL>
</discoveryURLs>
- identifierBag represents the complete IdentifierBag structure:
<identifierBag>
<keyedReference tModelKey="1254" keyValue="ASf" _
keyName="125-PLO" />
<keyedReference tModelKey="96" keyValue="sdf" _
keyName="124-PLG" />
<keyedReference tModelKey="962" keyValue="sdsd" _
keyName="165-RLA" />
</identifierBag>
- tModelBag represents the TModelBag structure:
<tModelBag>
<tModelKey>969-DRW-857-AWF</tModelKey>
<tModelKey>945-AW-984-AHF</tModelKey>
<tModelKey>987-2XW-123-SEWF</tModelKey>
</tModelBag>
- UDDI's Find Qualifiers: UDDI allows its users to specify search preferences. For example, you can make both case-sensitive and case-insensitive searches. It also allows exact match searches and permits you to look for any one specified key. The FindQualifiers structure in Listing 3 is more complex and has several child elements. I designed an inner utility class called FindQualifiers that provides methods to add qualifier tags and then returns the complete XML Element node.
All these nodes are objects of the class Element that provides two utility methods to create a tag in a required format. The first of these methods is a constructor where you provide the name of the tag to be created. The second method is an addChild() method, through which you add child tags.
The BusinessSpec class contains set methods for each of these fields. Each field will be created and populated by calling its proper set method with the required attributes.
For example, have a look at the following method. This setName method takes a string (nameStr), creates a name element, and adds the nameStr string as a text child inside the name element:
// Write business name.
public void setName(String nameStr){
this.name = doc.createElement(Xml.NO_NAMESPACE, "name");
name.addChild(Xml.TEXT, nameStr);
}// end setName()
At this stage, these tags are individual and not yet part of a document. The toString method of the BusinessSpec class is meant to join them together in the Document class and return the complete XML string.
Implementing UDDI's Find Qualifiers
Each of UDDI's Find Qualifiers is a separate findQualifier tag, all of which are bundled together in a findQualifiers parent tag. Here's the complete FindQualifiers structure extracted from Listing 3:
<findQualifiers>
<findQualifier>exactNameMatch</findQualifier>
<findQualifier>caseSensitiveMatch</findQualifier>
<findQualifier>sortByNameAsc</findQualifier>
<findQualifier>sortByNameDsc</findQualifier>
<findQualifier>andAllKeys</findQualifier>
<findQualifier>sortByDateAsc</findQualifier>
<findQualifier>sortByDateDsc</findQualifier>
</findQualifiers>
Listing 1 shows the inner class FindQualifiers containing seven static integer variables, one against each qualifier. This class also has an Element named findQualifier. The AddQualifier() method takes an integer as an argument and adds a new Element to the parent findQualifier. By calling this method with different integer values, you set these qualifiers inside the main findQualifier Element. Each integer value corresponds to a different qualifier. The GetFindQualifiers() method returns the complete constructed and populated FindQualifiers element.
Contacting the UDDI Registry
The find_Business XML structure is passed to the findBusiness() method of the UddiClient class along with a UDDI URL and a port number, which are hard-coded in the sample code. I tested this implementation against IBM's UDDI registry, which is why its address is used as a hard-coded value. Because the UddiClient is reusable, this hard coding is done only at the GUI level.
| |
 |
Figure 2. Here's the sequence of events followed when you invoke UDDI's find_business method.
|
The SoapTransport class (Listing 7) sends the XML structure to the specified URL and receives its response. Internally, this class uses the SoapCall and HttpConnection classes (both in Listing 8). The SetBody() method of SoapTransport sets the given XML inside the SoapCall. The send(,) method of this class sends the complete SOAP message to its destination. The SoapCall class is a small footprint implementation of SOAP. It builds the SOAP ENVELOPE and BODY tags.
The FindBusiness() method of the UDDIClient class handles all functionality required by the corresponding method of UDDI's Inquiry API internally. It hides all the SOAP and HTTP details from the user. The FindBusiness() method returns a BusinessList class object instance (see Listing 2). The returned BusinessList object returned contains all the information that the UDDI registry sends back in response to findBusiness call.
The UDDI Registry Replies
The response from the UDDI registry is the XML structure BusinessList, which contains a list of businesses matching the search criteria. Listing 4 shows a sample BusinessList structure. The BusinessList parses and processes the XML structure returned by UDDI.
The root tag <BusinessList> contains information about the UDDI operator, namespace, and version of the UDDI API. It also contains multiple BusinessInfo elements. Each <BusinessInfo> element represents one business and contains a name, a description, and a BusinessKey. Name is simply name of the business, description is some text describing the business, and BusinessKey uniquely identifies the business. Each BusinessInfo structure contains multiple <ServiceInfo> elements, each of which represent one service that a business provides.
The constructor in the BusinessList class takes the complete BusinessList XML string and populates its internal structures using KXML. Once populated, all the information about a BusinessList class is available through public Get methods. Users of this class can also get information about individual BusinessInfo elements and their children, the ServiceInfo elements.
That completes the implementation of the find_business method. If you want to perform drill-down searching, this sample implementation of the find_business method can be used as an architectural model to implement a complete UDDI client in Java.
UDDI has provided comprehensive means to search for specific Web services at a UDDI registry. Once users have discovered them, they'll want to explore further details of those services. My article "Using UDDI as a Search Engine" covers how to use different methods in UDDI APIs that lead to the discovery of WSDL file URLs, which disclose more information about registered services (see "Designing a WSDL Client").
Bilal Siddiqui is an Electronics Engineer, an XML consultant, and the co-founder of WaxSys, a company focused on simplifying e-Business. He is a technology evangelist and frequently-published technical author. You can contact Bilal at bsiddiqui@waxsys.com.