Skip to main content

Programming with UDDI4J version 2

UDDI4J updated

David Melgar (dmelgar@us.ibm.com), Advisory software engineer, IBM, Software Group
David Melgar has had a diverse career with a background in the retail industry, systems management, Java technology, and Web services. The original author of UDDI4J, David is a member of the Emerging Technologies division of IBM software group, and is currently focusing on Web services security within the Web Services Toolkit. You can contact David at dmelgar@us.ibm.com.

Summary:  As a follow up to Doug Tidwell's "UDDI4J: Matchmaking for Web services," this article discusses the next iteration of the UDDI client API, UDDI4J v2. I have summarized the changes within the UDDI specification for version 2, together with a more detailed discussion of the API changes within the new version of UDDI4J. The new API has been modified and extended to add support for UDDI version 2 as well as a number of changes independent of the new UDDI specification. Several code fragments are provided and discussed to illustrate use of the new API.

Date:  01 Jul 2002
Level:  Introductory
Activity:  856 views

What is UDDI4J?

Web services provide a new paradigm for distributed computing. The promise of invoking Web services dynamically based on descriptions stored in WSDL is very powerful. As Web service users become more sophisticated, the next challenge will be how to find or discover the existence of services that may be of interest. As the Web services invocations become more automated, it is important to have a mechanism to be able to discover Web services in a predictable, repeatable way that can be implemented programmatically.

Universal Description, Discovery and Integration (UDDI) provides such a mechanism. Defined as a Web service itself, UDDI allows businesses and their services to be registered in a UDDI registry. A registered service can include descriptive information such as WSDL and can be categorized in an arbitrary number of ways. Categorization of the Web service allows sophisticated searches to be used to find the most desirable service.

UDDI is defined as a set of XML messages that can be sent and received from a UDDI registry. UDDI4J is a client Java API implementation used to interact with a UDDI registry. UDDI4J objects and methods are used to construct a request message and to send it to a registry. Likewise, UDDI4J interprets response messages from a UDDI registry and presents a set of objects and methods used to access the response message.

UDDI4J version 1 was released to coincide with the original release of the public UDDI Business Registry (UBR). UDDI has continued to evolve, and with it UDDI4J. The UDDI version 2 specification has been available for several months along with beta registries. The public UDDI Business Registry now has support for version 2 of the UDDI specification. UDDI4J version 2 was released as a beta in November 2001 and than released as non-beta in July 2002. This new UDDI4J release adds support for the new features within the specification as well as additional usability and configuration improvements.

UDDI4J was originally released by IBM in January 2001 as an open source project on developerWorks with participation by other companies and individuals encouraged. For version 2, HP joined as a major participant in the evolution of UDDI4J and contributed much of the UDDI version 2 enhancements. With the active support and endorsement of IBM, HP, and SAP, UDDI4J has become the default Java API for UDDI interaction.

As UDDI continues to evolve to meet the needs of the growing Web services community, UDDI4J will continue to track those changes.


UDDI4J basics

UDDI4J is organized into a variety of packages. org.uddi4j.client.UDDIProxy is the primary class used to interact with a UDDI registry. It represents a proxy for the UDDI registry with which communication will take place. UDDIProxy provides methods which map very closely to the API defined within the UDDI specification. Parameters are typically data objects that represent various elements within UDDI.

Many of the API calls return org.uddi4j.response.DispositionReport to indicate the success or failure of the operation. Some calls may throw org.uddi4j.UDDIException to indicate an error condition. Depending on the nature of the error, a UDDIException may contain a DispositionReport with more information about the error.

The UDDI API is divided into an inquiry and publish API. These APIs use separate URLs. The publish URL typically specifies an https address using SSL. When using SSL within Java programming language, a JSSE provider must be defined and added to the set of security managers. The following code fragment enables SSL using the Sun's Java technology JSSE package. The security provider can also be added by modifying the jdk/jre/lib/security/java.security configuration file.

      System.setProperty("java.protocol.handler.pkgs",
                         "com.sun.net.ssl.internal.www.protocol");
      java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

UDDIProxy requires that both an inquiry and publish URL be specified. Once set, all method invocations use these URLs unless the values are modified. When using the publish API, a userid and password is required. These are typically obtained by creating an account through a Web site associated with the chosen registry.

