FAQ
History
PreviousHomeNext Search
Feedback
Divider

JAX-RPC Distributor Service

The Coffee Break server is a client of the JAX-RPC distributor service. To examine the code for the service, in the IDE mount the <INSTALL>/j2eetutorial/examples/cb/jaxrpc directory. The service supports two operations: fetching the price list and placing an order.

Fetching the Price List

This operation is implemented by the getPriceList method of the jaxrpc.service.Supplier. The getPriceList method returns a PriceListBean object, which lists the name and price of each type of coffee that can be ordered from this service. The getPriceList method creates the PriceListBean object by invoking a private method named loadPrices. In a production application, the loadPrices method would fetch the prices from a database. However, our loadPrices method takes a shortcut by invoking PriceLoader.loadItems, a method with hardcoded prices. Here are the getPriceList and loadPrices methods:

public PriceListBean getPriceList() {

   PriceListBean priceList = loadPrices(); 
   return priceList;
}

private PriceListBean loadPrices() {

    Date today = new Date();
    Date endDate = DateHelper.addDays(today, 30);
    Collection priceItems = PriceLoader.loadItems();
    PriceListBean priceList = new PriceListBean();
    priceList.setStartDate(today);
    priceList.setEndDate(endDate);
    priceList.setPriceItems(priceItems);
    return priceList;

} 

Placing an Order

The placeOrder method of jaxrpc.service.Supplier accepts as input a coffee order and returns a confirmation for the order. To keep things simple, the placeOrder method confirms every order and sets the ship date in the confirmation to the next day. (This date is calculated by DateHelper, a utility class that resides in the jaxrpc.service package.) The source code for the placeOrder method follows:

public ConfirmationBean placeOrder(OrderBean order) {

    Date tomorrow = 
        com.sun.cb.DateHelper.addDays(new Date(), 1);
    ConfirmationBean confirmation = 
        new ConfirmationBean(order.getId(), tomorrow);
    return confirmation;
} 

Publishing the Service in the Registry

Because we want customers to find our service, we will to publish it in a registry. The programs that publish and remove our service are called OrgPublisher and OrgRemover. Although related to the service, these programs are not part of the service's Web application (that is, the servlet that implements the service). They are stand-alone programs that are run separately. These programs reside in the <INSTALL>/j2eetutorial/examples/cb/jaxrpc/registry directory.

The OrgPublisher program begins by loading String values from the CoffeeRegistry.properties file. Next, the program instantiates a utility class named JAXRPublisher. OrgPublisher connects to the registry by invoking the makeConnection method of JAXRPublisher. To publish the service, OrgPublisher invokes the executePublish method, which accepts as input username, password, and endpoint. The username and password values are required by the Registry Server. The endpoint value is the URL that remote clients will use to contact our JAX-RPC service. The executePublish method of JAXRPublisher returns a key that uniquely identifies the service in the registry. OrgPublisher saves this key in a text file named orgkey.txt. The OrgRemover program will read the key from orgkey.txt so that it can delete the service. (See Deleting the Service From the Registry.) The source code for the OrgPublisher program follows.

package jaxrpc.registry;

import javax.xml.registry.*; 
import java.util.ResourceBundle;
import java.io.*;

public class OrgPublisher {

