UDDI4J lets Java do the walking

Access any UDDI registry from within Java using the UDDI4J API

Web services technology allows the communication between applications across the Internet over standard, XML-based protocols. The Simple Object Access Protocol (SOAP) invokes a Web service, which can be located anywhere on the Internet and written in any programming language. A Web service's interface is described using the Web Services Definition Language (WSDL). Public registries exist where a service provider can publish services and service requestors can find them. Such registries follow the Universal Description, Discovery, and Integration (UDDI) standard.

The standard defines an XML-based API with which clients access the registry. The open source UDDI4J project defines a Java API that provides access to any UDDI registry from within a Java application. UDDI4J lets you publish and find information in a UDDI registry by wrapping all the XML artifacts used by UDDI. It also handles the network access to a registry via the SOAP protocol, making it easy to integrate UDDI access into any new or existing Java application.

In this article, I introduce UDDI in general, then move on to the UDDI4J API, including some programming examples demonstrating its use. I will not cover the Web services architecture in any detail, nor will I explain the SOAP or WSDL specifications. Please see Resources for links to further articles and tutorials on these topics.

UDDI

UDDI defines a set of registries that contain information about businesses and the services they offer. Moreover, it defines a set of specifications: one specification for an XML schema that defines the structure of the contained data, one specification for a common API to access this data, and one API for the replication of data between different registries. A community of over 220 companies now back UDDI, each working together to define and support the comprising specifications.

Currently, two production UDDI registries exist: one hosted by IBM and one by Microsoft. Hewlett-Packard's registry should launch later this summer. (See Resources for links to all three registeries.) Since they replicate information between each other, any one provides all available information.

UDDI data structure

A UDDI registry contains data in a combination of white pages, yellow pages, and green pages. The white pages information includes items such as a business's name, its address, and other contact information. The yellow pages help categorize a business; they define its business type, as well as the industry in which it operates. Lastly, the green pages define what kinds of services a business offers, and how to electronically communicate with these services.

All UDDI registry data is formatted in XML. As such, the data structure specification defines the XML schemas all entries must follow. Some of the more generic defined elements can exist at various places of the registry:

  • TModel: A generic information container that typically points to a technical specification, thus making it possible to use TModels as technical fingerprints to identify certain services. Each TModel possesses a unique key. A number of entries in the UDDI registry use TModel, but most notably they are contained in a binding template, described below.
  • Identifier Bag: A number of named key-value pairs. Many of the elements in a UDDI registry can contain identifiers to help classify the given information. On top of that, each identifier includes a reference to a TModel, which indicates the key type contained in the identifier.
  • Category Bag: Contains a number of categories that resemble identifiers but have predefined taxonomies. For example, you'll find a category for industry codes as defined by the North American Industry Classification System (NAICS).

These elements help find businesses based on their industry classification, or based on certain technical specifications (TModels, for example) they support.

The other elements defined in the UDDI specification describe the actual businesses and their offered services:

  • Business Entity: Contains general information about a business, such as its contact information and business type categorization data. The entry also contains a number of business service entries.
  • Business Service: Represents the service a business offers. It contains a description, as well as an access-point element that defines where the service is located. Each business service entry contains a number of binding templates.
  • Binding Templates: Contains a reference to one or more TModels, which helps classifying the offered service.

Figure 1 shows the elements contained in a UDDI registry and their relationships. Please note the missing entry: the publisherAssertion, an element added to UDDI version 2.0, which no production registry yet supports. publisherAssertion helps define relationships between different business entity entries. As it's not supported, we will not look at it in any detail.

Figure 1. A UDDI registry

The UDDI API

The UDDI API specification defines itself as a collection of XML requests and their responses -- making the API completely programming-language neutral. There are two types of APIs: find methods and publish methods. Obviously, the find methods find certain entries in the registry; they do not make any updates.

You can call finder methods to retrieve any kind of entry contained in the registry. Finders exist for business entities, business services, or even individual TModels. The criteria passed with a find method can be a specific key -- to find all the services offered by a particular business, for example. Or it can be category or TModel information, for example to find all businesses that offer services associated with a particular specification identified by its TModel.

With the publish methods, you create new entries, change existing entries, and delete entries. Again, you can change business entities, business service entries, and also to TModels. All publish APIs require userid/password credentials to be passed with every request.

