Web services take float with JAXR

Use JAXR to find and register Web services

1 2 3 Page 2
Page 2 of 3

To submit information to a registry, an organization must first establish an account with a registry operator, using a Web-based form similar to the one in Figure 4. Once you obtain content-submitter privileges with a registry operator, you can use the username and password established with that provider as credentials when submitting your Web service information. Registry guests don't need an account.

Figure 4. A UDDI registry operator's sign-up form. Sign-up requires that you specify both the submitting organization and a content submitter. Click on thumbnail to view full-size image. (Source: IBM Website)

Registry elements

While you can use Web-based forms to register new services and manage your existing registrations, Web service registries allow programmatic interaction: Registries are Web services themselves. From the programmatic viewpoint, you will deal with the following components:

  • Registry provider: A Web service implementation of a registry specification, i.e., the registry itself.
  • Registry client: A program that interacts with a registry provider, whether browsing/searching a registry's content or managing Web service registrations.
  • Repository item: A content piece that resides inside a registry. This might be an XML Web service description file, a code chunk needed to interact with your service, or a specification document. You submit this when registering a new Web service, and others can download that content directly from a registry.
  • Registry entry: Metadata about a registry item. It catalogues the registry item and thus facilitates finding that content. A registry entry relates to a repository item as a library card relates to a book: The card classifies a book according to a library classification scheme and thus, helps you find that book. It is not concerned with a book's actual content, such as its chapter count or layout.

A library analogy helps distinguish a registry from a repository: A registry corresponds to the library card catalogue, while a repository resembles the bookshelves. A registry is not concerned with what a content piece consists of or how it is stored—it might delegate persistent storage to another component. When you register a repository item, you act as the librarian cataloguing a newly acquired book; you must specify what categories, or taxonomies, that content belongs to. Web service registries provide access to their content only through their registry interfaces.

Enter JAXR

Each Web service registry standard specifies a registry interface specific to that registry's information model. The Java API for XML Registries (JAXR) abstracts those different registry interfaces by providing an information model superset of several Web service registry models. If you interact with Web service registries via JAXR, you should be concerned with JAXR's information model only; JAXR translates elements of that model to specific registry model elements.

Using JAXR to access registries means that your program calls JAXR's client API. Those calls invoke objects on a JAXR provider. A JAXR implementation then maps registry information models to a specific registry's requirements and communicates with a registry provider under the covers. Figure 5 illustrates how JAXR offers a high abstraction level when interacting with Web service registries from a Java program.

Figure 5. JAXR's role: A client API calls a JAXR provider. Communication might take place via XML RPC (remote procedure calls) or XML messages.

As Figure 5 suggests, JAXR provides a pluggable architecture. As new Web service registry standards evolve, a JAXR provider can incorporate mappings to those new information models. Clients are shielded from that change, since they interact only with JAXR's model. Another JAXR benefit is that a client can interact with multiple registry types in one JAXR session. Once a client specifies a service in accord with JAXR's information model, it can request to map to and register with that model with several registry types.

Since JAXR's information model defines a superset of other registry models' capabilities, not every registry supports all JAXR features. Thus, JAXR's capabilities are grouped into profiles, and each method in the JAXR API is assigned a profile level. A JAXR provider declares its supported capability level via the CapabilityProfile interface. Higher capability levels support lower-level functionality as well.

A provider that supports a capability level must implement all methods that compose that level. If a client invokes a method not part of a provider's capability level, that method will throw an UnsupportedCapabilityException. At the time of this writing, Sun Microsystems bundles a capability-level 0 JAXR provider with its Java Web Service Developer Pack (JWSDP). (Check out "Supplement: The Adventures of JWSDP.") A capability-level 0 provider supports UDDI 2.0 registries. An open source development effort is under way to produce a capability-level 1 JAXR provider; that provider will interact with ebXML registries as well.

JAXR's client API serves both submitting organizations and registry guests. In other words, the API's two functionalities relate to managing registry objects—adding, editing, and removing Web service registrations or lifecycle management—and querying registries. The API occupies two packages: javax.xml.registries contains interfaces and classes related to lifecycle management and querying, while javax.xml.registries.infomodel includes the JAXR information model's classes.

Registry communication via JAXR

Using JAXR, our friend can quickly register her travel agency via the following five-step process:

  1. Connect to Web service registries. JAXR connections are created via the ConnectionFactory class. You can use the javax.xml.registry.ConnectionFactoryClass property to specify what factory class to use when creating a registry connection. If you specify a factory class that belongs to a capabilities 1 JAXR provider, you can connect to registries supported by that level API; if you specify one that supports level 0 only, you can interact only with UDDI registries. The JAXR specification suggests that you obtain your registry ConnectionFactory via a naming and directory service lookup; alternatively, you might create a new factory via a static creational method. JAXR also lets you simultaneously converse with multiple registry providers by requesting a FederatedConnection from the connection factory. Queries perform in a distributed manner via a federated connection.
  2. Prepare the connection. Associate attributes with the connection—the most common attributes being your credentials. You need to specify credentials for lifecycle management-related activities; you don't if you wish only to query a registry.
  3. Query or update the registry. Once you have a connection open to one or more registries, you obtain a reference to an abstraction for the registry via the RegistryService interface. If you decide to query the registry, you obtain from RegistryService a BusinessQueryManager or a DeclarativeQueryManager, depending on how you wish to search (more on searching later). For lifecycle management tasks, you would request the registry's LifeCycleManager.
  4. The registry's response to both queries and updates transmit to the client in the form of JAXRResponse objects. BulkResponse is a JAXRResponse type and contains a Collection object whose elements correspond to query replies. Or, if you tried to update the registry and the update failed, BulkResponse also lets you obtain a set of JAXRException objects telling you what went wrong.
  5. Close the connection.

