How to Migrate CORBA Applications to Web Services WHITE PAPER www.roguewave.com

Transcription

How to Migrate CORBA Applications to Web Services WHITE PAPER www.roguewave.com
WHITE PAPER
How to Migrate CORBA Applications to
Web Services
www.roguewave.com
WHITE PAPER
Abstract
This whitepaper describes the benefits of successfully and efficiently migrating CORBA applications to
Web services, using Rogue Wave’s HydraExpress.
Introduction
CORBA was a very widely used technology for implementing distributed systems and client-server
architectures. It could be argued that CORBA helped pave the way for today’s Service Oriented
Architectures. However, many applications where CORBA was used have removed this technology or
are looking to do so for many reasons. Among these reasons are that CORBA was often not interoperable
between different ORB vendors, the emergence of SOA technologies including Web services, and the
maintenance cost of commercial CORBA products.
Many architects have chosen to replace CORBA technologies with Web service technologies because
Web services were intentionally designed not to suffer from the same pitfalls that CORBA faced. Web
services provide an easy path to SOA to the point that the two technologies are almost always mentioned
together. WS standards were specifically designed such that different vendors would be compatible with
each other, so that a client and a service need not be built using the same product stack. Adding in the
fact that commercial WS stacks are usually much cheaper than CORBA stacks, and you have some very
compelling reasons to look at Web services to replace your CORBA infrastructure.
With so many reasons to replace CORBA with Web services, the question becomes how does one go
about doing this?
This paper illustrates the steps required to move a sample CORBA service and client to Web services
utilizing HydraExpress.
The getCustomersInRegionMethod
The sample method exposed in CORBA is getCustomersInRegion. This method takes an area code as an
argument and then returns a string containing a list of all the customers in that area code. This method is
part of our CustomerDB service. In this example, CustomerDB only has the one method.
C++ Declaration for the Business Logic Implementation
Typically, the messaging infrastructure and the underlying implementation logic are kept in separate
classes. In the example below, the actual business logic resides in a class named CustomerDBInterface.
«2»
www.roguewave.com
WHITE PAPER
Below is the relevant part of the class declaration:
class CustomerDBInterface
{
public:
CustomerDBInterface();
std::string getCustomersInRegion(std::string areaCode);
IDL
The IDL for the CustomerDB service is very simple because there is only the one method, and no types
have been defined:
CustomerDB.idl:
interface customerDB {
string getAllCustomersInRegion(in string areaCode);
};
CORBA
CORBA utilities such as idl2cpp are usually used to generate the server side bindings for converting the
classes and methods defined in the idl.
An example declaration for the method in the CustomerDB.idl might be:
// The following operations need to be implemented
virtual char* getAllCustomersInRegion(const char* _areaCode) = 0;
The class would then be extended to override the getAllCustomersInRegion method and create the
CORBA service. The logic used to perform the actual business logic will remain the same as we move to
Web services.
Migrating the CustomerDB CORBA Service to a Web Service
Migrating from the CORBA service to a web service starts with creating a WSDL file to describe the
new web service. The IDL file contains the types and methods that the new service needs to implement.
Each type definition, interface definition, and method definition in the IDL is mapped to its WSDL
representation. Because this example doesn’t contain any type definitions, it goes straight to the
customerDB interface.
Type definitions:
In this example, no complex types are defined. The argument and response are both strings which
are a native type for both CORBA and WSDL. In an example with complex types, one would
need to define corresponding types in XML schema for each complex type in the IDL.
«3»
www.roguewave.com
WHITE PAPER
Message definitions:
In WSDL, there are a number of different messaging patterns that can be used. This example
shows a synchronous call so it will need an “in” message representing the method arguments,
and an “out” message representing the return value. For customerDB, both the input (or request)
message and response (output) contain one part that is a string.
<message name=”getAllCustomersInRegionRequest”>
<part name=”areaCode” type=”xs:string”/>
</message>
<message name=”getAllCustomersInRegionResponse”>
<part name=”customers” type=”xs:string”/>
</message>
Port definitions:
A port in WSDL is a collection of operations available at the specified port. A single WSDL file
can contain multiple services. Each service binds to one or more ports. In this example, there is
only one port with one operation.
<portType name=”CustomerDB”>
<operation name=”getAllCustomersInRegion”>
<input message=”y:getAllCustomersInRegionRequest”/>
<output message=”y:getAllCustomersInRegionResponse”/>
</operation>
</portType>
Bindings:
Until now, everything that’s been done looks quite a bit like IDL. However, WSDL needs to
describe more than what an IDL must. Besides the types and operations, a WSDL needs to
describe some web service details about how the messages going to and from the service will be
encoding. This is done with bindings.
Each port and its operations must be assigned a binding style and transport. It may seem
complicated, but there are only a few to select from. Any good WSDL reference will give lots of
detail on what the binding style and corresponding transport mean. The following example uses
rpc for simplicity. Because some industry Web services systems only accept the document-literal
encoding style, if ever in doubt, it’s recommended that document-literal be used.
<binding name=”CustomerDB” type=”y:CustomerDB”>
<soap:binding style=”rpc” transport=”http://schemas.xmlsoap.org/soap/
http”/>
<operation name=”getAllCustomersInRegion”>
<input>
<soap:body use=”encoded” encodingStyle=”soap-enc”/>
</input>
«4»
www.roguewave.com
WHITE PAPER
<output>
<soap:body use=”encoded” encodingStyle=”soap-enc”/>
</output>
</operation>
</binding>
Service definition:
Finally, we define which ports our service will contain and where that service will live.
<service name=”CustomerDBService”>
<port name=”CustomerDB” binding=”y:CustomerDB”>
<soap:address location=”http://localhost:8090/customerDB/CustomerDB/”/>
</port>
</service>
Generating the Service Using HydraExpress
Now that all the pieces of the WSDL are put together, it’s time to turn that WSDL into a service using
HydraExpress. HydraExpress generates the client and server bindings for implementing this service in
C+. The command for doing this with HydraExpress is:
rwsfgen –projectname CustomerDB customerDB.wsdl
Implementing the Service
HydraExpress generates the bindings for all the types as well as all the skeletons for taking a web service
request and routing that to a C++ method. The logic goes in the CustomerDBImp.cpp file. The method
generated for handling the getCustomersInRegion operation is:
std::string CutomerDBImp::getAllCustomersInRegion(LEIF::CallInfo& callInfo,
const std::string& areaCode_in)
{
//add your logic here
…
The simplest way to call the business logic (though not the best for performance) is to instantiate the
CustomerDBInterface object and call the getCustomersInRegion method on it. As such, the above
skeleton becomes:
std::string CutomerDBImp::getAllCustomersInRegion(LEIF::CallInfo& callInfo, const
std::string& areaCode_in)
{
CustomerDBInterface db;
return db.getCustomersInAreaCode(areaCode_in);
}
«5»
www.roguewave.com
WHITE PAPER
Generally one wouldn’t instantiate the business logic object every time they received a web services
request, but it is done here for simplicity. There are several ways to instantiate this object only once for
better performance.
The last step is to build and deploy the HydraExpress service using the build and deploy targets in the
generated makefile. The service is deployed, ready to run and now can be consumed by web services
clients in any language.
Other Considerations
The previous example illustrates replacing a very simplistic CORBA interface with a very simplistic
Web services interface. Of course, things are rarely this simple in real-life implementations of enterprise
software.
Complicating factors in CORBA include using the naming service, transactions, and use of opaque
objects. The good news is that there are ways to duplicate these CORBA features using Web services
technologies. In addition to this, there are many times when HTTP is not an appropriate messaging
transport. HydraExpress allows the use of other transports and even enables you to write your own so
that you get to use the transport that makes sense for the use case.
Summary
Migrating a system from CORBA to Web services is not a daunting task thanks to HydraExpress. The
IDL in the CORBA system can be used to create a WSDL file and generate the necessary framework.
Next, take the SAME business logic that was working in CORBA and use it in the new web service. This
makes it unnecessary to have to re-write the most important part of the enterprise application, the business
logic. Preserving this investment saves both the time required to re-implement your application, as well
as addressing any associated bugs. HydraExpress can help organizations evolve existing applications
towards a SOA without sacrificing the business logic code that already works.
USA 1-800-487-3217
FRANCE +33 (0)1 30 09 78 78
GERMANY +49 (0)6103 59340
UK +44 8450 549950
www.roguewave.com
Copyright © 2008, Rogue Wave Software, Inc. All Rights Reserved. Rogue Wave
and HydraSDO are registered trademarks of Rogue Wave Software, Inc. All other
trademarks are the property of their respective owners.