These methods' parameters and return values reflect the defined UDDI data structures closely. Since the API, as defined, is a collection of XML messages, some of these messages simply contain the exact structure of the element they represent.

UDDI for Java (UDDI4J)

A typical UDDI API implementation uses SOAP under the covers to access a UDDI registry. Each registry provides SOAP access points. One example for such an implementation: UDDI for Java (UDDI4J). The open source UDDI4J project provides a Java implementation of the UDDI API specification. You can use it to access all registries following the specification. (See Resources to access the latest version of the UDDI4J implementation, which, at the time of this writing, is 1.0.3.)

At its core, UDDI4J maps the data structures defined in UDDI into Java objects. For example, the business entity data structure has the following XML schema definition:

<element name="businessEntity">
   <type content="elementOnly">
      <group order="seq">
         <element ref="discoveryURLs" minOccurs="0" maxOccurs="1"/>
         <element ref="name"/>
         <element ref="description" minOccurs="0" maxOccurs="*"/>
         <element ref="contacts" minOccurs="0" maxOccurs="1"/>
         <element ref="businessServices" minOccurs="0" maxOccurs="1"/>
         <element ref="identifierBag" minOccurs="0" maxOccurs="1"/>
         <element ref="categoryBag" minOccurs="0" maxOccurs="1"/>
      </group>
      <attribute name="businessKey" minOccurs="1" type="string"/>
      <attribute name="operator" type="string"/>
      <attribute name="authorizedName" type="string"/>
   </type>
</element>

Without delving into too much detail, you can see that a business entity element contains a number of other elements (discoveryURLs, name, description, and so on), as well as three attributes: businessKey, operator, and authorizedName.

Now let's look at the respective Java class defined in UDDI4J -- com.ibm.uddi.datatype.business.BusinessEntity. We won't list the entire source here, just the significant pieces:

public class BusinessEntity extends UDDIElement {
   public static final String UDDI_TAG = "businessEntity";
   protected Element base = null;
   String businessKey = null;
   String operator = null;
   String authorizedName = null;
   DiscoveryURLs discoveryURLs = null;
   Name name = null;
   Contacts contacts = null;
   BusinessServices businessServices = null;
   IdentifierBag identifierBag = null;
   CategoryBag categoryBag = null;
   // Vector of Description objects
   Vector description = new Vector();
   ...
}

The remainder of the class consists of get and set methods for the class's attributes. You can tell that elements and attributes of the XML definition for business entity are treated the same way in the Java class.

You will find a similar class for all structures defined in the UDDI specification. Not only are the data structures mapped in this way, there are also classes for all request and response structures defined in the UDDI API specification. However, a typical client will not use those classes to access a UDDI registry -- com.ibm.uddi.client.UDDIProxy class performs that task.

The UDDIProxy class

To access a UDDI registry, a client program employs the UDDIProxy class. Not only does it wrap the find and publish methods defined in the UDDI specification, UDDIProxy also handles the network access to the actual UDDI registry server. UDDI registries provide a SOAP access point for clients to use. The UDDIProxy class uses the Apache SOAP implementation to send and receive messages to and from the registry. You merely specify to the class the registry's URL and use any method defined on it, plus the type of network protocol you want to use (HTTP in most cases).

Thus, the call to construct an UDDIProxy instance looks like:

UDDIProxy up = new UDDIProxy(
      new URL("http://www.ibm.com/services/uddi/inquiryapi"),
      new URL("https://www.ibm.com/services/uddi/protect/publishapi"),
      new org.apache.soap.transport.http.SOAPHTTPConnection());

In this example, the proxy is set up to talk to the IBM UDDI registry. Note that each UDDI registry provides a test area you can use for testing purposes. Note also that the URL for publishing uses HTTPS for the communication, since it makes changes to the registry. You will see later that you need to provide a valid userid/password combination for making changes. The last parameter indicates that we want to use HTTP as the network protocol to talk to the registry. You can download the Apache SOAP implementation that includes this class at http://xml.apache.org/soap.

Use the find methods

Next, to find existing business entries and their services, turn to the UDDIProxy class. I mentioned earlier that the hierarchy of entries in a UDDI registry starts with business entities, which contain business services with binding templates and so forth. To browse a registry, you therefore start with the appropriate find method for a business entity, called find_business(). The following code extract shows how you can list all businesses whose name starts with "J" (assuming you have created an instance of UDDIProxy called "up" like shown above):

