The JAXR API
So far, we have discussed at a conceptual level the object model defined by JAXR. Let us now look at the API that client apps use to interact with the registry and work with this model.
RegistryService is the main interface implemented by the JAXR pluggable provider layer. It allows the client to query the implementation for the capability level it supports and also obtain references to the three main interfaces from the underlying registry-specific providers. These are:
-
The BusinessLifeCyleManager interface, used for creating objects based on the information model
- The BusinessQueryManager interface, used to query the registry using objects from the information model
- The DeclarativeQueryManager interface, used to execute statement type queries on the registry
All objects in the information model are implemented as interfaces in JAXR. The underlying registry provider supplies the implementation classes. As ScreenShot shows, we will break up the API into four parts for discussion, along the lines of connecting to the registry, creating data items, finding data, and performing queries on the registry. Let us look at each of them in detail.
JAXR and Connections
The first few step in any JAXR app is to establish a connection to the underlying registry, which is abstracted with a RegistryService interface. In general, all JAXR apps have the following sequence:
-
Create a ConnectionFactory.
- Create a Connection object from that factory to the registry.
- Pass the Connection the appropriate user credentials (e.g., username and password) required by the registry operator.
- Obtain the reference to the RegistryService from the connection.
- Do some work with the RegistryService.
JAXR uses the Factory pattern and a ConnectionFactory that can be configured with properties for initializing the underlying Connection object. Just like the JAXM factories discussed in , the JAXR factory can be obtained from the J2EE container's JNDI context, as shown below:
HashMap properties = new HashMap(); properties.put("some property", "some value"); // set other properties. InitialContext ctx = new InitialContext(properties); ConnectionFactory connfactory = (ConnectionFactory)ctx.lookup("java:comp/env/jaxr/connectionfactory");
Note that the JNDI mechanism can be used only if the container supports it. Tomcat and the reference implementation servlet container do not have this feature. EJB containers such as the J2EE reference implementation do have this feature.
Tomcat 4.1 and above can be enabled to use JNDI with some effort; see details at http://jakarta.apache.org/tomcat/tomcat-4.1-doc/index.html.
Table 12.1 shows the properties specified by JAXR. The only required setting is the javax.xml.registry.queryManagerURL property; others are optional. The factory can also be instantiated by the default mechanism using the new-Instance() method, as shown below:
// Set the properties for the factory Properties environment = new Properties(); environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL); environment.setProperty("javax.xml.registry.lifeCycleManagerURL", PUBLISH_URL); // Instantiate the factory and create a connection from it ConnectionFactory connfactory = ConnectionFactory.newInstance(); connfactory.setProperties(environment); Connection connection = connfactory.createConnection(); // Authenticate the username and password with the registry PasswordAuthentication passwdAuth = new PasswordAuthentication(uddiusername, uddipassword.toCharArray()); Set credentials = new HashSet(); credentials.add(passwdAuth); connection conn.setCredentials(credentials); // Obtain a reference to the registry service RegistryService registryservice = connection.getRegistryService();
Connection property |
Description |
---|---|
javax.xml.registry.queryManagerURL |
A required string that specifies the URL to the query manager service for the provider. |
javax.xml.registry.lifeCycleManagerURL |
An optional string that specifies the URL to the lifecycle manager service for the provider. |
javax.xml.registry.semanticEquivalences |
An optional set of tuples that specifies how two Concepts in two different ClassificationSchemes for the internal taxonomy may be considered equivalent (for example, microsoft-com:geoweb:2000:United States, microsoft-com:geoweb:2000:USA | microsoft-com:geoweb:2000:Netherland, microsoft-com:geoweb:2000:Holland) |
javax.xml.registry.security.authenticationMethod |
An optional string that may be used to tell the provider about the authentication method to use |
javax.xml.registry.uddi.maxRows |
An optional integer that tells UDDI registries the maximum number of rows that should be returned for find operations |
javax.xml.registry.postalAddressScheme |
The PostalAddress object in the information model has well-defined attributes (e.g., street, city, postal code), whereas some registries, such as the UDDI registry, may represent address attributes simply as a set of lines. This optional string property can be used to specify a ClassificationScheme (i.e., a postal address scheme) the provider uses to map the structured information in JAXR and unstructured information in the underlying registry. |
JAXR and Create-Replace-Update-Delete (CRUD) Operations
The second part of the JAXR API deals with how apps can work with and manipulate objects in the information model with operations that can be used to create, update, delete, and save data in the underlying registry. The JAXR provider is responsible for translating these operations into the underlying registry's API calls. The LifeCycleManager and the BusinessLifeCycleManager in the javax.xml.registry package shown in ScreenShot primarily abstracts all these operations, which are shown in ScreenShot. The two lifecycle managers contain overloaded methods for:
-
Creating metadata entries such as Associations, Classification, ClasslificationScheme, and Concept
- Creating data entries such as Organization, User, PostalAddress, Telephonenumber, Service, and ServiceBinding
- Saving and deleting the Organization, Service, Concepts, Associations, and so on

