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.