    public static void main(String[] args) {

        ResourceBundle registryBundle =
           ResourceBundle.getBundle
           ("jaxrpc.registry.CoffeeRegistry");

        String queryURL = 
            registryBundle.getString("query.url");
        String publishURL =
            registryBundle.getString("publish.url");
        String username =
            registryBundle.getString("registry.username");
        String password =
            registryBundle.getString("registry.password");
        String endpoint = registryBundle.getString("endpoint");
       String keyFile = registryBundle.getString("key.file");

        JAXRPublisher publisher = new JAXRPublisher();
        publisher.makeConnection(queryURL, publishURL);
        String key = publisher.executePublish
            (username, password, endpoint);

        try {
            FileWriter out = new FileWriter(keyFile);
            out.write(key);
            out.flush();
            out.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
    
} 

The JAXRPublisher class is almost identical to the sample program JAXRPublish.java, which is described in Managing Registry Data.

First, the makeConnection method creates a connection to the Registry Server. See Establishing a Connection for more information. To do this, it first specifies a set of connection properties using the query and publish URLs passed in from the CoffeeRegistry.properties file. For the Registry Server, the query and publish URLs are actually the same.

Properties props = new Properties();
props.setProperty("javax.xml.registry.queryManagerURL",
    queryUrl);
props.setProperty("javax.xml.registry.lifeCycleManagerURL",
    publishUrl); 

Next, the makeConnection method creates the connection, using the connection properties:

ConnectionFactory factory = ConnectionFactory.newInstance();
factory.setProperties(props); 
connection = factory.createConnection(); 

The executePublish method takes three arguments: a username, a password, and an endpoint. It begins by obtaining a RegistryService object, then a BusinessQueryManager object and a BusinessLifeCycleManager object, which enable it to perform queries and manage data:

rs = connection.getRegistryService();
blcm = rs.getBusinessLifeCycleManager();
bqm = rs.getBusinessQueryManager(); 

Because it needs password authentication in order to publish data, it then uses the username and password arguments to establish its security credentials:

PasswordAuthentication passwdAuth = 
    new PasswordAuthentication(username, 
        password.toCharArray());
Set creds = new HashSet();
creds.add(passwdAuth);
connection.setCredentials(creds); 

It then creates an Organization object with the name "JAXRPCCoffeeDistributor," then a User object that will serve as the primary contact. It gets the data from the resource bundle instead of hardcoding it as strings, but otherwise this code is almost identical to that shown in the JAXR chapter.

ResourceBundle bundle =
    ResourceBundle.getBundle("jaxrpc.registry.CoffeeRegistry");

// Create organization name and description 
Organization org =
    blcm.createOrganization(bundle.getString("org.name"));
InternationalString s = 
    blcm.createInternationalString
    (bundle.getString("org.description"));
org.setDescription(s);

// Create primary contact, set name 
User primaryContact = blcm.createUser();
PersonName pName =
    blcm.createPersonName(bundle.getString("person.name"));
primaryContact.setPersonName(pName); 

It adds a telephone number and email address for the user, then makes the user the primary contact:

org.setPrimaryContact(primaryContact); 

It gives JAXRPCCoffeeDistributor a classification using the North American Industry Classification System (NAICS). In this case it uses the classification "Other Grocery and Related Products Wholesalers".

Classification classification = (Classification)
    blcm.createClassification(cScheme,
        bundle.getString("classification.name"), 
        bundle.getString("classification.value"));
Collection classifications = new ArrayList();
classifications.add(classification);
org.addClassifications(classifications); 

Next, it adds the JAX-RPC service, called "JAXRPCCoffee Service," and its service binding. The access URI for the service binding contains the endpoint URL that remote clients will use to contact our service:

http://localhost:80/SupplierService/SupplierService 

JAXR validates each URI, so an exception is thrown if the service was not deployed before you ran this program.

Collection services = new ArrayList();
Service service =
    blcm.createService(bundle.getString("service.name"));
InternationalString is = 
    blcm.createInternationalString
    (bundle.getString("service.description"));
service.setDescription(is);

// Create service bindings
Collection serviceBindings = new ArrayList();
ServiceBinding binding = blcm.createServiceBinding();
is = blcm.createInternationalString
    (bundle.getString("service.binding"));
binding.setDescription(is);
try {
    binding.setAccessURI(endpoint); 
} catch (JAXRException je) {
    throw new JAXRException("Error: Publishing this " + 
    "service in the registry has failed because " + 
    "the service has not been deployed on the application 
server.");
}
serviceBindings.add(binding);

// Add service bindings to service
service.addServiceBindings(serviceBindings);

// Add service to services, then add services to organization
services.add(service);
org.addServices(services); 

Then it saves the organization to the registry:

Collection orgs = new ArrayList();
orgs.add(org);
BulkResponse response = blcm.saveOrganizations(orgs); 

The BulkResponse object returned by saveOrganizations includes the Key object containing the unique key value for the organization. The executePublish method first checks to make sure the saveOrganizations call succeeded.

If the call succeeded, the method extracts the value from the Key object and displays it:

Collection keys = response.getCollection();
Iterator keyIter = keys.iterator();
if (keyIter.hasNext()) {
    javax.xml.registry.infomodel.Key orgKey =
        (javax.xml.registry.infomodel.Key) keyIter.next();
    id = orgKey.getId();
    System.out.println("Organization key is " + id);
} 

Finally, the method returns the string id so that the OrgPublisher program can save it in a file for use by the OrgRemover program.

Deleting the Service From the Registry

The OrgRemover program deletes the service from the Registry Server immediately before the service is removed. Like the OrgPublisher program, the OrgRemover program starts by fetching values from the CoffeeRegistry.properties file. One these values, keyFile, is the name of the file that contains the key that uniquely identifies the service. OrgPublisher reads the key from the file, connects to the Registry Server by invoking makeConnection, and then deletes the service from the registry by calling executeRemove. Here is the source code for the OrgRemover program:

package jaxrpc.registry;

import java.util.ResourceBundle;
import javax.xml.registry.*; 
import javax.xml.registry.infomodel.Key;
import java.io.*;

public class OrgRemover {

    Connection connection = null;

    public static void main(String[] args) {

        String keyStr = null;

        ResourceBundle registryBundle = 
            ResourceBundle.getBundle
            ("jaxrpc.registry.CoffeeRegistry");

        String queryURL = 
            registryBundle.getString("query.url");
        String publishURL =
            registryBundle.getString("publish.url");
        String username =
            registryBundle.getString("registry.username");
        String password =
            registryBundle.getString("registry.password");
        String keyFile = registryBundle.getString("key.file");

        try {
            FileReader in = new FileReader(keyFile);
            char[] buf = new char[512];
            while (in.read(buf, 0, 512) >= 0) { }
            in.close();
            keyStr = new String(buf).trim();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

        JAXRRemover remover = new JAXRRemover();
        remover.makeConnection(queryURL, publishURL);
        javax.xml.registry.infomodel.Key modelKey = null;
        modelKey = remover.createOrgKey(keyStr);
        remover.executeRemove(modelKey, username, password);
    }
} 

Instantiated by the OrgRemover program, the JAXRRemover class contains the makeConnection, createOrgKey, and executeRemove methods. It is almost identical to the sample program JAXRDelete.java, which is described in Removing Data from the Registry.

The makeConnection method is identical to the JAXRPublisher method of the same name.

The createOrgKey method is a utility method that takes one argument, the string value extracted from the key file. It obtains the RegistryService object and the BusinessLifeCycleManager object, then creates a Key object from the string value.

The executeRemove method takes three arguments: a username, a password, and the Key object returned by the createOrgKey method. It uses the username and password arguments to establish its security credentials with the Registry Server, just as the executePublish method does.

The method then wraps the Key object in a Collection and uses the BusinessLifeCycleManager object's deleteOrganizations method to delete the organization.

Collection keys = new ArrayList();
keys.add(key);
BulkResponse response = blcm.deleteOrganizations(keys); 

The deleteOrganizations method returns the keys of the organizations it deleted, so the executeRemove method then verifies that the correct operation was performed and displays the key for the deleted organization.

Collection retKeys = response.getCollection();
Iterator keyIter = retKeys.iterator();
javax.xml.registry.infomodel.Key orgKey = null; 
if (keyIter.hasNext()) { 
    orgKey = 
        (javax.xml.registry.infomodel.Key) keyIter.next();
    id = orgKey.getId();
    System.out.println("Organization key was " + id);
} 
Divider
FAQ
History
PreviousHomeNext Search
Feedback
Divider

All of the material in The J2EE Tutorial for the Sun ONE Platform is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.