Screenshot: The LifeCycleManager and the BusinessLifeCycleManager
Earlier in the chapter, we mentioned how everything in the information model is represented by an interface and that the implementation classes are vendor-provided. The BusinessLifeCyleManager is used as a factory for instantiating these objects in app classes. For example, empty User and TelephoneNumber objects can be created as shown below and subsequently populated with relevant attributes:
User contact = lifecyclemgr.createUser(); TelephoneNumber telnum = lifecyclemgr.createTelephoneNumber();
JAXR and Get-Find Operations
The third part of the API relates to searching the registry using get-find type operations. These operations relating to retrieving data from the underlying registry are abstracted by the QueryManager and the BusinessQueryManager interfaces in the javax.xml.registry package, as ScreenShot shows. Both these query managers contain overloaded methods that relate to different mechanisms for searching and retrieving information on existing data in the registry. The data could relate to Associations, Organizations, Concepts, or other objects from the information model. The JAXR provider takes care of translating these operations into the underlying registry's API and generating the corresponding SOAP messages.
A registry can be queried for different fields (e.g., Organization, Concepts, ServiceBindings, Service, Associations) using the BusinessQueryManager interface. Each argument to the methods in this interface is of type java.util.Collection, which represents the following:
-
findQualifiers. Constants specified in the javax.xml.registry.FindQualifier interface that specify the find criteria (e.g., sorting, searching, etc.) For example, to search in a case-sensitive manner and have the results arranged in descending order, the qualifier parameter would look like this:
Collection findqualifier= new ArrayList(); findqualifier.add(FindQualifier. CASE_SENSITIVE_MATCH); findqualifier.add(FindQualifier. SORT_BY_NAME_DESC);
- namePatterns. The wildcard pattern based on the syntax of the SQL LIKE clause to search on (e.g., %Flute%, %Flute, Flute, Flute%, etc.)
- For example, to search for an organization whose name contains starts with "Flute" in a case-sensitive manner and have the results arranged in descending order, the code would look like this:
Collection findqualifier= new ArrayList(); findqualifier.add(FindQualifier. CASE_SENSITIVE_MATCH); findqualifier.add(FindQualifier. SORT_BY_NAME_DESC); Collection searchpattern = new ArrayList(); searchpattern.add("%Flute"); BulkResponse response = querymgr.findOrganizations(findqualifier,searchpattern, null, null, null, null);
- classifications. The Classification objects to use during the find operation.
- specifications. The javax.xml.registry.infomodel.Concept or javax.xml.registry.infomodel.ExtrinsicObject objects to use during the find operation.
- externalIdentifiers. The javax.xml.registry.infomodel.ExternalIdentifiers objects to use during the find operation.
- externalLinks. The javax.xml.registry.infomodel.ExternalLink objects to use during the find operation.
Typical use cases covered later in this chapter will show more detailed code using these parameters in the corresponding find operations.
JAXR and Declarative Queries
Level 1 registries, such as the ebXML registry, expose clients with the ability to execute declarative queries against the registry (ScreenShot). JAXR abstracts this using the Query and DelarativeQuery interfaces. JAXR at present supports only SQL-92 and the OASIS ebXML registry filter queries. An example of a simple query that returns all the organizations in the registry is shown below:
// obtain a connection here RegistryService registryservice = conn.getRegistryService(); DeclarativeQueryManager decquerymgr = registryservice. getDeclarativeQueryManager; String querystr = "SELECT * FROM Organization" Query query = decquerymgr.createQuery(Query.QUERY_TYPE_SQL, querystr); BulkResponse response = dqm.executeQuery(query);

