Home Image graphic
ProductsResourcesDownloadWhat's NewAboutSupportHome

Distributed Technology Library White Papers Power Parnters White Papers

Wrapping Legacy Applications: A Distributed Computing Solution

This paper discusses the issues of wrapping legacy applications using distributed objects. Wrapping applications is a method of encapsulation that provides clients with well-known interfaces for accessing server applications or components. The principal advantage is that, behind the interface, the client need not know the exact implementation. The developer could have implemented the method as a simple variable update, as an inter-process socket invocation, or even as a no-op. The class implementer provides a protocol via the class header, that explains how to use the class without tying the client to any particular implementation. The class can thus be reimplemented in numerous ways without impacting the client.

C++ is an ideal language for implementing encapsulation. A C++ class has a well-known public interface that clients use to access the services the class provides. CORBA objects have additional benefits over regular C++ objects because CORBA is both programming language and platform independent. With CORBA, a developer can feel comfortable that objects with interfaces defined in IDL will be accessible to an ever-increasing set of users - programmers who are developing on multiple platforms and operating systems, and who are using several programming languages. Additionally, CORBA objects, though accessed through a local surrogate object, may exist anywhere on the network, allowing administrators to place them strategically across the network, leveraging additional CPUs.

Three Scenarios

We now look at three examples that demonstrate the benefits of using CORBA distributed object technology for wrapping legacy applications. The first example deals with extending a standalone simulation library by providing a well-defined, distributed interface accessible by other remote applications. The second deals with migrating a database application from a vendor-specific solution for accessing and updating the database to a more flexible, non-proprietary solution. The final example demonstrates how a standalone application can be converted into an application with distributed-enabled components.

I. Wrapping a Simulation Library

Here, we deal with a library that provides a framework for building simulations in C++. Developers use the library for building simulation-enabled objects of different types, populating the simulation with objects based on programmatic rules. Developers must initialize and start the simulation engine, then populate it under various conditions, followed by compiling the application, linking in the simulation library, and running the application. The user interacts with the simulation via a GUI, starting and stopping it, adding and removing entities, and querying the engine for various details, such as the number of active simulation entities.

Without a CORBA interface, developers can use the simulation framework for building simple, stand-alone simulation applications - but they cannot realize more complex, efficient uses. While the GUI provides an interface for humans to access and interrogate the simulation, other applications cannot access the simulation programmatically. Any developer interested in building, running and analyzing a simulation must run a local version of the simulation application. Moreover, simulations often take a certain amount of up-time in order to reach the steady state necessary to convey useful information, and each developer must invest this ramp-up time to gain any meaningful benefits. Simulations consume many computer cycles and need powerful machines to handle their loads. Migrating the simulation between machines at runtime is often necessary to run the simulation effectively as machine loads change.

While the simulation framework does not provide this capability, a CORBA interface that encapsulates the simulation engine can solve most of these problems. Just as GUIs provide a graphical interface for interacting with applications, CORBA IDL provides the programmatic interface. IDL allows remote applications to "see" the simulation via a set of well-defined CORBA interfaces, and allows multiple sites to interact with the simulation simultaneously. Developers can port a simulation library to a high-end platform to provide an efficient, powerful system for running the application. Indeed, clients of the simulation do not need to know where the actual simulation is running, as long as they have an object reference to the simulation object that wraps the simulation application.

Adding a simple CORBA interface to the simulation application opens up several other issues that must be addressed. Among them:

Should all users have privileges to start and stop the simulation?

Is there a limit to the number of entities that can enter the simulation?

Should some clients only have read access to the simulation?

CORBA does not address these domain-specific questions. The extent to which developers address them depends on the robustness and usefulness of the simulation.

II. Wrapping a Database Application

The next example deals with a database client application that accesses and updates personnel information on a database server. Database clients access the data server via a database API that supports SQL. A GUI application triggers the database with such requests as adding employees and assigning them to departments and supervisors. Locally, the personnel application treats all of the types maintained in the database as classes, which map into corresponding tables while maintaining special database tables to store relationships between classes. Although this is not a complicated mapping, developers must be careful to maintain synchronization between application classes and database tables.

One benefit provided by CORBA is encapsulating the back-end database structure from the client code. Companies migrating from one database product to another will find it inconvenient to redevelop client code after each migration. Providing client access to the database through an interface that stays constant, even when the back-end system changes, eliminates this need for redesign.

This IDL hierarchy provides a flexible design to support migration to a different back-end database without affecting the client code:

The developer codes client applications to the interface defined in AbstractDBInterface. Initially, the middleware developer implements XyzRDBInterface and ties the implementation directly to the legacy application. This arrangement gives the client, via the AbstractDBInterface, the same functionality with respect to accessing the database as using straight SQL. Simultaneously, or after implementing XyzRDBInterface, the middleware developer can implement NewDBInterface using any database technology. Since the interface of both XyzRDBInterface and NewDBInterface matches AbstractDBInterface, a client of AbstractDBInterface does not care whether an object of type XyzRDBInterface or NewDBInterface is loaded in the system.