BusinessList bl = up.find_business("J", null, 0);
Vector businessInfos = bl.getBusinessInfos().getBusinessInfoVector();
Enumeration enum = businessInfos.elements();
while (enum.hasMoreElements()) {
   BusinessInfo bi = (BusinessInfo)enum.nextElement();
   System.out.println("found a business : "+bi.getNameString());
}

Once you have the BusinessInfo object, you can retrieve the supported services by using the getServiceInfos() method and so forth. The ListServices.java file shows an example for how to drill down the hierarchy of entries in the registry. The sample code uses the IBM test registry, but you can access any other registry, too. It expects one input parameter as the search criteria for the find_business() method.

Use the publish methods

Now that you have seen how to find entries in a registry, let us look at how to create new entries there -- the publish methods' job. As above, you'll employ the UDDIProxy class.

However, before you can create your own entries, please note that both the IBM and the Microsoft registry make publishing available only via an HTTPS connection. A standard JVM cannot create such a connection, so you'll have to make other arrangements. "Java Tip 96: Use HTTPS in Your Java Client Code" explains how to do so. Please also note: to make changes, you must register with those sites. The simple registration for the test areas gives you a valid userid and password combination.

Let us assume you have a business, called John's Balance Business that offers accounting services. You want to create a UDDI entry for your business. With the business entity, you want to associate a category bag that shows your business as an accounting business. The following code creates a UDDIProxy instance, the required authentication object, and a category bag:

   UDDIProxy up = new UDDIProxy(
      new URL(
"http://www-3.ibm.com/services/uddi/testregistry/inquiryapi"),
      new URL(
"https://www-3.ibm.com/services/uddi/testregistry/protect/publishapi"),
      new org.apache.soap.transport.http.SOAPHTTPConnection());
   AuthToken at = up.get_authToken("myuserid", "mypassword");
   String ais = at.getAuthInfoString();
   KeyedReference kr = 
      new KeyedReference("Other Accounting Services", "541219");
   // The following UUID references the NAICS TModel key
   kr.setTModelKey("UUID:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2");
   Vector krVector = new Vector();
   krVector.addElement(kr);
   CategoryBag cb = new CategoryBag();
   cb.setKeyedReferenceVector(krVector);

To finish, you create the new business entity, add the category bag to it, and save it in the registry:

BusinessEntity be = new BusinessEntity();
be.setName(new Name("John's Balance Business"));
be.setDefaultDescriptionString("A business doing balance stuff.");
be.setCategoryBag(cb);
Vector beVector = new Vector();
beVector.addElement(be);
try {
   up.save_business(ais, beVector);
   System.out.println("Business saved.");
} catch (UDDIException x) {
   System.out.println("Caught exception : "+x.getFaultString());
}

You can find a complete sample in the PublishServices.java file contained in jw-0824-uddi.zip. There you'll also find the DeleteServices.java file that shows how to delete your newly created entry.

You may have noted that the samples shown do not address where to store an actual WSDL document. In fact, the UDDI specifications operate completely independent of WSDL or SOAP. The issue of where and how to store a WSDL document in a UDDI registry is beyond the scope of this article. You can find a link to a whitepaper explaining this in Resources.

Show developers UDDI4J, and you've shown them the world!

In this article you learned how you can use the UDDI4J API to access information stored in a UDDI registry, thus allowing access to information about businesses and their Web services from within any Java application. UDDI4J users can skip the specifics of the network access to a registry, as well as the details of the XML documents stored there. You also learned about the basic structure of the content stored in a registry, and how the UDDI4J maps this content into the Java language.

You can now use this knowledge and start developing your own applications that integrate UDDI information. The sample source code that comes with this article can serve as a starting point. For publishing, use one of the available test registries at first. Consider the following usage scenario: you have integrated a particular Web service into your application. You could add functionality to automatically refresh the cached information about the location of that Web service in case it becomes unavailable. With UDDI4J, this should be a relatively easy task. Enjoy!

André Tost works as a solution architect for IBM's Software Group in Rochester, MN. He holds a degree in electrical engineering from Berufsakademie Stuttgart, Germany, and has been working on various object-oriented development projects over the last seven years.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more