The following code fragment is a typical setup step required for code which uses the publish API.

        // Construct a UDDIProxy object
        UDDIProxy proxy = new UDDIProxy();

        try {
            // Select the desired UDDI server node
            proxy.setInquiryURL("inquiryURL");
            proxy.setPublishURL("publishURL");

            // Pass in userid and password registered at the UDDI site
            AuthToken token = proxy.get_authToken("userid", "password");
            ...
        } catch (UDDIException e) {
        ...



UDDI4J changes

There are a number of significant changes to UDDI4J version 2 that include both support for those in the version 2 specification and enhancements that improve the behavior of UDDI4J but are unrelated to the specification.

  • Support for UDDI version 2 features, including:
    • business relationships
    • service projections
    • enhanced inquiry
    • internationalization features
  • Enhancements unrelated to UDDI version 2:
    • package name change
    • pluggable transports
    • debug logging
    • collection class enhancements

Compatibility

UDDI version 2 has modified some existing message APIs and changed the version identifier on all incoming and outgoing messages. The result is some incompatibility between UDDI version 2 and version 1. UDDI version 2 registries are able to accept both version 1 and version 2 messages. However, version 1 registries are not able to handle version 2 messages.

UDDI4Jv2 generates and handles version 2 messages only, and does not support version 1 messages. UDDI4Jv1 can be used to send and receive version 1 messages. Both UDDI4Jv1 and version UDDI4Jv2 can be used at the same time within the same JVM to allow communication with version 1 or 2 registries. It is not anticipated that many version 1 registries will remain in operation as most will be upgrading to support version 2.

Package name change

As a further commitment to open source, the package name for UDDI4J has been changed from com.ibm.uddi to org.uddi4j. Likewise a new Web site has been defined, http://www.uddi4j.org, to host releases and information about the project. Mailing lists are available for general questions and for participation in the development of UDDI4J.

Samples

An expanded set of samples is provided with UDDI4J version 2. Some of the more mundane setup tasks have been simplified using a configurator class to establish the SSL provider, set the URLs, etc. from information provided in a property file. Information about the current public registry URLs has been removed from the samples given the expanded set of vendors providing registries. A list of the more common registry URLs is available under the 'Links' topic at the http://www.uddi4j.org site.

Configuration enhancements

UDDI4J version 2 adds configuration options which are set using properties. These properties can be specified as system properties or, if needed, they can be set within a properties object and passed to UDDIProxy in a new constructor. If multiple copies of UDDI4J are needed within the same JVM, this new constructor allows a mechanism to configure the environment from a property file and allows each copy of UDDI4J to run with a different configuration. Using system properties is a simpler and more straightforward approach to configuring UDDI4J.

System properties can be set in code or on the command line as follows:

java -DpropertyName=propertyValue

Pluggable transports

UDDI4Jv2 adds support for pluggable transport layers. UDDI4Jv1 required used of Apache SOAP. Additional SOAP implementations have appeared since the first release. An abstraction and factory layer has been created so that multiple SOAP transport providers can be supported. The Apache SOAP project has been superseded by the follow on Apache Axis project. HP, a major contributor to UDDI4Jv2, also provides a SOAP transport. These three SOAP transports are supported by UDDI4Jv2. Apache SOAP remains the default transport. Use of an alternate transport can be specified by setting the following property,

org.uddi4j.TransportClassName=transport_class_name

The specified transport class name can be one of the following included transports or a third party provided SOAP transport.

  • org.uddi4j.transport.ApacheSOAPTransport (the default)
  • org.uddi4j.transport.ApacheAxisTransport
  • org.uddi4j.transport.HPSOAPTransport

Communication errors which originate from the transport result in a org.uddi4j.transport.TransportException being thrown. This exception wrappers a transport specific exception that may contain additional detail.

Debug support

UDDI4J has added the ability to log incoming and outgoing messages. This is very useful when diagnosing communications problems with UDDI registries. Output is enabled by setting the following system property:

org.uddi4j.logEnabled=true

Logging is supported by all of the SOAP transports. The HP SOAP transport has additional properties that can be used to determine the log destination.

Proxy

Proxies are often used to communicate through a firewall to allow communication from a company's intranet to the Internet. Proxies can be HTTP or socks. UDDI4J now supports commonly used Java properties to define HTTP and socks proxy to allow communication through a firewall. The required values are dependent on the company's network configuration and can be obtained from your network administrator. UDDI4J handles passing the basic set of http proxy properties to the underlying transport. Properties supported include:

  • http.proxyHost - The hostname of the proxy server.
  • http.proxyPort - Port used by the proxy server, defaults to 80.
  • https.proxyHost - Hostname of the proxy server if different from the http proxyhost.
  • https.proxyPort - Port used for SSL by the proxy server, defaults to 80.
  • http.proxyUserName - If your proxy server requires authentication, specify the username.
  • http.proxyPassword - Specify the matching password if a proxy username is given.

The following proxy related properties are directly supported by the JDK and included for completeness.

  • socksProxyHost - Hostname of the socks proxy server.
  • socksProxyPort - Portname of the socks proxy server.

Improved usability

Many UDDI4J classes directly map one to one with elements defined in the UDDI schema. In UDDI4J v1, this resulted in several classes that sounded like collection classes but were in fact only containers for real collections. UDDI4J v2 has improved the usability of these classes by adding a set of collection class methods to these classes. More complex classes that contain attributes as well as a collection have not been enhanced with these methods.

The methods that have been added are:

public void add(KeyedReference)
public boolean remove(KeyedReference)
public KeyedReference get(int index)
public int size()

The following classes have been modified to include these new methods:

util.IdentifierBag collection of KeyedReferences
util.CategoryBag collection of KeyedReferences
util.DiscoveryURLs collection of  DiscoveryURL objects
util.FindQualifiers collection of FindQualifier objects
util.TmodelBag collection of Tmodel objects
response.BusinessInfos collection of BusinessInfo objects
response.PublisherAssertions collection of PublisherAssertion objects
response.RelatedBusinessInfos collection of RelatedBusinessInfo objects
response.ServiceInfos collection of ServiceInfo objects
response.TmodelInfos collection of TmodelInfo objects
datatype.binding.BindingTemplates collection of BindingTemplate objects
datatype.binding.TModelInstanceDetails collection of TmodelInstanceInfo objects
datatype.business.Contacts collection of Contact objects
datatype.service.BusinessServices collection of BusinessService objects

A new constructor has also been provided for the KeyedReference class to allow it to be constructed by supplying all its attributes.

public KeyedReference(String keyName, String keyValue, String tModelKey)

The following examples illustrate adding a keyed reference to an identifier bag with and without using the new methods.

Using the old process the following code was required:

      Vector ibVector = new Vector();
      KeyedReference kr1 = new KeyedReference("name", "value");
      kr1.setTModelKey("tmodelKey");
      ibVector.add(kr1);
      IdentifierBag ib = new IdentifierBag();
      // The identifierbag is not really a collection, simply a container for a vector
      ib.setKeyedReferenceVector(ibVector);

With the new collection class methods, this has been simplified to:

      KeyedReference kr1 = new KeyedReference("name", "value", "tmodelKey");
      IdentifierBag ib = new IdentifierBag();
      // New identifierBag method, it now acts like a simple collection class 
      ib.add(kr1);   


UDDI version 2 changes: Business relationships

UDDI version 2 adds modeling support for complex organizations. The concept of business relationships is the largest single change in UDDI version 2 that affects UDDI4J. Large organizations had been using UDDI and encountered issues regarding representation of divisions or portions of their businesses. Typically each division would create their own UDDI business entity, however there was no easy way to establish a relationship to indicate that these various businesses were really part of the same overall business. UDDI version 2 has added an ability to add this relationship. Most of the changes reflected in UDDI4J are related to this capability of expressing relationships between businesses.

Two new UDDI constructs have been added to handle these relationships: publisher assertions and service projections. A publisher assertion is an assertion made by the publisher of a business that a relationship exists between two businesses. A relationship is established between two businesses when each publisher asserts the same relationship. When the UDDI registry receives one assertion, it places the relationship in a pending state. When a matching assertion is received by the publisher of the other business, the business relationship is established. Three relationship types have been defined. A parent-child relationship describes a hierarchical association such as a subsidiary or division. Peer-peer relationships represent an association where neither business is considered the parent. An identity relationship indicates that both business entities represent the same business, similar to creating an alias for the business.

Once two businesses have an established relationship, services that have been defined in one of those businesses can be referenced from the other business. When the other business's service appears within a business, it is known as a service projection. The public UDDI v2 business registry does not currently support service projections. This support will be added at a later date.

Using publisher assertions

UDDI4J closely follows the UDDI specification when implementing the API. The best and only reference required to understand UDDI4J is the UDDI specification itself available from the UDDI organization site (see Resources). Appendix J in the UDDI version 2 specification has a reference on using business relationships.

The following new APIs related to business relationships have been defined within UDDI version 2. These APIs are represented within UDDI4J as new methods on the UDDIProxy class.

RelatedBusinessesList find_relatedBusinesses (FindQualifiers findQualifiers,
                                              String businessKey
                                              KeyedReference keyedReference);	

DispositionReport add_publisherAssertions (String authInfo,
                                           PublisherAssertion publisherAssertion);   
DispositionReport add_publisherAssertions (String authInfo,Vector publisherAssertion);   

DispositionReport delete_publisherAssertions (String authInfo,
                                              PublisherAssertion publisherAssertion);
DispositionReport delete_publisherAssertions (String authInfo,Vector publisherAssertion);
                                     
AssertionStatusReport get_assertionStatusReport (String authInfo,
                                                 CompletionStatus completionStatus);
AssertionStatusReport get_assertionStatusReport (String authInfo,
                                                 String completionStatus);

PublisherAssertions get_publisherAssertions (String authInfo);

PublisherAssertions set_publisherAssertions (String  authInfo,Vector publisherAssertion);
PublisherAssertions set_publisherAssertions (String  authInfo,PublisherAssertion  pub);

The following example illustrates how the first publisher creates a publisher assertion. A keyed reference is created which describes the relationship to be formed. The key value indicates the type of relationship being asserted. Defined value types are peer-peer, parent-child, or identity and are defined in the UDDI data structures specification. When using parent-child, the from key represents the parent business and to key represents the subsidiary. To create a publisher assertion, two publishers are required, each with its own registry userid.

      // Follows example in v2 spec appendix J
      KeyedReference kr = new KeyedReference("Holding Company",               // Key name
                                             "parent-child",                  // Key value
                                             TModel.RELATIONSHIPS_TMODEL_KEY);// Tmodelkey
      PublisherAssertion pa = new PublisherAssertion(bk1,     // from key
                                                     bk2,     // to key
                                                     kr);     // keyed reference
      // Add publisher assertion linking two businesses
      DispositionReport dr = proxy.add_publisherAssertions(token1.getAuthInfoString(),pa);

When one publisher adds an assertion, the registry places the relationship in a pending state, waiting for the affected business to make the identical assertion in response, indicating that both parties agree to the relationship assertion. The second publisher reciprocates by adding the same assertion. Once both parties have asserted the same relationship, the UDDI registry will create the business relationship. In this fragment, a query is performed to find pending assertions affecting this publisher. The business keys from the assertion report are used to recreate the matching original assertion.

      // List available assertions (relationships)
      AssertionStatusReport asr = proxy.get_assertionStatusReport(token2.getAuthInfoString(),
                                                          CompletionStatus.TOKEY_INCOMPLETE);
      Vector v = asr.getAssertionStatusItemVector();
      for (int i = 0; i < v.size(); i++) {
         AssertionStatusItem asi = (AssertionStatusItem)v.elementAt(i);
         PublisherAssertion pa = new PublisherAssertion(asi.getFromKeyString(),
                                                     asi.getToKeyString(),
                                                     asi.getKeyedReference());
         DispositionReport dr = proxy.add_publisherAssertions(pa);
      }

Using service projections

Note that service projections are not supported by the public UDDI Business Registry at the time this article was written. This information is provided for future reference.

In the following fragment, the second publisher creates a service projection. A query is performed on the related (first) business that contains the service to be projected. The BusinessService object is stored, and later used in a save_business() call to add this service to the second business as a projection.

      BusinessDetail bd1 = proxy.get_businessDetail(bk1);
      BusinessEntity be1 = (BusinessEntity)bd1.getBusinessEntityVector().elementAt(0);
      BusinessServices bss1 = be1.getBusinessServices(); 
      BusinessService serviceProjection = bss1.get(0); // Desired service 

      // Update a business and include the service projection 
      BusinessDetail bd2 = proxy.get_businessDetail(bk2);
      BusinessEntity be2 = (BusinessEntity)bd2.getBusinessEntityVector().elementAt(0);
      BusinessServices bs = new BusinessServices();
      bs.add(serviceProjection);
      be2.setBusinessServices(bs);
      Vector entities = new Vector();
      entities.addElement(be2);
      proxy.save_business(token2.getAuthInfoString(),entities);

Services can be examined to determine if they are projections using the following code. In this example, information regarding a business entity is retrieved, including a list of its services. The services can be examined to determine if they are native to that business or belong to the related business. Services which are projected will specify the businesskey of the business they are projected from, rather than the business being queried.

      // How to look at services and see if one is a service projection
      BusinessDetail bd = proxy.get_businessDetail("businessKey");
      BusinessEntity be = (BusinessEntity)bd.getBusinessEntityVector().elementAt(0);
      BusinessServices bss = be.getBusinessServices();
      for (int i = 0; i < bss.size(); i++) {
         BusinessService bs = bss.get(i);
         String businessKey = bs.getBusinessKey();
         if (!businessServiceKey.equals(businessKey)) {
            System.out.println("Service " + bs.getName() + " is a projection");
         }
      }

Internationalization

Several descriptive strings are implemented as objects to allow language specific identifiers. UDDI handles internationalization by allowing the user to specify a collection of these objects where each object has a value and a language identifier. If a single value is provided, the language identifier defaults to a language determined by the registry at the time the publisher account was created, typically English. Language values are those allowed for the xml:lang attribute, specified in RFC 1766.

A common source of confusion is thinking that multiple values are concatenated to allow for a longer string. This is not the case. Each provided object is unique to a language. It is a usage error to specify more than one object with the same (or missing) language identifier. UDDI4J does not validate the values. An error will be generated from the UDDI registry.

New NLS capabilities have been added with the addition of a language identifier to the Name class.

Name(string, language)

The find_business and find_service methods on UDDIProxy now accept a collection of 'Name' objects rather than a single value.

The org.uddi4j.datatype.Description class available since UDDI version 1 has similar behavior and usage.

Enhanced inquiry

Query operations have been consolidated so that a single find_business() call can be used to search based on DiscoveryURLs, IdentifierBag, CategoryBag and TmodelBag without having to cycle through multiple searches.

The new signature for the find_business() method on UDDIProxy is:

BusinessList find_business (FindQualifiers findQualifiers,
                            Vector names,
                            DiscoveryURLs discoveryBag,
                            IdentifierBag identifierBag,
                            CategoryBag categoryBag,
                            TmodelBag  tModelBag
                            Int maxRows);

Additional findQualifiers have also been added as documented in the UDDI v2 specification.

Conclusion

This article has summarized the changes that have gone into UDDI4J version 2, package name and samples changes, ability to specify a SOAP transport, support for debug logging, including enhanced usability, support for UDDI version 2, configuration capabilities including choosing which SOAP transport to use, debug logging, proxy, usability enhancements, and of course, support for UDDI version 2. The UDDI version 2 concepts of business relationships and service have been discussed and code fragments presented. Given this information, you are now armed with information to be able to use UDDI4J to further explore UDDI version 2.

More detailed information on the changes between version 1 and version 2 can be obtained by consulting the UDDI version 2 specification and follow on errata. Latest news and releases related to UDDI4J can be found on uddi4j.org


Resources

About the author

David Melgar has had a diverse career with a background in the retail industry, systems management, Java technology, and Web services. The original author of UDDI4J, David is a member of the Emerging Technologies division of IBM software group, and is currently focusing on Web services security within the Web Services Toolkit. You can contact David at dmelgar@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=11687
ArticleTitle=Programming with UDDI4J version 2
publish-date=07012002
author1-email=dmelgar@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers