Title: | An Architecture for Web Services. |
Subject(s): | |
Source: | |
Author(s): | |
Abstract: | Discusses the Common Object Request Broker Architecture (CORBA) developed by the Object Management Group which is the standard infrastructure for distributed-object systems. Integration of the JavaBean proxy into a Java application; Use of the Web service at run time; Conclusions. |
AN: | 2783693 |
ISSN: | 1044-789X |
Database: | Business Source Elite |
Section: INTERNET PROGRAMMING
An established vision in the distributed-object community involves publishing distributed-object services on the Web that may be reused by application developers to rapidly create new Java applets or applications. In this article, I'll discuss an architecture that can turn this vision into reality by taking full advantage of the synergy between web and distributed-object systems. This architecture also facilitates both the publication of distributed-object services on the Web, as well as the subsequent reuse of these web services by application developers to rapidly and visually create new applications. (In the context of this article, I define a "server" as a distributed object, a "service" as a method on a particular distributed object, and a "web service" as a service that may be accessed and reused using only web and nondistributed-object technologies.) Furthermore, this architecture's implementation is based on well-established, freely available, and proven technologies and development paradigms.
Using this architecture, you can use web browsers to browse servers and the services they provide, select the service you wish to use, and download a proxy in the form of a JavaBean. This proxy encapsulates server location, protocol, licensing, security, and all other details associated with requesting a remote service. It may then be integrated into applications either visually using a JavaBean Integrated Development Environment (IDE), or at the software level using any Java IDE. The application can then use the selected service by simply interacting with the proxy. The technologies and frameworks used to implement this architecture and illustrate this approach include Sun JDK 1.1.7 (http:// www.java.sun.com/), Inprise VisiBroker 3.3 CORBA implementation (http://www .inprise.com/), JRun 2.2 (http://www .livesoftware.com/), and the CORBA Beans 2.4 framework from the Technical Resource Connection (http://www.trcinc .com/corbabeans/), An implementation of this architecture and interactive demo is available from DDJ (see "Resource Center," page 5) and at http://www.trcinc .com/corbabeans/.
An Architecture for Web Services
The Common Object Request Broker Architecture (CORBA), developed by the Object Management Group (OMG) (http:// www.omg.org/), is the standard infrastructure for distributed-object systems. Proven in reliability, scalability, and extensibility, it offers many architectural and implementation advantages that can be leveraged to rapidly create a distributed-object system. CORBA makes it possible for you to focus the development effort on added business value, and offers implementation and location transparency. This allows distributed objects to be implemented in different languages and run on multiple operating systems, hardware, or network nodes.
The CORBA Naming Service provides services for CORBA clients to locate CORBA servers, and is organized in a tree-based directory structure. The root of the tree, the root Naming Context, may contain either references to servers, or subNaming Contexts. Clients can drill down through subNaming Contexts to locate the server of interest. They can then obtain an object reference that facilitates the location of the associated server. This is analogous to the Yahoo tree-based search engine at http://www.yahoo.com/, except in this case, the servers displayed are not web servers, but CORBA servers. The interface of a CORBA server is defined in an implementation language-neutral way using Interface Definition Language (IDL). For example, Listing One defines the IDL for a simple CORBA Inventory Server, and illustrates the concepts I discuss here. The CORBA Interface Repository is an infrastructure service that lets CORBA clients determine at run time the IDL interface of a CORBA server. Clients can use this interface information to dynamically form and execute requests on the associated server using the CORBA Dynamic Invocation Interface (DID, communicating with the CORBA server using the standard Internet InterORB Protocol (IIOP). This CORBA functionality makes it particularly well suited to implementing web services over an intranet or the Internet.
Figure 1 details the architecture that facilitates the publication and reuse of CORBA services over the web. To illustrate the roles, responsibilities, and collaborations of the components in this architecture, I'll walk through three key use-case scenarios.
A server developer can publish the services provided by a CORBA server as web services by:
1. Registering the CORBA server with the CORBA Naming Service.
2. Loading the CORBA Interface Repository with the IDL of the CORBA server being published.
An application developer can reuse a web service by integrating it with an application by:
1. Selecting a server.
2. Selecting a service provided by the selected server.
3. Downloading a JavaBean proxy for the selected service.
4. Integrating the proxy with the application being developed.
The application developer can browse and select a server using a web browser:
1. You request the URL for the Naming Service Gateway Servlet using the browser.
2. The servlet receives this request via the web server and responds by contacting the CORBA Naming Service to get a "snapshot" of the elements in the root Naming Context.
3. The servlet reformats this information into HTML and returns it via the web server to the web browser for display.
4. The hyperlinked elements displayed each represent either a CORBA server or subNaming Context contained by the root Naming Context.
5. If you then select the hyperlink for a subNaming Context, the display changes to show the elements of the subNaming Context in the same way as for the root Naming Context explained previously.
Using this process, you can drill down to the Naming Context containing the CORBA server that provides the services of interest. Selecting the hyperlinked element for the CORBA server results in a request to the Naming Service Gateway Servlet for the interface of the selected server. The servlet would get this information from the CORBA Interface Repository via the CORBA server, format it into HTML, and return it via the web server to the web browser for display. For example, selecting the Inventory Server with the IDL shown in listing One, results in a display as in Figure 2. This display shows the hyperlinked signatures for each of the services provided by the selected Inventory Server.
You can then select a service by clicking on the hyperlink corresponding to that service. The Naming Service Gateway Servlet responds to this request by first creating a JavaBean proxy to access the requested service, then serializing this bean and returning it via the web server to the web browser. At this point, the web browser prompts you to indicate a file to which you would like to save the serialized bean. After saving the bean, it may be integrated into a Java application to access the associated service. The configuration information for the bean is all stored in the downloaded bean file. This presents a significant advantage over configuring the bean using software. For example, if the location or interface of the server associated with the proxy bean changed over the lifetime of the system, the application developer could simply download a new serialized bean that reflects the changes. No software would need to be recompiled for the application to accommodate these changes.
Integrating the JavaBean Proxy into a Java Application
The bean proxy can be visually integrated into a Java application using a JavaBean IDE, as illustrated in Figure 3, or at the software level using any Java IDE. To briefly illustrate the interaction between the application and proxy bean, integration at the software level is illustrated in Listing Two. In this code snippet, the DynamicRequest proxy bean for the getItems service on the inventory server is first instantiated from the serialized JavaBean file downloaded in the previous step. The result of the instantiation is a completely configured proxy bean. The input arguments for the request are then set, and the request is invoked. Finally, the results of the request are obtained through the JaxaBean-compliant interface of the DynamicRequest proxy bean. For more information on the DynamicRequest proxy and supporting framework, see my article "A CORBA Bean Framework" (DDJ, November 1998).
Using the Web Service at Run Time
The proxy bean collaborates with the application and web service at run time, as illustrated in Figure 4. After the proxy bean is instantiated, its input arguments may be set. The typed values of these arguments are cached by the proxy bean. When the request is invoked on the proxy bean, it contacts a server locator service, in this case the CORBA Naming Service, to get an object reference that allows it to locate the CORBA server providing the service it is associated with. This server location step is only required the first time the DynamicRequest proxy bean is invoked. It then builds a dynamic request using DII according to the signature of the service with which it is associated, in this case the getItems service, and the values of the input arguments. The proxy bean then invokes the DII request, resulting in an interaction between the proxy and the CORBA server, in this case the Inventory Server. This interaction may occur over either an intranet or the Internet via IIOP. When the request completes, the proxy bean extracts the output arguments and results of the request and caches them in a form that may be easily accessed via its JavaBean-compliant interface. The proxy bean then generates a new JavaBean event and publishes this event to all its registered listeners to notify them that the request is complete. These listeners may then get the results of the request from the proxy through its JavaBean interface. Note that all interactions between the proxy and servers are direct using IIOP, rather than via the web server. This approach leads to an architecture that is efficient, will successfully scale without the formation of a bottleneck at the web server, and is not "web-server-centric."
While the architecture I've presented here shows how to publish the services provided by CORBA servers as web services, the same architectural approach may be used to publish any type of server developed with a variety of middleware technologies and protocols. The proxy used in the architecture encapsulates and uses DII to interact with the CORBA server with which it was associated. DII is a client-driven interface, and interactions between the proxy and server are initiated by the proxy. To facilitate other communication paradigms (for example, true publish and subscribe) it is necessary to have server callbacks where an interaction between the proxy and server is initiated by the server. To facilitate this, a similar proxy could be developed based on the CORBA Dynamic Skeleton Interface (DSI).
This architecture offers significant advantages. It decouples application development and server development, allowing organizations to focus limited, expensive, distributed-object systems server development expertise on the development and publication of web services. On the other hand, more abundant and less expensive application-development expertise may be focused on reusing these web services. Since application developers don't require distributed-object systems expertise to reuse these web services, training may be focused on server developers, thereby minimizing training costs and delays required before a new project starts, as well as development costs and delays typically associated with a complex new technology.
Furthermore, this architecture also provides a layer of abstraction between the application and distributed-object middleware, effectively wrapping the middleware implementation and decoupling applications from it. The advantages of this layer of abstraction are twofold:
• It allows a particular middleware product to be changed during the lifetime of the system without any impact on the applications using it. This in turn allows to rapidly assimilate and leverage the benefits of distributed-object technology without having to first go through tedious and costly research and evaluations to make a selection from a vast range of middleware products.
• This layer of abstraction facilitates the integration of services provided by a variety of different types of servers into a unified web interface, allowing application developers to reuse these different types of services as web services all in the sane way.
Additionally, with the recent mainstream growth of distributed-object technology, particularly CORBA (for example, JavaIDL in JDK1.2), this approach addresses a growing need to lower the hurdles associated with new organizations and individuals assimilating this powerful technology and accelerating the realization of its benefits.
Conclusion
To date, the Web has underline tremendous growth and proven itself in a variety of information systems. On a separate tier, distributed-object systems, and in particular CORBA-based systems, have proven themselves in mission critical, enterprise, distributed-object systems. In this article, I've presented an architecture that leverages the strengths of both web and distributed-object systems to create web services that deliver the power of distributed-object systems and CORBA, yet may be accessed and reused with standard web tools and no CORBA expertise. This article illustrates one approach that paves the way for a new breed of sophisticated web services that are required to facilitate more powerful, automated, business services.
module StoreServer { struct ItemDescription { long year; string manufacturer; string model; string description; }; struct ItemRecord { ItemDescription description; double cost; }; typedef sequence<ItemRecord> ItemSequence; interface InventoryServer { ItemSequence getItems( in long year, in boolean includeBefore, in boolean includeAfter ); long inventory( in ItemDescription itemDescription ); }; }
// Instantiate proxy bean. DynamicRequest request = (DynamicRequest) Beans .instantiate ( null, "corbabeans. InventoryServer1_getItems" ); // Set dynamic request input arguments, request.setArgParamVal( "year", new Integer( 1997 ) ); request.setArgParamVal( "includeBefore". new Boolean( false ) ); request.setArgParamVal( "includeAfter", new Boolean( false ) ); // Invoke dynamic request. request. invoke (); // Get results from invoking dynamic request. int numItems = ((SequenceParameter) request .getReturnParam( "return" ) ) .getLength(); for( int i = 0; i < numItems; ++i ) { System, out. println ( request, getReturnParamVal ( "return[" + i + "] .description.manufacturer" ) ); }
DIAGRAM: Figure 1: An architecture for web services.
PHOTO (COLOR): Figure 2: Naming Service Gateway browser view.
DIAGRAM: Figure 3: Visual integration of the proxy bean and Java applications.
DIAGRAM: Figure 4: Using the web service at run time.
~~~~~~~~
By David Houlding
David is an infrastructure modeler for The Technical Resource Connection, and
can be contacted at david.houlding@trcinc.com.