Before you start writing the code for publish applications, you need to understand two basic requirements for this type of application. First, the publish applications must read and understand the contents of a WSDL document. Second, they must send requests to a UDDI registry and then process any responses. Fortunately, there are two existing Java class libraries that provide this functionality: the Web Services Description Language for Java (WSDL4J) and the UDDI Java API (UDDI4J).
WSDL4J provides a standard Java interface which can be used to parse existing WSDL documents or to programmatically create new WSDL documents. WSDL4J is an open source project located on the IBM developerWorks site (see Resources) whose purpose is to provide a reference implementation for Java Specification Request 110 (JSR 110): Java APIs for WSDL (please also see Resources for more on this). This JSR is being developed through the Java Community process.
The programming examples in this article use WSDL4J V0.8. Most of the
WSDL4J classes represent the elements that can appear in a WSDL document.
For example, the <definition> element is
represented by the Definition class, and the <service> element is represented by the Service
class. There are also utility classes that make it easy to read and parse
a WSDL document, as well as write out the contents of the WSDL4J objects
as an XML document.
UDDI4J provides a Java client-side interface that can be used to publish and find service descriptions in any UDDI registry. This too is an open source project hosted on the IBM developerWorks site (again, see Resources for a link).
For the publish applications, I will be using UDDI4J V1.03. This
version provides a complete implementation of the UDDI V1 application
programming interface. The UDDI4J classes include a complete
representation of the UDDI data entities. For example, a TModel class
represents a UDDI tModel and a BusinessService
class represents a businessService. UDDI4J also
includes a UDDI registry proxy class. This class is used to send publish and find requests
to a UDDI registry.
Publishing a WSDL service interface as a UDDI tModel
I'll start off by developing the code that will be used to publish a WSDL service interface description as a UDDI tModel. In the first part of this series, I reviewed the steps that were required to properly publish a WSDL service interface definition. I will go through these steps as the requirements for developing the publish application. Here is a brief summary of these steps:
- Set the
tModelname from thetargetNamespacefor the WSDL document. - If there is a documentation element within the description element, then use it to create a
tModeldescription. - Put the network-accessible location for the WSDL service interface document in an overviewDoc.
- Add at least one
keyedReferencethat indicates that thetModelcontains a reference to a WSDL service description.
The code associated with each of these steps is described in detail below. You can also view and download the complete PublishServiceInterface application (see Resources for a link).
Step 1: Create the tModel and set the name from the targetNamespace
Before processing this step, you need to read and parse the WSDL
document. You do this using the WSDLReader class in WSDL4J. After reading
the WSDL document, you create a new tModel
object and set its name from the targetNamespace in the WSDL document.
Listing 1: First read and parse the WSDL document
// Read WSDL service interface document Definition def = WSDLReader.readWSDL(null, wsdlURL); ... // Create tModel from WSDL service interface TModel tModel = new TModel(); // [STEP 1: tModel} Set the businessService name from targetNamespace tModel.setName(def.getTargetNamespace()); |
Step 2: Set the tModel description from the WSDL documentation element
Setting the tModel description is optional.
If the documentation element is specified within a definition element,
then it can be used to set the tModel
description.
Listing 2: Setting a tModel description
// Get documentation element Element element = def.getDocumentationElement(); // [STEP 2: tModel] Set default tModel description String desc = DOMUtils.getChildCharacterData(element); tModel.setDefaultDescriptionString(desc); |
Step 3: Create the overviewDoc for the tModel
The overviewDoc will contain the network accessible location for the WSDL service interface document. In this code segment, the overviewURL is set to the location of the WSDL document.
Listing 3: Setting the overviewURL
// Create overview doc OverviewDoc overviewDoc = new OverviewDoc(); // Create overview URL OverviewURL overviewURL = new OverviewURL(wsdlURL); // Set overviewURL overviewDoc.setOverviewURL(overviewURL); // [STEP 3: tModel] Set the overviewDoc tModel.setOverviewDoc(overviewDoc); |
Step 4: Categorize the tModel as a WSDL service description
Since a tModel can reference a service
description that can be specified in any markup language, it is important
to indicate that this tModel represents a WSDL
service description. Adding one additional entry in the tModel's categoryBag will do this. In this sample
code, there are two keyedReferences. One
indicates the type of service description, and the other one indicates the
business purpose of a service that implements this service interface.
Listing 4: Editing the tModel's categoryBag
// Create a categoryBag and get the CategoryBag
categoryBag = new CategoryBag();
// Create a keyedReference for wsdlSpec
KeyedReference kr = new KeyedReference("uddi-org:types", "wsdlSpec");
kr.setTModelKey("UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4");
krList.add(kr);
// Create a keyedReference for the category of service
Vector krList = new Vector();
kr = new KeyedReference("Stock market trading services", "84121801");
kr.setTModelKey("UUID:DB77450D-9FA8-45D4-A7BC-04411D14E384");
krList.add(kr);
// Set keyed reference vector
categoryBag.setKeyedReferenceVector(krList);
// [STEP 4: tModel] Set the category bag
tModel.setCategoryBag(categoryBag);
|
Publishing a WSDL service implementation as a UDDI businessService
The second application will publish a WSDL service implementation
description in a UDDI registry as a businessService. To do this, you must create both a
businessService and a bindingTemplate. The steps listed below are based on
the process that was defined in the first part of this series. These
steps show how to create both a businessService
and a bindingTemplate, and will be used as the
basis for building your publish application. The code associated
with each of these steps has been extracted from the complete PublishServiceImplementation application.
I will review the steps for creating a businessService first. Here is a summary of these
steps:
- Set the
businessServicename from the name of the service element. - If it is specified, use the contents of the documentation element to create a description for the
businessService.
Step 1: Create the businessService and set the name from the service name
Start by reading and parsing the contents of the WSDL document. You
do this using the WSDLReader class in WSDL4J. After reading the WSDL
document, you can create a new businessService
object and set its name from the service name in the WSDL document.
Listing 5: Creating and naming a new businessService object
// Read WSDL service implementation document Definition wsdlDefinition = WSDLReader.readWSDL(null, wsdlURL); // Get the first service element only Service wsdlService = ((Service[]) wsdlDefinition.getServices().values().toArray(new Service[0]))[0]; ... // Create businessService from WSDL service interface BusinessService businessService = new BusinessService(); ... // [STEP 1: businessService] Set the businessService name from service name businessService.setName(wsdlService.getQName().getLocalPart()); |
Step 2: Set the businessService description from the WSDL documentation element
The WSDL documentation element within the service element is used to
set the default description for the businessService:
Listing 6: Setting the default businessService description
// Get documentation element element = wsdlService.getDocumentationElement(); // [STEP 2: businessService] Set default businessService description businessService.setDefaultDescriptionString(DOMUtils.getChildCharacterData(element)); |
Now that you have created a businessService,
you can create the bindingTemplate. Here is a
summary of the four steps for creating the bindingTemplate:
- If the port element contains a documentation element, then use its contents to create a description for a
bindingTemplate. - Use the location within the port element to set the
accessPoint. - Add a
tModelInstanceInfoto thebindingTemplate. This element contains thetModelKey. - Create an overviewDoc element that contains a reference to the WSDL service implementation document.
Step 1: Create the bindingTemplate and set the description from the WSDL documentation element
Create a new bindingTemplate object, and
then set its default description from the WSDL documentation element that
was within the port element.
Listing 7: Create and set a bindingTemplate object
// Create a bindingTemplate BindingTemplate bindingTemplate = new BindingTemplate(); // Get the first port element Port wsdlPort = ((Port[]) wsdlService.getPorts().values().toArray(new Port[0]))[0]; // Get documentation element element = wsdlPort.getDocumentationElement(); // [STEP 1: bindingTemplate] Set default bindingTemplate description bindingTemplate.setDefaultDescriptionString(DOMUtils.getChildCharacterData(element)); |
Step 2: Set the access point within the bindingTemplate
The access point is set from the extensibility element that is within the port element. For this sample code, I assumed that the SOAP binding was used and that the access point uses an HTTP protocol.
Listing 8: Setting the bindingTemplate access point
// Get first extensibility elementExtensibility Element ext = (ExtensibilityElement) wsdlPort.getExtensibilityElements().get(0); // Create access point (assume that it is always SOAP binding and HTTP protocol) AccessPoint accessPoint = new AccessPoint(((SOAPAddress)ext).getLocationURI(), "http"); // [STEP 2: bindingTemplate] Set the access point bindingTemplate.setAccessPoint(accessPoint); |
Step 3: Create a tModelInstanceInfo which will reference the service interface
The bindingTemplate must contain a
reference to the tModel that is associated with
the service interface definition. This is done by creating a tModelInstanceInfo which contains the tModelKey for this tModel.
Listing 9
// [STEP 3: bindingTemplate] Create tModelInstanceInfo using the tModelKey tModelInstanceInfo = new TModelInstanceInfo(tModelKey); |
Step 4: Create the overviewDoc in the instanceDetails
This step is similar to that for the service interface document, except that the overviewDoc will contain the location of the WSDL service implementation document.
Listing 10
// Create overview URLOverviewURL overviewURL = new OverviewURL(wsdlURL); // Set overviewURL overviewDoc.setOverviewURL(overviewURL); // [STEP 4: bindingTemplate] Set the overview doc instanceDetails.setOverviewDoc(overviewDoc); |
Using the publish applications
The publish applications that you developed can be used to publish WSDL service interfaces and WSDL service implementations. You can use the following WSDL service descriptions, which are listed in the Resources section, to test these applications:
- SQS-interface.wsdl -- WSDL service implementation description for a stock quote service
- SQS.wsdl -- WSDL service interface description for a stock quote service
These service descriptions appeared in the first article in this series. To use them, you should put them in a location where they are accessible through a Web server. Also, you must update the location attribute on the import element in the WSDL service implementation document. This attribute must contain the network accessible location for the WSDL service interface document. An example of the value for the location attribute would be http://localhost:8080/wsdl/SQS-interface.wsdl.
Selecting a UDDI registry to use
To run the publish applications, you also need to select a UDDI registry to use. This section describes the different types of UDDI registries, and shows how to use the class to access them.
There are two types of UDDI registries that you can use to run the publish applications in this article: the UDDI test registries available on the Internet, or a private UDDI registry -- which can (but needn't) be run on your own system. When running test code, you should never use one of the public UDDI registries: the public UDDI registries can be effective only if they contain reliable data; publishing test data to these registries will diminish the reliability of their data.
After you have selected a UDDI registry to use, you must register yourself with that UDDI registry. When you register, you will specify a userid and password, which you will need to publish data to the registry.
There are two public UDDI test registries. IBM hosts one and the
other one is provided by Microsoft. Each registry has two interfaces.
The inquire interface is used to find
information in the registry, and the publish
interface is used to publish and unpublish data in the registry. The two
test registries are accessible at the following locations:
IBM Test Registry
- Inquire: http://www-3.ibm.com/services/uddi/testregistry/inquiryapi
- Publish: https://www-3.ibm.com/services/uddi/testregistry/protect/publishapi
An example of a private UDDI registry is the IBM WebSphere UDDI Registry Preview (see Resources for a link). A private UDDI registry must be installed on one of your own systems. After a private registry is installed on your local system, it should be accessible using the following set of URLs:
- Inquiry:
http://localhost:80/services/uddi/inquiryapi - Publish:
http://localhost:80/services/uddi/publishapi
In UDDI4J, the UDDIProxy class provides the interface to a UDDI registry. Each
of the publish applications contains a get
method. This method does two things. First, the UDDI proxy is created
using the inquiry URL and publish URL. Second, it adds the support that is
needed to use SSL (all publish messages are sent to the UDDI test
registries using an SSL connection. Both of the publish
applications in this article use IBM's SSL support, but other
implementations can be used by changing the protocol handler and the
security provider.)
Listing 11: Create the UDDI proxy for a UDDI registry
/**
* Create the UDDI proxy for a UDDI registry.
* @param inquiryURL the inquiry URL for the UDDI registry
* @param publishURL the publish URL for the UDDI registry
* @return Returns the UDDI proxy of the IBM test registry.
*/
public static UDDIProxy get(String inquiryURL, String publishURL)
throws Exception
{
UDDIProxy uddiProxy = null;
// Add SSL support (this is IBM's SSL support
// but it can be replaced with other implementations)
System.setProperty("java.protocol.handler.pkgs",
"com.ibm.net.ssl.internal.www.protocol");
java.security.Security.addProvider(new com.ibm.jsse.JSSEProvider());
// Create UDDI proxy
uddiProxy = new UDDIProxy();
uddiProxy.setInquiryURL(inquiryURL);
uddiProxy.setPublishURL(publishURL);
// Return UDDI proxy
return uddiProxy;
}
|
Running the publish applications
The following table provides a brief description of each publish application, as well as their command-line arguments.
| Application | Description | Command-line arguments |
| PublishServiceInterface | Read a WSDL service interface document and publish it as a UDDI tModel. | PublishServiceInterface <wsdlURL> <userid> <password> [<inquiryURL> <publishURL>] |
| PublishServiceImplementation | Read a WSDL service implementation document and publish it as a UDDI businessService. | PublishServiceImplementation <wsdlURL> <userid> <password> <businessKey> <tModelKey> [<inquiryURL> <publishURL>] |
The command-line arguments for these commands are:
- wsdlURL
the network accessible location for the WSDL document - userid
the userid that is registered at the UDDI registry - password
the password associated with the userid - businessKey
the businessKey for the businessEntity where the businessService will be published - tModelKey
the tModelKey for the tModel that is associated with the WSDL service interface definition - inquiryURL
the inquiry URL for the UDDI registry (the default value is http://www-3.ibm.com/services/uddi/testregistry/inquiryapi) - publishURL
the publish URL for the UDDI registry (the default value is https://www-3.ibm.com/services/uddi/testregistry/protect/publishapi)
For the PublishServiceImplementation application, a businessEntity must be published before you can
publish a businessService. To create a businessEntity, you can either use the Web-based user
interface for the UDDI registry, or you can use the UDDI4J. The UDDI4J:
Matchmaking for Web services article (see Resources), which contains an example of how to do
this. Also, the tModelKey command-line argument
can be obtained from the output of the PublishServiceInterface
application.
You can download and run both of the publish applications on your own system. To do this you must install both WSDL4J and UDDI4J, along with all of their prerequisites. You will also need an implementation of the Java Secure Socket Extension (see Resources), since it provides SSL support.
Another option is to download and install the IBM Web Services Toolkit
(see Resources). The Web Services Toolkit (WSTK)
includes WSDL4J and UDDI4J, as well as all of the other prerequisite
software. If you install the WSTK, you can use the wstkenv command to set up the classpath that is
needed to compile and run the publish applications. The wstkenv command is located in the WSTK bin directory,
and its purpose is to define a set of environment variables. One of these
environment variables is named WSTK_CP; this environment variable contains
the classpath that is required to compile and run the publish
applications. Here's an example of the command that you would use to run the
PublishServiceInterface application on Windows NT or Windows 2000:
Listing 12
java -cp %WSTK_CP% PublishServiceInterface <wsdlURL> <userid> <password> |
If you are using one of the UDDI test registries and your system is located behind a firewall, you will need to use either a socks client or to specify a socks or proxy server. The WSTK documentation includes a Toolkit Configuration Guide which contains instructions on how to do this.
Through this series of articles, I have described how to publish and find different types of WSDL service descriptions in a UDDI registry. In this last article, I showed how to use WSDL4J and UDDI4J to publish both a WSDL service interface and a service implementation. When publishing services descriptions in a UDDI registry, it is important to follow the process defined in this series of articles. By following this process, you will ensure that potential service requestors can easily find and use your Web services
- Part one in this series: Understanding
WSDL in a UDDI registry, Part 1
- Part two in this series: Understanding
WSDL in a UDDI registry, Part 2
- JSR 110: Java APIs
for WSDL is the Java Specification Request that is being worked on
through the Java Community Process.
- Download the IBM Web
Services Toolkit. It contains all of the prerequisite software
that is needed to run the publish applications.
- View and download the complete PublishServiceInterface application:
- Download the PublishServiceImplementation.java.
- Download the PublishServiceInterface.java.
- You can use the WSDL service descriptions from the first article in
this series to test the applications we've built in this article. Download SQS-interface.wsdl to see the WSDL service implementation description for a stock quote service and
download SQS.wsdl to see the WSDL service interface description
for a stock quote service.
- The UDDI4J:
Matchmaking for Web services article contains information on how to
create a businessEntity in a UDDI registry.
- The Microsoft UDDI test registry is located at http://test.uddi.microsoft.com/.
- The Java Secure Socket
Extension is used to enable SSL support.
Peter Brittenham is currently the lead architect for the IBM Web Services Toolkit. The Web Services Toolkit contains the tools and runtime support that are required to build Web services using SOAP and WSDL, as well as the runtime support to publish and find service definitions in a UDDI registry. He can be contacted at peterbr@us.ibm.com.
Comments (Undergoing maintenance)