The following code snippet illustrates these steps:

try {
     //1. Obtain a connection factory, either by creating a new instance, 
     //or from a naming and directory service.
     ConnectionFactory cFac = ConnectionFactory.newInstance();
     //Set up properties for the connection factory.
     Properties prop = new Properties();
     //Factory class to use.
     prop.setProperty("javax.xml.registry.factoryClass",
           "com.sun.xml.registry.uddi.ConnectionFactoryImpl");
     //Query URL.
     prop.setProperty("javax.xml.registry.queryManagerURL",
           "http://www-3.ibm.com/services/uddi/v2beta/inquiryapi");
     
     //Lifecycle manager URL. Note the use of SSL. 
     prop.setProperty("javax.xml.registry.lifeCycleManagerURL",
           "https://www-3.ibm.com/services/uddi/v2beta/protect/publishapi");
     cFac.setProperties(prop);
     Connection con = cFac.createConnection();
     //2. Set the properties for the connection. This is only needed for
     //   lifecycle management tasks. Use the username and password you 
     //   established with the registry operator.
     String userName = "testuser";
     String password = "testuser";
     PasswordAuthentication pw =
          new PasswordAuthentication(userName, password.toCharArray());
     Set cSet = new HashSet();
     cSet.add(pw);
     con.setCredentials(creds);
     
     //3. Obtain the registry service, and from that object, obtain the 
     // JAXR provider's BusinessQueryManager or LifeCycleManager objects.
     RegistryService regService = con.getRegistryService();
     BusinesQueryManager qm = regService.getBusinessQueryManager();
     BusinessLifeCycleManager lcm  = regService.getBusinessLifeCycleManager();
     //Perform either queries or updates. See below for each activity's code.
     .......
     //4. Handle the appropriate response. See below.
     .......
     //5. Close connection.
     con.close();
} catch (JAXRException e) {
     ....
}

The JAXR information model

At the heart of JAXR's information model is the RegistryObject; everything inside the registry is a RegistryObject. (Recall that registry objects represent metadata and differ from repository objects, which contain the actual content.) RegistryObject itself is defined as an attribute collection or Slots. You can dynamically add or remove attributes from a RegistryObject.

When you register your company with a registry provider, you create a RegistryObject subtype called Organization. An Organization can have any number of child organizations and Users associated with it. You can also assign TelephoneNumber and PostalAdress values to an Organization.

Most important, the services offered by an Organization are assigned to it in the form of Service objects. Each Service, in turn, might define several ServiceBindings. If the service is accessible via the Web—which is the case for Web services—a ServiceBinding would specify an access URI (Uniform Resource Identifier) for that service. As well, a service might also provide a SpecificationLink that points to the technical specification needed to invoke the service via the access URL. That specification link would point back to another RegistryObject representing the specification itself. The actual specification content—stored in a repository beneath the registry or at an external location—might be a WSDL document, a CORBA IDL (interface definition language) file, a Java RMI (Remote Method Invocation) stub, or even a Jini service template. Figure 6 illustrates the relationship between an organization and its services.

Figure 6. Organization-related classification of registry objects in the JAXR information model

If you looked for a specific organization's services (for instance, Sun's or IBM's), you would only need the relationship hierarchy I just described. Based on the organization's name, you would obtain the services it provides, and then retrieve any of those services' specification and access the URI. With that information, you would then invoke the service.

However, our friend at Magellan Travel has a slightly more ambitious aim: to discover all services offered by companies in a given industry, such as hotels and cruise lines. Therefore, she must classify registry objects (companies and their services) according to industry-specific, and even geographic, taxonomies.

JAXR's information model lets you classify a registry object according to any taxonomy. For instance, the Magellan Travel Agency would want to advertise that it is a travel agency. Based on that information, cruise lines could then locate Magellan's Organization; retrieve Magellan's services, a service to update cruise travel information, for instance; and invoke those services. Therefore, Magellan would need to classify its Organization registry object in accordance with an industry-specific taxonomy, preferably a standard one shared by businesses worldwide.

Similarly, a cruise company would describe itself as belonging to the cruise industry. Magellan would periodically contact Web services registries via JAXR, and query those registries based on an industry-specific taxonomy. Further, suppose that Magellan only offered cruises in the South Pacific. In that case, it would also want to query the registries along geographic taxonomy lines. For that to work, cruise companies must be able to classify themselves according to multiple taxonomies. JAXR provides these capabilities.

JAXR taxonomy

A taxonomy in JAXR's information model corresponds to a set of Classifications—a ClassificationScheme. You can represent the taxonomy's elements internal to the registry—those elements would then themselves be registry objects. Alternatively, you might classify registry objects according to taxonomies external to the registry. Regardless of whether you use internal or external Classifications, you'd call RegistryObject's addClassification() method to link the classification with the registry object.

1 2 3 Page 2
Page 2 of 3