Screenshot: The DeclarativeQueryManager for level 1 providers
The relational schema definition for SQL queries required by the ebXML Registry Service can be found at www.oasis-open.org/committees/regrep/documents/2.0/sql/database.sql. The stored procedures that must be supported by the SQL query feature are defined at www.oasis-open.org/committees/regrep/documents/2.0/sql/storedProcedures.sql.
Publishing Company Information to a UDDI Registry
The JAXR API provides a higher level of abstraction. There are essentially two ways to register the business and the services it provides with a UDDI registry. UDDI specifications require that a UDDI provider expose the registry though a Web-based HTML interface, such as that shown in earlier figures. In this section, we will show how the JAXR API can be used to register details about Flute Bank and its bill payment Web service in the UDDI registry.
The relational schema definition for SQL queries required by the ebXML Registry Service can be found at www.oasis-open.org/committees/regrep/documents/2.0/sql/database.sql. The stored procedures that must be supported by the SQL query feature are defined at www.oasis-open.org/committees/regrep/documents/2.0/sql/storedProcedures.sql.
From an information model perspective, here are the steps that need to be followed to create the conceptual representation:
-
Create an Organization object.
- Create a User object with a TelephoneNumber and EmailAddress and set it as the primary contact for the Organization.
- Classify the Organization. We will follow the NAICS classification scheme and assign the code and category description that fits Flute Bank: the high-level category of "Finance and Insurance," with a corresponding code of 52.
From an implementation perspective, the steps are straightforward:
-
Create a Connection and obtain a reference to the RegistryService.
- Obtain a BusinessLifeCycleManager from the RegistryService.
- Obtain a BusinessQueryManager from the RegistryService. This is used only to set the ClassificationScheme.
- Create the information model, as outlined above. Save the organization in the registry by invoking the saveOrganizations(Collection organizations) method in the BusinessLifeCycleManager.
- Parse the BulkResponse returned by the registry to obtain the unique key the registry assigned our service.
- Close the connection to the registry.
Listing 12.1 shows the complete code for these steps. Upon successful registration, the registry assigns a unique key and discovery URL to Flute Bank, which are printed in the output of the example. The successful registration can be verified using the Web interface of the registry, shown in ScreenShot.
Remember that although we are publishing to a UDDI registry, developers using JAXR never have to do anything UDDI-specific. JAXR providers take care of all the wiring under the hood.
Let us examine what happens under the hood when the example class UDDIPublish is executed. Publication calls to UDDI happen only as a set of authenticated operations where the authentication is token-based. The JAXR provider connects to the registry using SSL and verifies the username and password by making the get_authToken call. The registry returns the XML response with the authToken element. The request sent looks like this:
The response from the registry looks like this:
The provider then sends another SOAP request, which includes the token and XML structure, based on the save_business UDDI operation:
In response to this request, the registry returns the businessDetail structure, which is the top-level element in the UDDI information model. It is used to represent information about an entity or business, as shown below:
Notice that in the businessDetail structure of the response, the registry has assigned the unique identifier to the entity and filled out the businessKey, operator, and authorizedName attributes. It has also assigned a unique discovery URL, where the XML describing the UDDI businessEntity structure for Flute Bank can be accessed. All this communication and these SOAP messages are transparent to the Java app. The app deals only with the JAXR API and the information model objects contained therein; the provider takes care of the details.
Because publication to UDDI happens over SSL, the SOAP messages cannot be captured on the wire using HTTP tools. JAXR debugging can be enabled by using the options
Additionally, using -DuseSOAP=true enables JAXR to switch Soap4J instead of JAXM internally. This can be helpful when using JDK 1.4.
WSDL, with its abstract and concrete sections, was covered in ; in , UDDI and how the WSDL elements map to UDDI elements was discussed. Let us now look at how JAXR can be used to publish service descriptions contained in the WSDL programmatically to a registry.
The service interface consists of the abstract description (types, messages, operations, portTypes, and elements) and a protocol binding (binding element), which describe the Web service interface. The service implementation consists of the imported service interface and the WSDL service element, which describe port implementation details, such as location. Typically, the service interface and the service implementation can and should be defined in different WSDL documents. The rationale behind this from the UDDI consortium is that different industry verticals will define a set of service interfaces that will be made publicly available. Organizations will then build services that conform to these industry-standard specifications (i.e., the abstract definition and the protocol binding for the service), implement them, and expose the endpoints. These recommendations from the UDDI consortium can be found at www.uddi.org/bestpractices.html.
Let us look at the earlier example of the bill payment service. Suppose all the banks in the Good Banking Consortium got together and agreed to have a common bill payment service interface, so that customers of one bank could use the bill payment service of another bank to address a wider merchant account base. They could describe the billpayserviceinterface.wsdl shown in Listing 12.2a. (This is the same WSDL we covered in previous chapters.) Flute Bank could then implement this standard service and expose it as an endpoint. The WSDL is shown in Listing 12.2c. Notice that the schema definitions in billpayservice.wsdl have also been separated into their own XSD file, so that they can be reused across multiple service interfaces. Listing 12.2b shows the schema.Listing 12.2a: Service interface separated into billpayinterface.wsdl
In , we mentioned best practices relating to how the WSDL elements should be stored in the registry. The WSDL service interface should be represented as a tModel, so that it can be reused across service implementations. The service and port elements in the service implementation descriptions map to the businessService and bindingTemplate in the UDDI registry. ScreenShot shows the mapping of the WSDL elements to the UDDI structures for the BillPay Web service. ScreenShot shows the WSDL information as it would appear in the UDDI registry browser.
All the above mappings can be realized quite easily using JAXR. Let us look at how the WSDL can be published to a UDDI registry and examine the JAXR code for doing so. The JAXR client should:
Connect to the registry and authenticate with the username and password.
Note that in the ideal situation, steps 1 to 6 would be performed by the industry consortium (such as the Good Banking Consortium). Flute Bank would perform only step 6 and publish it under the service implementation within its own organization. In most cases today, however, the service interface and description would be shared by the same business entity. The code in Listing 12.3 shows details about doing so with JAXR.Listing 12.3: JAXR app to publish the WSDL
By default, JAXR will download and verify that the WSDL is available at the URLs when publishing. The validation can be bypassed by using the setValidateURI(false) method.
Although five usage combinations can be derived and are outlined below based on the concept of separating the service interface and service implementation, we believe that usage is currently typically centered around two use cases (items two and three).
Publishing the service interface only. This can be realized as the first part of Listing 12.3.
The only difference between the realization for this and Listing 12.3 would be multiple ServiceBinding objects associated with the Service.
We have already covered the case of finding entities in the registry in the previous two examples, where we searched for an organization called Flute Bank and also for classifications. Steps 1 through 8 remain the same as in the section Publishing Company Information to a UDDI Registry and in Listing 12.1, with one exception. Per the UDDI specifications, no authentication or SSL is needed to query the registry. Let us look at the subsequent steps:
Use the reference to the BusinessQueryManager and one of the find methods (see ScreenShot) to query the registry. Listing 12.4 queries the registry for an organization whose name must exactly match "Flute Bank." This should return one or more organizations, one of which would be the organization we published in Listing 12.1.
We have looked at how service information can be published. Let us now look at how it can be retrieved from the registry by JAXR client apps. There are two broad use cases for retrieving the WSDL definition:
The client knows the organization and wants to retrieve one or more interfaces shared by it.
In the first case, the client must query the registry for a particular organization. It can retrieve this information based on name, classification, external identifiers, and other criteria. The organization can then be queried for the services published under it. Listing 12.5a shows how the WSDL published earlier can be retrieved using the Flute Bank organization name. Listing 12.5b shows its corresponding output.Listing 12.5a: Querying the registry for service information
In the second case, the client can query the registry based on the namespace declaration from the WSDL defining the service interface. The namespace corresponds to the name of the concept (i.e., the tModel name) classified with the wsdlSpec in UDDI, as shown earlier. This may be helpful in two cases:
The parties can agree upon the namespace as part of the service level agreement between them.
Listing 12.6a shows how the service can be queried on namespace. Listing 12.6b shows the corresponding output.Listing 12.6a: Service discovery based on namespace
We have just looked at how the service information can be published and retrieved from the UDDI registry. In , we talked about the register-find-bind scenario for Web services. In most cases, service consumers will locate the WSDL and generate the client-side code in Java or other languages for consuming that service. In , we looked at how to do this for both Java and C#. This is a typical use of the static compile-time binding pattern discussed in . In most cases, clients will not look up the UDDI registry at runtime for this information, because the WSDL published in the registry will be part of some service level or business agreement and will not be expected to change often.
We also discussed the second static deploy-time binding pattern, where the portType is known but the location is retrieved at runtime. Let us look at a strategy for implementing this pattern:
Design-time tools can discover the service in the UDDI registry and retrieve its service interface and the service implementation. Though we looked at how to do this programmatically with JAXR, we envision that vendor-provided tools will perform this task at design time, using APIs such as those provided by JSR-110 (Java API for WSDL) in combination with JAXR.
We have already discussed this static deploy-time pattern earlier but clearly this can be useful if:
The service location changes.
Though we have discussed how information can be published progammatically to the registry, it is quite common for an enterprise to follow an administrator-driven approach during app deployment into production environments Here, for example, a designated person is responsible for publishing information in the UDDI registry using the browser-based interface. This also makes sense, because information such as company address, contact information, and service location is expected to remain static and is included as part of the service level agreements forged with business partners.
Screenshot: Flute Bank as registered in the IBM UDDI registry Listing 12.1: Publishing organization information
import javax.xml.registry.infomodel.*;
import javax.xml.registry.*;
import java.util.*;
import java.net.PasswordAuthentication;
public class UDDIPublishOrg {
private static final String QUERY_URL=
"http://www-3.ibm.com:80/services/uddi/v2beta/inquiryapi";
private static final String PUBLISH_URL =
"https://www-3.ibm.com:443/services/uddi/v2beta/protect/publishapi";
private static String uddiusername;
private static String uddipassword;
public static void main(String[] args) {
if(args.length!=2){
System.out.println("Usage java UDDIPublish username uddipassword");
return;
}
uddiusername = args[0];
uddipassword = args[1];
try{
// Set the properties for the ConnectionFactory
Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL);
environment.setProperty("javax.xml.registry.lifeCycleManagerURL",PUBLISH_URL);
// Instantiate the factory and create a connection from it
ConnectionFactory connfactory = ConnectionFactory.newInstance();
connfactory.setProperties(environment);
Connection conn = connfactory.createConnection();
// Authenticate the username and password with the registry
PasswordAuthentication passwdAuth = new PasswordAuthentication
(uddiusername, uddipassword.toCharArray());
Set credentials = new HashSet();
credentials.add(passwdAuth);
conn.setCredentials(credentials);
// Obtain a reference to the RegistryService, the BusinessLifeCycleManager, and
// the BusinessQueryManager
RegistryService registryservice = conn.getRegistryService();
BusinessLifeCycleManager lifecyclemgr
=registryservice.getBusinessLifeCycleManager();
BusinessQueryManager querymgr = registryservice.getBusinessQueryManager();
// Create an organization object
Organization company = lifecyclemgr.createOrganization("Flute Bank");
InternationalString description = lifecyclemgr.createInternationalString("A
fictitious bank used for examples in the tutorial Java Web Services Architecture,
"+ "shared by Morgan Kaufman, ." +
"The authors can be reached at webservicesbook@bugmenot.com OR" +
"www.javawebservicesarchitecture.com. ");
company.setDescription(description);
// Create a user object
User contact = lifecyclemgr.createUser();
PersonName name = lifecyclemgr.createPersonName("John Malkovich");
contact.setPersonName(name);
// Create and set the user's telephone number
TelephoneNumber telnum = lifecyclemgr.createTelephoneNumber();
telnum.setNumber("1-800-FLUTE-US");
Collection phonenumbers = new ArrayList();
phonenumbers.add(telnum);
contact.setTelephoneNumbers(phonenumbers);
// Create and set the user's email address
EmailAddress email = lifecyclemgr.createEmailAddress
("uddiadmin@bugmenot.com");
Collection emaillist = new ArrayList();
emaillist.add(email);
contact.setEmailAddresses(emaillist);
// Set the user as the primary contact for the organization
company.setPrimaryContact(contact);
ClassificationScheme scheme =
querymgr.findClassificationSchemeByName(null," ntis-gov:naics");
// Create the classification using the above scheme and pass the relevant category
code and description
Classification classification =
(Classification)lifecyclemgr.createClassification(scheme, "Finance and Insurance",
"52");
Collection classificationlist = new ArrayList();
classificationlist.add(classification);
company.addClassifications(classificationlist);
// Set the organization in the list of organizations
// An organization list is a list of organizations, because a user could choose to
publish multiple organizations
Collection organizationlist = new ArrayList();
organizationlist.add(company);
// make the final call to the registry and get a response
BulkResponse response = lifecyclemgr.saveOrganizations(organizationlist);
Collection exceptions = response.getExceptions();
// If there are no exceptions, the publish action was successful
if (exceptions == null) {
Collection keys = response.getCollection();
Iterator iterator = keys.iterator();
Key key = (Key) iterator.next();
String uid = key.getId();
System.out.println("The unique ID returned by the UDDI registry for
the Organization is " + uid);
company.setKey(key);
}
// This means exceptions occurred during the publish action
else {
Iterator iterator = exceptions.iterator();
while (iterator.hasNext()) {
Exception exception = (Exception) iterator.next();
System.out.println("Exception occurred while saving to the
registry: " + exception);
}
}
// Finally, close the connection
conn.close();
} catch (Exception exception) {
System.out.println("General exception occurred: " + exception);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<get_authToken generic="2.0" user cred="fluteuddi"
xmlns="urn:uddi-org:api_v2"/>
</soap-env:Body>
</soap-env:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<authToken generic="2.0" xmlns="urn:uddi-org:api_v2"
operator="www.ibm.com/services/uddi">
<authInfo>xyzi2892somesecuretoken</authInfo>
</authToken>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<save_business generic="2.0" xmlns="urn:uddi-org:api_v2">
<authInfo>xyzi2892somesecuretoken</authInfo>
<businessEntity businessKey="">
<name xml:lang="en">Flute Bank</name>
<description xml:lang="en">A fictitious bank used for examples in the tutorial
Java Web Services Architecture, shared by Morgan Kaufman,
1-55860-900-8. The authors can be reached at webservicesbook@bugmenot.com OR http://www.javawebservicesarchitecture.com.
</description>
<contacts>
<contact>
<description xml:lang="en">
The primary contact person for Flute web services
</description>
<personName>John Malkovich</personName>
<phone useType="">1-800-FLUTE-US</phone>
<email>uddiadmin@bugmenot.com</email>
</contact>
</contacts>
<businessServices>
<businessService serviceKey="">
<name xml:lang="en">Billpayservice</name>
<description xml:lang="en">A web service allowing online account holders to
pay bills online</description>
<bindingTemplates>
<bindingTemplate bindingKey="">
<description>Flute Bank, beyond providing simple account-related
services, also has the infrastructure to support online bill payments.
The online bill payment system is offered to customers as a value-added service.
</description>
<accessPoint URLType="http">
http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay
</accessPoint>
<tModelInstanceDetails/>
</bindingTemplate>
</bindingTemplates>
</businessService>
</businessServices>
<categoryBag>
<keyedReference tModelKey="uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"
keyName="Finance and Insurance" keyValue="52"/>
</categoryBag>
</businessEntity>
</save_business>
</soap-env:Body>
</soap-env:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<businessDetail generic="2.0" xmlns="urn:uddi-org:api_v2" operator="www.ibm.com/
services/uddi">
<businessEntity businessKey="25BF1920-D020-11D6-9314-000629DC0A7B"
operator="www.ibm.com/services/uddi" authorized >
<discoveryURLs>
<discoveryURL useType="businessEntity">
http://uddi.ibm.com/testregistry/uddiget?businessKey=25BF1920-D020-11D6-
9314-000629DC0A7B
</discoveryURL>
</discoveryURLs>
<name xml:lang="en">Flute Bank</name>
<description xml:lang="en">A fictitious bank used for examples in the tutorial
Java Web Services Architecture, shared by Morgan Kaufman, .
The authors can be reached at webservicesbook@bugmenot.com OR
http://www.javawebservicesarchitecture.com.
</description>
<contacts>
<contact>
<description xml:lang="en">The primary contact person for Flute Web services
</description>
<personName>John Malkovich</personName>
<phone useType="">1-800-FLUTE-US</phone>
<email>uddiadmin@bugmenot.com</email>
</contact>
</contacts>
<businessServices>
<businessService serviceKey="25E12010-D020-11D6-9314-000629DC0A7B"
businessKey="25BF1920- D020-11D6-9314-000629DC0A7B">
<name xml:lang="en">Billpayservice</name>
<description xml:lang="en">A Web service allowing account holders to pay bills
online</description>
<bindingTemplates>
<bindingTemplate bindingKey="2606F790-D020-11D6-9314-000629DC0A7B"
serviceKey="25E12010-D020-11D6-9314-000629DC0A7B">
<description xml:lang="en">Flute Bank, beyond providing simple
account-related services, also has the infrastructure to support
online bill payments. The online bill payment system is offered
to customers as a value-added service.
</description>
<accessPoint
URLType="http">http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay
</accessPoint>
<tModelInstanceDetails/>
</bindingTemplate>
</bindingTemplates>
</businessService>
</businessServices>
<categoryBag>
<keyedReference tModelKey="UUID:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"
keyName="Finance and Insurance" keyValue="52"/>
</categoryBag>
</businessEntity>
</businessDetail>
-Dorg.apache.commons.logging.log=org.apache.commons.logging.impl.SimpleLog and
-Dorg.apache.commons.logging.simplelog.defaultlog=debug.
Publishing Service Information to a UDDI Registry
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="billpayservice-abstractinterface" targetNamespace="http://
www.flutebank.com/xml" xmlns:tns="http://www.flutebank.com/xml" xmlns="http://
schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap=
"http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<schema targetNamespace="billpaydatatypes.xsd" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns="http://www.w3.org/2001/XMLSchema"/>
</types>
<message name="billpay_getlastpayment">
<part name="string_1" type="xsd:string"/>
</message>
<message name="billpay_getlastpaymentresponse">
<part type="xsd:double"/>
</message>
<message name="billpay_listscheduledpayments"/>
<message name="billpay_listscheduledpaymentsresponse">
<part type="tns:ArrayOfPaymentDetail"/>
</message>
<message name="billpay_schedulepayment">
<part name="date_1" type="xsd:dateTime"/>
<part name="string_2" type="xsd:string"/>
<part name="double_3" type="xsd:double"/>
</message>
<message name="billpay_schedulepaymentresponse">
<part type="tns:PaymentConfirmation"/>
</message>
<message >
<part
type="tns:ScheduleFailedException"/>
</message>
<portType >
<operation parameterOrder="String_1">
<input message="tns:BillPay_getLastPayment"/>
<output message="tns:BillPay_getLastPaymentResponse"/>
</operation>
<operation parameterOrder="">
<input message="tns:BillPay_listScheduledPayments"/>
<output message="tns:BillPay_listScheduledPaymentsResponse"/>
</operation>
<operation
parameterOrder="Date_1 String_2 double_3">
<input message="tns:BillPay_schedulePayment"/>
<output message="tns:BillPay_schedulePaymentResponse"/>
<fault
message="tns:ScheduleFailedException"/>
</operation>
</portType>
<binding type="tns:BillPay">
<operation >
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</output>
<soap:operation soapAction=""/>
</operation>
<operation >
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</output>
<soap:operation soapAction=""/>
</operation>
<operation >
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</output>
<fault >
<soap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
use="encoded" namespace="http://www.flutebank.com/xml"/>
</fault>
<soap:operation soapAction=""/>
</operation>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
</binding>
</definitions>
Listing 12.2b: The schema definition referenced by billpayservice.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://www.flutebank.com/xml" xmlns="http://www.w3.org/2001/
XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.flutebank.com/xml"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType >
<complexContent>
<restriction base="soap-enc:Array">
<attribute ref="soap-enc:arrayType" wsdl:arrayType=
"tns:PaymentDetail[]"/>
</restriction>
</complexContent>
</complexType>
<complexType >
<sequence>
<element type="dateTime"/>
<element type="string"/>
<element type="string"/>
<element type="double"/>
</sequence>
</complexType>
<complexType >
<sequence>
<element type="int"/>
<element type="string"/>
<element type="double"/>
</sequence>
</complexType>
<complexType >
<sequence>
<element type="string"/>
<element type="string"/>
</sequence>
</complexType>
</schema>
Listing 12.2c: The billpayservice.wsdl implemented by Flute Bank
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="billpayservice" targetNamespace="http://www.flutebank.com/
billpayservice" xmlns:tns="http://www.flutebank.com/xml" xmlns="http://
schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap=
"http://schemas.xmlsoap.org/wsdl/soap/">
<import namespace="http://www.flutebank.com/xml"
location="baillpayinterface.wsdl"/>
<service >
<port binding="tns:BillPayBinding">
<soap:address
location="http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay"/>
</port>
</service>
</definitions>
Screenshot: WSDL representation in UDDI
// imports not shown
public class WSDLuploader {
private static final String QUERY_URL =
"http://www-3.ibm.com:80/services/uddi/v2beta/inquiryapi";
private static final String PUBLISH_URL =
"https://www-3.ibm.com:443/services/uddi/v2beta/protect/publishapi";
private static String uddiusername;
private static String uddipassword;
/**
* Main method to publish the WSDL to the UDDI registry
*/
public static void main(String[] args) {
if(args.length!=2){
System.out.println("Usage java UDDIPublish username uddipassword");
return;
}
uddiusername = args[0];
uddipassword = args[1];
try{
// Set the properties for the ConnectionFactory
Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL",
QUERY_URL);
environment.setProperty("javax.xml.registry.lifeCycleManagerURL",
PUBLISH_URL);
// Instantiate the factory and create a connection from it
ConnectionFactory connfactory = ConnectionFactory.newInstance();
connfactory.setProperties(environment);
Connection conn = connfactory.createConnection();
// Authenticate the username and password with the registry
PasswordAuthentication passwdAuth =
new PasswordAuthentication(uddiusername, uddipassword.toCharArray());
Set credentials = new HashSet();
credentials.add(passwdAuth);
conn.setCredentials(credentials);
// Obtain a reference to the RegistryService, the BusinessLifeCycleManager,
// and the BusinessQueryManager
RegistryService registryservice = conn.getRegistryService();
BusinessLifeCycleManager lifecyclemgr =
registryservice.getBusinessLifeCycleManager();
BusinessQueryManager querymgr =
registryservice.getBusinessQueryManager();
// First find the organization (this would already be registered from the
// previous examples)
Collection searchpattern = new ArrayList();
searchpattern.add("Flute Bank");
Collection findqualifier= new ArrayList();
findqualifier.add(FindQualifier.EXACT_NAME_MATCH);
BulkResponse orgresponse = querymgr.findOrganizations(findqualifier,
searchpattern, null, null, null, null);
Collection orgs = orgresponse.getCollection();
Iterator orgiter= orgs.iterator();
// We don't need to iterate, because we know there is only one organization in the
registry
// called Flute Bank
Organization fluteorg = (Organization) orgiter.next();
// Create a concept for the service interface of the WSDL
Concept concept=
lifecyclemgr.createConcept(null," http://www.flutebank.com/xml",null);
InternationalString conceptdescription =
lifecyclemgr.createInternationalString("The service interface of the
bill payment Web service");
concept.setDescription(conceptdescription);
// Note that the WSDL at this URL must be physically accessible. JAXR will access
//the URL and ensure that the WSDL is valid
ExternalLink link=lifecyclemgr.createExternalLink(
"http://127.0.0.1:8080/billpayservice/
billpayserviceinterface.wsdl#BillPayBinding",
"Wsdl service interface document");
concept.addExternalLink (link);
// Classify the service interface as the WSDL
Collection classification=new ArrayList();
ClassificationScheme uddiOrgTypes =
querymgr.findClassificationSchemeByName(null, "uddi-org:types");
Classification wsdlclassification =
lifecyclemgr.createClassification(uddiOrgTypes, "wsdlSpec", "wsdlSpec");
classification.add(wsdlclassification);
concept.setClassifications(classification);
// Save the concept (the UDDI registry will save this as a tModel and return a
// Key to it)
Collection concepts = new ArrayList();
concepts.add(concept);
BulkResponse savedConcepts =lifecyclemgr.saveConcepts(concepts);
Iterator conceptIterator =savedConcepts.getCollection().iterator();
if (conceptIterator.hasNext()){
javax.xml.registry.infomodel.Key key
=(javax.xml.registry.infomodel.Key) conceptIterator.next();
concept.setKey(key);
System.out.println("tModel key: "+ key.getId());
}
// the service interface has been saved and the tModel created in the UDDI
// registry
// Create the concrete service (this maps to the businessService)
Service service = lifecyclemgr.createService("Billpayservice");
InternationalString servicedescription =
lifecyclemgr.createInternationalString("A Web service
allowing account holders to pay bills online");
service.setDescription(servicedescription);
// Create the service bindings for the Web service
Collection serviceBindings = new ArrayList();
ServiceBinding binding = lifecyclemgr.createServiceBinding();
InternationalString bindingdescription =
lifecyclemgr.createInternationalString("HTTP bindings for
the Billpayservice Web service");
binding.setDescription(bindingdescription);
// replace with the actual URL where the service is deployed
binding.setAccessURI("http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay");
// Create the specification link for the Web service
SpecificationLink specLink=lifecyclemgr.createSpecificationLink();
// the concept now has the key created for the tModel
specLink.setSpecificationObject(concept);
binding.addSpecificationLink(specLink);
serviceBindings.add(binding);
// Add the service bindings to service
service.addServiceBindings(serviceBindings);
// Link the service to the provider
service.setProvidingOrganization(fluteorg);
// Add the Web service to the list of services, then add the list of services to
// the organization
Collection servicelist = new ArrayList();
servicelist.add(service);
// Make the final call to the registry to save the services and get a response
BulkResponse response = lifecyclemgr.saveServices(servicelist);
System.out.println("services saved");
Collection exceptions = response.getExceptions();
// If there are no exceptions, the publish action was successful
if (exceptions == null){
Collection keys = response.getCollection();
Iterator iterator = keys.iterator();
Key key = (Key) iterator.next();
String uid = key.getId();
System.out.println("The unique ID returned by the UDDI registry for the
Organization is "+ uid);
}
// This means exceptions occurred during the publish action
else {
Iterator iterator = exceptions.iterator();
while (iterator.hasNext()) {
Exception exception = (Exception) iterator.next();
System.out.println("Exception occurred while saving to the registry: "
+ exception);
exception.printStackTrace();
}
}
// Finally, close the connection
conn.close();
} catch (Exception exception) {
System.out.println("General exception occurred: "+ exception);
}
}
}
<import namespace="http://www.goodbankconsortium.com/xml"
location="http://www.goodbankconsortium.com/creditcardinterface.wsdl"/>
<import namespace="http://www.betterbankconsortium.com/xml"
location="http://www.betterbankconsortium bankacountdebit.wsdl"/>
<service >
<port binding="good:BillPayBinding">
<soap:address
location="http://www.flutebank.com:8080/billpayservice/CardBillPay"/>
</port>
<port binding="better:BillPayBinding">
<soap:address
location="http://www.flutebankx.com:8080/billpayservice/AccountBillPay"/>
</port>
</service>
Querying UDDI Registry with JAXR
import javax.xml.registry.infomodel.*;
import javax.xml.registry.*;
import java.util.*;
public class UDDIQueryOrg {
public static void main(String[] args) {
// Set the properties for the ConnectionFactory Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL);
environment.setProperty("javax.xml.registry.lifeCycleManagerURL", PUBLISH_URL);
// Instantiate the factory and create a connection from it
ConnectionFactory connfactory = ConnectionFactory.newInstance();
connfactory.setProperties(environment);
Connection conn = connfactory.createConnection();
Collection searchpattern = new ArrayList();
searchpattern.add("Flute Bank");
Collection findqualifier= new ArrayList();
findqualifier.add(FindQualifier.EXACT_NAME_MATCH);
// Find using the name
BulkResponse response = querymgr.findOrganizations(findqualifier,
searchpattern, null, null, null, null);
// Display information about the organizations found
Collection orgs = response.getCollection();
Iterator orgiterator = orgs.iterator();
while (orgiterator.hasNext()) {
Organization org = (Organization) orgiterator.next();
System.out.println("\t Organization name: " + org.getName().getValue());
System.out.println("\t Organization description: " +
org.getDescription().getValue());
System.out.println("\t Organization uid: " + org.getKey().getId());
// Display information about the discovery URLs found
Collection links = org.getExternalLinks();
Iterator linkiterator = links.iterator();
while(linkiterator.hasNext()){
ExternalLink link = (ExternalLink)linkiterator.next();
System.out.println("\t\t Link URI = " +link.getExternalURI());
}
// Display information about the discovery URLs found
Collection classify = org.getClassifications();
Iterator classifyiterator = classify.iterator();
while(linkiterator.hasNext()){
Classification clasf = (Classification)linkiterator.next();
System.out.println("\t\t Classification value = " +clasf.getValue());
}
// Display primary contact information
User pc = org.getPrimaryContact();
if (pc != null) {
PersonName pcName = pc.getPersonName();
System.out.println("\t\t Primary contact name: " +
pcName.getFullName());
Collection phNums = pc.getTelephoneNumbers(pc.getType());
Iterator phIter = phNums.iterator();
while (phIter.hasNext()) {
TelephoneNumber num = (TelephoneNumber) phIter.next();
System.out.println("\t\t Phone number: " + num.getNumber());
}
Collection eAddrs = pc.getEmailAddresses();
Iterator eaIter = eAddrs.iterator();
while (phIter.hasNext()) {
System.out.println("\t\tEmail Address: " +
(EmailAddress) eaIter.next());
}
}
}
}
Listing 12.4b: Output of UDDIQuery
C:\jaxr\jwsa>java UDDIQueryOrg fluteadmin flutepassword Organization name: Flute Bank Organization description: A fictitious bank used for examples in the tutorial Java Web
Services Architecture, shared by Morgan Kaufman, . The authors
can be reached at
webservicesbook@bugmenot.com OR
www.javawebservicesarchitecture.com.
Organization uid: 38920050-D028-11D6-9314-000629DC0A7B
Link URI = http://uddi.ibm.com/testregistry/uddiget?
businessKey=38920050-D028-11D6-9314-000629DC0A7B
Primary contact name: John Malkovich
Phone number: 1-800-FLUTE-US
Finding Services Information in UDDI
import javax.xml.registry.infomodel.*;
import javax.xml.registry.*;
import java.util.*;
public class UDDIQueryServices {
private static final String QUERY_URL =
"http://www-3.ibm.com:80/services/uddi/v2beta/inquiryapi";
/* Main method */
public static void main(String[] args) {
try{
// Set the properties for the ConnectionFactory
Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL);
// Instantiate the factory and create a connection from it
ConnectionFactory connfactory = ConnectionFactory.newInstance();
connfactory.setProperties(environment);
Connection conn = connfactory.createConnection();
// Obtain a reference to the RegistryService,the BusinessLifeCycleManager,
// and the BusinessQueryManager
RegistryService registryservice = conn.getRegistryService();
BusinessLifeCycleManager lifecyclemgr =
registryservice.getBusinessLifeCycleManager();
BusinessQueryManager querymgr = registryservice.getBusinessQueryManager();
// prepare the arguments for the find operation
Collection searchpattern = new ArrayList();
searchpattern.add("Flute Bank");
Collection findqualifier= new ArrayList();
findqualifier.add(FindQualifier.EXACT_NAME_MATCH);
// Find using the name
BulkResponse response = querymgr.findOrganizations(findqualifier,
searchpattern, null, null, null, null);
// Display information about the organizations found
// In our case, only one should be returned
Collection orgs = response.getCollection();
Iterator orgiterator = orgs.iterator();
while (orgiterator.hasNext()) {
Organization org = (Organization) orgiterator.next();
System.out.println("Organization name: "+org.getName().getValue());
System.out.println("Organization uid: " + org.getKey().getId());
//Display service and binding information
Collection services = org.getServices();
Iterator svcIter = services.iterator();
while (svcIter.hasNext()) {
Service svc = (Service) svcIter.next();
System.out.println("\t\t Service name: " +
svc.getName().getValue());
System.out.println("\t\t Service description: " +
svc.getDescription().getValue());
Collection serviceBindings = svc.getServiceBindings();
Iterator sbIter = serviceBindings.iterator();
while (sbIter.hasNext()) {
ServiceBinding sb =(ServiceBinding) sbIter.next();
System.out.println("\t\t\t Binding "+
"Description: " +sb.getDescription().getValue());
System.out.println("\t\t\t Access URI: " +
sb.getAccessURI());
Collection servicespecs= sb.getSpecificationLinks();
Iterator servicespecit=servicespecs.iterator();
while(servicespecit.hasNext()){
SpecificationLink spec=
(SpecificationLink)servicespecit.next();
Concept tModel= (Concept)spec.getSpecificationObject();
// get the tModel
System.out.println("\t\t\t\t Service Interface :"
+tModel.getDescription().getValue());
Iterator extlinks=tModel.getExternalLinks().iterator();
while(extlinks.hasNext()){
ExternalLink extlink=(ExternalLink)extlinks.next();
System.out.println("\t\t\t\t\t Service Interface
location : "+extlink.getExternalURI());
System.out.println("\t\t\t\t\t Location
description:"
+extlink.getDescription().getValue());
}
}
}
}
}
// Finally, close the connection
conn.close();
} catch (Exception exception) {
System.out.println("General exception occurred: " + exception);
}
}
}
Listing 12.5b: Client side output of a service query
C:\jaxr\jwsa>java UDDIQueryServices flutebank fluteadmin Organization name: Flute Bank Organization uid: 46F5D8A0-D3D5-11D6-8370-000629DC0A7B
Service name: Billpayservice
Service description: A Web service allowing account holders to pay bills online
Binding Description: HTTP bindings for the
Billpayservice Web service
Access URI: http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay
Service Interface: The service interface of the bill payment Web
service
Service Interface location:
http://127.0.0.1:8080/billpayservice/billpayserviceinterface.wsdl#BillPayBinding
Location description: Wsdl service interface document
import javax.xml.registry.*;
import javax.xml.registry.infomodel.*;
import java.util.*;
public class UDDIQueryServicesByNamespace {
private static final String QUERY_URL="http://uddi.microsoft.com:80/inquire";
/* Main method of the class*/
public static void main(String[] args) {
try{
// Set the properties for the ConnectionFactory
Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL);
// Instantiate the factory and create a connection from it
ConnectionFactory connfactory = ConnectionFactory.newInstance();
connfactory.setProperties(environment);
Connection conn = connfactory.createConnection();
// Obtain a reference to the RegistryService,the BusinessLifeCycleManager
// and the BusinessQueryManager
RegistryService registryservice = conn.getRegistryService();
BusinessLifeCycleManager lifecyclemgr =
registryservice.getBusinessLifeCycleManager();
BusinessQueryManager querymgr =
registryservice.getBusinessQueryManager();
// prepare the parameters for the find operation
Collection findqualifier= new ArrayList();
findqualifier.add(FindQualifier.EXACT_NAME_MATCH);
// WSDL tModels must be classified under the wsdlSpec classification in UDDI
Collection classifications = new ArrayList();
ClassificationScheme uddiOrgTypes =
querymgr.findClassificationSchemeByName(null, "uddi-org:types");
Classification wsdlSpecClassification =
lifecyclemgr.createClassification(uddiOrgTypes, "wsdlSpec", "wsdlSpec");
classifications.add(wsdlSpecClassification);
// WSDLs corresponding to this namespace
Collection searchpattern = new ArrayList();
searchpattern.add("%http://www.flutebank.com/xml%");
// find the Concepts (i.e., the tModels)
BulkResponse response = querymgr.findConcepts(null, searchpattern,
classifications, null, null);
Collection specConcepts = response.getCollection();
Iterator iter = specConcepts.iterator();
while (iter.hasNext()) {
try {
Concept concept = (Concept)iter.next();
String name = concept.getName().getValue();
Collection extlinks = concept.getExternalLinks();
System.out.println("WSDL :\n\t Namespace: " + name +
"\n\t Key: " + concept.getKey().getId() +
"\n\t Description: " + concept.getDescription().getValue());
Iterator linkiter=extlinks.iterator();
while(linkiter.hasNext()) {
ExternalLink link = (ExternalLink)linkiter.next();
System.out.println("\t WSDL location : " + link.getExternalURI());
}
// Find all the organizations using this WSDL definition
Collection tmodels = new ArrayList();
tmodels.add(concept);
response = querymgr.findOrganizations(null, null, null, tmodels, null, null);
Collection orgs = response.getCollection();
Iterator orgIter = orgs.iterator();
if (orgIter.hasNext())
System.out.println("Organizations using the " + name + " WSDL
namespace:");
else
System.out.println("No Organizations using the WSDL " + name);
while (orgIter.hasNext()) {
Organization org = (Organization)orgIter.next();
System.out.println("\t Name: " + org.getName().getValue() +
"\n\t Key: " + org.getKey().getId() +
"\n\t Description: " + org.getDescription().getValue());
}
}catch (JAXRException e) {
e.printStackTrace();
}
}
} catch (JAXRException e) {
e.printStackTrace();
}
}
}
Listing 12.6b: The client side output
C:\jaxr\jwsa>java UDDIQueryServicesByNamespace WSDL :
Namespace: http://www.flutebank.com/xml
Key: UUID:67191F10-D3D6-11D6-8370-000629DC0A7B
Description: The service interface of the bill payment Web service WSDL location:
http://127.0.0.1:8080/billpayservice/billpayserviceinterface.wsdl#BillPayBinding Organizations with service implementations for namespace www.flutebank.com/xml
Name: Flute Bank
Key: 46F5D8A0-D3D5-11D6-8370-000629DC0A7B
Description: A fictitious bank used for examples in the tutorial Java Web Services Architecture, shared by Morgan Kaufman, . The authors can be
reached at webservicesbook@bugmenot.com OR
http://www.javawebservicesarchitecture.com.
Runtime Service Discovery from UDDI
BulkResponse response=querymgr.findServiceBindings(serviceKey,null,null,null);
Deployment-Time Publication to UDDI