Download FAQ History |  | API Search Feedback

> ## JAX-RPC Distributor Service

> The Coffee Break server is also a client-- it makes remote calls on the JAX-RPC distributor service. The service code consists of the service interface, service implementation class, and several JavaBeans components that are used for method parameters and return types.

> ### Service Interface

> The service interface, `SupplierIF`, defines the methods that can be called by remote clients. The parameters and return types of these methods are JavaBeans components:

> - `AddressBean`--shipping information for customer
> - `ConfirmationBean`--order id and ship date
> - `CustomerBean`--customer contact information
> - `LineItemBean`--order item
> - `OrderBean`--order id, customer, address, list of line items, total price
> - `PriceItemBean`--price list entry (coffee name and wholesale price)
> - `PriceListBean`--price list

> Because these components are shared by other programs, their source code resides in the `<``INSTALL``>/jwstutorial12/examples/cb/common/src` directory. The source code for the `SupplierIF` interface, which follows, resides in the `<``INSTALL``>/jwstutorial12/examples/cb/jaxrpc/src` directory.

>     package com.sun.cb;

>     import java.rmi.Remote;
>     import java.rmi.RemoteException;

>     public interface SupplierIF extends Remote {

>         public ConfirmationBean placeOrder(OrderBean order)
>             throws RemoteException;
>         public PriceListBean getPriceList() throws RemoteException;
>     }

> ### Service Implementation

> The `SupplierImpl` class implements the `placeOrder` and `getPriceList` methods, which are defined by the `SupplierIF` interface. So that you can focus on the code related to JAX-RPC, these methods are short and simplistic. In a real-world application, these methods would access databases and interact with other services, such as shipping, accounting, and inventory.

> The `placeOrder` method 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 `cb/common` subdirectory.) 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;
>     }

> 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 getting the prices from the `SupplierPrices.properties` file. Here are the `getPriceList` and `loadPrices` methods:

>     public PriceListBean getPriceList() {

>        PriceListBean priceList = loadPrices();
>        return priceList;
>     }

>     private PriceListBean loadPrices() {

>        String propsName = "com.sun.cb.SupplierPrices";
>        Date today = new Date();
>        Date endDate = DateHelper.addDays(today, 30);

>        PriceItemBean[] priceItems =
>            PriceLoader.loadItems(propsName);
>        PriceListBean priceList =
>            new PriceListBean(today, endDate, priceItems);

>        return priceList;
>     }

> ### Publishing the Service in the Registry

> Because we want customers to find our service, we will publish it in a registry. The programs that publish and remove our service are called `OrgPublisher` and `OrgRemover`. These programs are not part of the service's Web application. They are stand-alone programs that are run by the `ant` `set-up-service` command. (See Building and Installing the JAX-RPC Service.) Immediately after the service is installed, it's published in the registry. And in like manner, right before the service is removed, it's removed from the registry.

> 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 com.sun.cb;

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

>     public class OrgPublisher {

>         public static void main(String[] args) {

>             ResourceBundle registryBundle =
>                ResourceBundle.getBundle
>                ("com.sun.cb.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. This code is almost identical to the code in the JAXR examples.

>     ResourceBundle bundle =
>         ResourceBundle.getBundle("com.sun.cb.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:8080/jaxrpc-coffee-supplier/jaxrpc/SupplierIF

> JAXR validates each URI, so an exception is thrown if the service was not installed 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 installed on Tomcat.");
>     }
>     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 com.sun.cb;

>     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
>                 ("com.sun.cb.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);
>     }

Download FAQ History |  | API Search Feedback

All of the material in The Java(TM) Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.