From the client perspective, the interface is constant. Because the developer migrates the implementation, not the interface, he/she need only update the client code once to match the interface of AbstractDBInterface. An administrator can switch from a server object of type XyzRDBInterface to NewDBInterface without impacting the client.

To create an object-oriented CORBA interface for the client, the server developer must analyze the current system and determine appropriate methods in which to map the SQL commands contained within the client environment. It is advisable to remove all transactional code contained within the client code and migrate that to the server. This transactional code represents the established business rules and logic of the company - rules requiring, for example, that all employees with a certain set of qualifications earn a salary within a set range. Such business logic represents a higher level of intelligence that the database cannot fully capture.

Classic client/server database systems place transactional logic through a combination of transactional database calls on the client and stored procedures on the server. This is an inelegant solution because, in essence, the knowledge of the business is spread across both the client and the server. Adding new client applications to this system is difficult because the logic built into the initial client application must be duplicated in each new client.

The ideal solution is to extract the business logic from the client and provide the client with a CORBA interface to the database. The CORBA implementation encapsulates the database, maintaining the business logic as a layer on top of the database and outside the scope of any particular client. In addition, the CORBA implementation can asynchronously notify registered clients of important events, for example, when it determines a critical shortage of office space, it notifies the appropriate client. A CORBA-based middle tier becomes a highly flexible and scalable solution.

III. Converting C++ into a Distributed Application

The third example deals with converting a standalone home accounting system to a distributed application. This example differs from the others in that we are not interested in providing a CORBA interface to a back-end system, but rather in reworking an application to take advantage of distributed components internally.

The initial application provides the traditional capabilities for managing personal finances, enabling a user to add and manage bank, savings, and credit card accounts via a GUI. The application also provides account reconciliation, report generation, and such financial tools as amortization scheduling for mortgages and retirement analysis.

Adding distributed components to this application greatly extends its functionality within an office environment. A distributed object model allows objects like report generators to be run on the most powerful computer available on the network. From an application point of view, distributed components appear as local objects, yet take advantage of computing resources across the network.

Developers can add robustness without increasing the complexity for your programming task. Although it is possible to extend the functionality using threads, threads do not scale well because they are limited to running on a single machine and can only take advantage of multiple CPUs on that machine.

After determining the relevancy of using distributed components, developers should target candidate classes for adding distributed capability. While, logically, you could rewrite all classes within the system as distributed objects, this is overkill. Practically speaking, developers should target those classes that perform time-consuming, complex operations such as the report generator and amortization scheduler. Making heavily used classes like these distributed objects frees up system resources.

The next step is to define the interface for this component. In general, this task is quite simple: all public methods are good choices as interface methods for the distributed version of this class. After defining the interface, developers must define the behavior of all of the methods of this class. The original version of the report generator, for example, has an access method for initializing the generator with information on which to report and a method to start report generation.

This last method is synchronous and does not return until it generates the report in its entirety. A better design provides a method that returns immediately after informing the report generator to commence with the generation, then has the report generator notify the client of the report's completion. This asynchronous method of interacting with the report generator allows the client application to continue processing in parallel with the report generator. The client is free to process new events without freezing the display and can even start up a new report generation session.

A strict CORBA-based solution for adding distributed components to the accounting application requires the development of an IDL interface that contains operations for the different services provided by the report generator. Here, the CORBA object simply calls the corresponding report generator method from within each CORBA method.

A simpler alternative, one less intrusive on the overall system design, converts the report generator class into a PowerBroker Extended C++ class. PowerBroker Extended C++ classes look similar to regular C++ classes, but add several key words for facilitating distributed method invocations. Converting a regular C++ class into a PowerBroker Extended C++ class requires much less work than writing a full-scale CORBA object that redirects all methods to the original object. Moreover, in using PowerBroker Extended C++ classes, PowerBroker generates an asynchronous method for every method tagged as a distributed member function within the Extended C++ class. With respect to the report generator, for example, no extra coding on the server is needed to provide notification of completion. Under a strict CORBA implementation, extra coding is necessary to propagate the notification back to the client.

Summary

These three scenarios demonstrate the benefits of using distributed object technology for wrapping and extending legacy applications. CORBA provides a straightforward mechanism for hooking into legacy systems, providing desktop access, and extending the life of valuable applications by treating them as reusable components. Using CORBA along with an effective design can simplify the migration of legacy applications and limit the coding impact on client-side applications. CORBA does not solve every problem facing software developers, but it does provide an elegant solution for reusing, migrating and reengineering components that take advantage of distributed computing.

Back to TopBack to Top

© Copyright 1997, Expersoft Corporation. All rights reserved.
Expersoft is a registered trademark of, and PowerBroker is a trademark of Expersoft Corporation.
Java is a trademark of Sun Microsystems, Inc.