Main Page

Previous Section Next Section

UDDI4J

UDDI4J is a Java client API used to access a UDDI registry. UDDI4J objects and methods are used to build a request message in SOAP format that is sent to the registry. UDDI4J was originally developed by IBM as an open source undertaking and has the endorsement of HP, SAP, and others.

UDDI4J contains APIs that allows you to publish, find, and bind to a Web service. Because UDDI4J is open source, it comes with source code, JavaDoc, and several sample applications. It contains multiple APIs but the one most frequently used is the UDDIProxy class. Let us look at how UDDIProxy class interacts with a registry:

UDDIProxy proxy = new UDDIProxy();

proxy.setInquiryURL("http://www.flutebank.com/uddi/test/inquiryapi");

proxy.setPublishURL("https://www.flutebank.com/uddi/test/publishapi");

We start by creating an instance of the UDDIProxy class and then set the proxy to point to Flute Bank's test UDDI registry. The inquiry API is set to use HTTP protocol, because we want the inquiry to be publicly accessible. The publish URL uses HTTPS, because we want to make sure only users that are authorized can submit changes to the registry.

The publish URL can use protocols other than SSL for publication as long as it is supported by a valid Java security provider (JSSE). As you may be aware, security providers are configured in the java.security configuration file or, alternatively, can be done at runtime. The code for changing providers is simple:

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());

The proxy class is responsible for connecting to the UDDI registry on the user's behalf and transmits the appropriate SOAP messages. The proxy class uses the underlying transport to communicate through firewalls or network bastion hosts (Network Proxy Servers). In some organizations, to communicate from inside your organization to the outside may require using an ID and password. UDDI4J supports this by supporting the system properties shown in Table 6.2.

Table 6.2: System Properties Supported by UDDI4J

Property

Description

http.proxyHost

The hostname of the network proxy server.

http.proxyPort

The port number used by the network proxy server. This defaults to port 80.

https.proxyHost

he hostname of the network proxy server that supports SSL. This is usually the same server as HTTP.

https.proxyPort

The port number used by the network proxy server for SSL. This defaults to port 443.

socksProxy.Host

The hostname of the network proxy server that supports Socks-based proxies.

socksProxy.Port

The port number used by the network proxy server.

The ultimate goal of UDDI4J is to allow discovery of businessEntities and the services they offer. UDDI4J provides several additional classes that allow you to access entity and service information from a UDDI registry. These include a BusinessInfo object that describes an individual businessEntity, a BusinessList object, which is a collection of BusinessInfo objects returned from search results, and a ServiceInfo object, which allows you to access the services offered from a particular businessEntity.

A user who wanted to find all businesses that meet a specified criterion, such as companies that start with the name "Flute," would use the find_business method of the proxy similar to this:

BusinessList bl = proxy.find_business("Flute", null, 0);

The find_business method has three parameters. The first contains the search string, the second points to an instance of a FindQualifiers object, for which we are specifying null, and the third is the number of matches to return. Zero specifies that we should return all matches. For advanced searching, you can use the FindQualifiers object to include searching on business categories, identifiers, and tModels. The BusinessList object is a collection that contains all businesses that match the search criteria.

Usually when you have a, you will want to extract information for each business. Let us look at a simple code snippet that does the job:

Vector biVector = bl.getBusinessInfos().getBusinessInfoVector();

for (int ii = 0; ii < biVector.size(); ii++) {

    BusinessInfo bi = (BusinessInfo)biVector.elementAt(ii);
}

Using UDDI4J to publish business entities to the registry is also straightforward. Publication to a UDDI registry requires authentication using SSL, so the proxy also provides a get_authToken method to handle this task. Publishing a businessEntity requires creating a new BusinessEntity object and supplying it with the various properties you want published. Let us look at a simple example that specifies the name of the business and the operator:

AuthToken token = proxy.get_authToken("uid"," pass");

Vector entityVector = new Vector();
BusinessEntity be = new BusinessEntity("");

be.setName("Flute Bank");
be.setOperator("Administrator");

entityVector.addElement(be);
BusinessDetail bd = proxy.save_business(token.getAuthInfoString(), entityVector);

It is a good idea to check whether the registration was successful. You can query the registry a second time and compare BusinessDetail information. Alternatively, the majority of the proxy methods upon failure may throw UDDIException for severe errors or return an instance of a DispositionReport that indicates success or failure of an operation.

Earlier in the chapter, we mentioned that Flute Bank wanted to create multiple registrations for its insurance, banking, and investment divisions. After registering each division as a businessEntity, we will need to create a publisher assertion, which is a type of keyedReference that describes the relationship between two businessEntities. Let us look at sample code used to demonstrate how this can be accomplished programmatically:

// Specify which keyed reference to use
KeyedReference kr = new KeyedReference("Division", "parent-child",
                                                     TModel.RELATIONSHIPS_TMODEL_KEY);
// Create a new publisher assertion
PublisherAssertion pa = new PublisherAssertion(parentKey, childKey, kr);

// Link together both entities to create an assertion
DispositionReport dr = proxy.add_publisherAssertions(token.getAuthInfoString(), pa);

Remember that when an assertion is added, the business entity relationship is not valid until both parties make an identical assertion that specifies they mutually agree to the relationship. The example shows only one assertion being made. Sometimes you may also want to know programmatically assertions made by other parties. In the case of Flute Bank, we want to automatically approve all assertions made against it. This can be done using this code snippet:

// Determine incomplete relationship where other parties have created an assertion
AssertionStatusReport asr = proxy.get_assertionStatusReport(token.getAuthInfoString(),
                                                   CompletionStatus.TOKEY_INCOMPLETE);
// We need a list of partially formed relationships
Vector v = asr.getAssertionStatusItemVector();

for (int ii = 0; ii < v.size(); ii++) {
    AssertionStatusItem asi = (AssertionStatusItem)v.elementAt(ii);

    // Create a matching publisher assertion
    PublisherAssertion pa = new PublisherAssertion(asi.getFromKeyString(),
                                       asi.getToKeyString(), asi.getKeyedReference());

    // Check the disposition for errors
    DispositionReport dr = proxy.add_publisherAssertions(pa);

}

In prior examples, we published information programmatically for Flute Bank. Likewise, there may be situations in which we may wish to programmatically delete information in a registry. This may require using qualifiers, as we of course want to delete specific records and do not want to use wildcard operations. An example of the qualifier we may want to use is

FindQualifiers findQualifiers = new FindQualifiers();
Vector qualifier = new Vector();
qualifier.add(new FindQualifier("exactNameMatch"));
findQualifiers.setFindQualifierVector(qualifier);

This qualifier specifies that we want to use an exact name match. Previously, we searched for all entities that start with the word "Flute." This allows us to be more specific. Flute Bank wishes to programmatically delete the businessEntity for its Biche branch and will use the code in Listing 6.15:

Listing 6.15: Creating a new business assertion
Start example
// Create a vector of names
Vector names = new Vector();
names.add(new Name("Flute Bank Biche")));

// Let's make search case sensitive
FindQualifiers findQualifiers = new FindQualifiers
Vector qualifier = new Vector();
qualifier.add(new FindQualifier("caseSensitiveMatch"));
findQualifiers.setFindQualifierVector(qualifier);

// Search for specified business and limit result to 10
BusinessList businessList = proxy.find_business(names, null, null, null, null,
                                                                  findQualifiers, 10);
Vector businessInfoVector = businessList.getBusinessInfos().getBusinessInfoVector();

// Delete any businesses returned from the search
for (int ii = 0; ii < businessInfoVector.size(); ii++) {
  BusinessInfo bi = (BusinessInfo)businessInfoVector.elementAt(ii);
  DispositionReport dr = proxy.delete_business(token.getAuthInfoString(),
                                                                 bi.getBusinessKey());
  if (dr.success()) {
     System.out.println("Business Deleted");
  } else
       System.out.println("Error Number: "+ dr.getErrno() +
          "\n Error Code: "+ dr.getErrCode() +
          "\n Error Text: "+ dr.getErrInfoText());
  }
}

End example

Now let us look at one more example of using UDDI4J to find a business. In the Listing 6.16, we will use UDDI4J to locate multilingual businesses. UDDI4J supports passing the preferred language identifier as a parameter.

Listing 6.16: Creating a new publisher assertion
Start example
Vector descriptionVector = businessInfo.getDescriptionVector();
String businessDescription = "";
String defaultDescription = "";

for (int ii = 0; ii < descriptionVector.size(); ii++) {
  Description description = (Description)descriptionVector.elementAt(ii);

  if (description.getLang().compareToIgnoreCase("en-zh") == 0) {
     businessDescription = description.getText();
     break;
  }

  // More than likely a business will have an English description.
  // Use this as default

  if (description.getLang().compareToIgnoreCase("en-us") == 0) {
     defaultDescription = description.getText();
  }

  // If none in Chinese, then use default
  if (businessDescription == "") {
     businessDescription = defaultDescription;
  }

  // Convert to appropriate character set
  businessDescription = new String(businessDescription.getBytes("ISO-8859-1")," UTF-8);
End example

UDDI4J has additional features that may prove useful. The initial version used Apache SOAP for its transport layer. Transport layers are handled via an abstract factory approach that will allow other SOAP transport providers to be used. Configuration of the transport is specified by changing a system property.

org.uddi4j.TransportClassName=org.uddi4j.transport.ApacheAxisTransport

The UDDI4J is one manner for querying a registry. The Java API for XML registries (JAXR) is another and will be covered in its own chapter.


Previous Section Next Section


JavaScript Editor Java Tutorials Free JavaScript Editor