Better Open Source Enterprise C++ Web Services

4,527 views

Published on

In this webinar/presentation presented on November 10, 2009, Nandika Jayawardana explores the capabilities of the WSO2 Web Services Framework for C++ (WSO2 WSF/C++) to develop and deploy Web services in C++.

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
4,527
On SlideShare
0
From Embeds
0
Number of Embeds
692
Actions
Shares
0
Downloads
94
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Better Open Source Enterprise C++ Web Services

  1. 1. Better Open Source Enterprise C++ Web Services Introducing WSO2 Web Services Framework for C++ Nandika Jayawardana Product Manager nandika@wso2.com
  2. 2. Outline ● Introduction to WSF/C++ ● WSF/C++ Architecture ● Consuming and Providing Web services ➢ Client API ➢ Service API ● Working with Code Generation Tool ● Security in Web services ➢ HTTPS/SSL ➢ WS-security ● Handling attachments ● Deploying WSF/C++ ● Performance and feature comparisons ● Summary
  3. 3. Introduction to WSF/C++ ● All-in-one solution for the building and deploying of Web services in C++/C ● Designed for embedding within C or C++ software applications to enable Web services ● Utilizes many popular open source projects including Apache Axis2/C, Apache Rampart/C, Apache Sandesha2/C and Apache Savan/C ● Offers developers with a simple and comprehensive C++ API ● WSF/C++ has the same configurability and flexibility of Axis2/C
  4. 4. WSF/C++ Architecture
  5. 5. WSF/C++ Architecture
  6. 6. WSF/C++ Components
  7. 7. Consuming and Providing Web Services ● Two approaches to create and consume web services ➢ Code first ● Start with code and build the contract ( WSDL ) based on code ➢ Contract first ● Start with contract ( WSDL ) and develop clients and services ● WSF/C++ provides comprehensive client and service API's for code first approach ● Contract first approach is supported by the code generation tool
  8. 8. Client API ● ServiceClient class acts as the client API for WSF/C++ ● Options class provides methods to configure the client with various options. ● Steps in writing a client ➢ Initialize the environment ➢ Create an options class instance ➢ Set your options with options object ➢ Create a service client instance ➢ Create the XML payload using Axiom C++ ➢ Pass the payload to service client request or send method to invoke the service ➢ Process the received response
  9. 9. Example Client Environment::initialize("echo.log", AXIS2_LOG_LEVEL_TRACE); ServiceClient sc("http://localhost:9090/axis2/services/echo"); OMNamespace * ns = new OMNamespace("http://wso2.org/wsfcpp/services/echo", "ns1"); OMElement * payload = new OMElement(NULL,"echoIn", ns); OMElement * child = new OMElement(payload,"text", NULL); child->setText("Hello World!"); cout << endl << "Request: " << payload << endl; try { OMElement * response = sc.request(payload, ""); if (response) { cout << endl << "Response: " << response << endl; } } catch (WSFault & e) { if (sc.getLastSOAPFault()) { cout << endl << "Response: " << sc.getLastSOAPFault() << endl; } else { cout << endl << "Response: " << e << endl; } } delete payload;
  10. 10. Axiom C++ ● Provides a pull parser based API for handling XML in C++ ● Built on top of Axiom/C API ● Very convenient and easy API to handle XML ● Classes in Axiom/C++ include ➢ OMNode ➢ OMElement ➢ OMText ➢ OMAttribute ➢ OMNamespace ➢ OMDataHandler
  11. 11. Service API ● A service is deployed as a shared library contained within a directory with the same name as service ● A service descriptor named services.xml is used to configure the service ● All services are contained within the services folder in the WSF/C++ repository ● By default a service is loaded at the first service invocation ● ServiceSkeleton class defines the api interface for writing a service ● A service should extend from ServiceSkeleton class and implement the abstract methods defined in ServiceSkeleton class
  12. 12. WSF/C++ Repository
  13. 13. Service configuration ● services.xml <service name="echo"> <parameter name="ServiceClass" locked="xsd:false"> echo </parameter> <description> Echo Service </description> <operation name="echoString"> <messageReceiver class="wsf_cpp_msg_recv" /> <parameter name="wsamapping"> http://wso2.org/wsfcpp/services/echo </parameter> <parameter name="RESTMethod">POST</parameter> <parameter name="RESTLocation">echoString</parameter> </operation> </service>
  14. 14. Steps in implementing a service ● Extend from the ServiceSkeleton class ● Implement methods init(), invoke() and onFault() ● Define the service loading macro WSF_SERVICE_INIT(<class name>) ● Define methods corresponding to each of the service operations and implement the business logic. Make sure that these methods are mapped to service operations in your invoke method. ● Build the code into a shared library ● Copy and edit a services.xml to suit the service description ● Create a folder with the same name as service name and copy the created shared library and services.xml ● Copy newly created service to services folder under WSF/C++ repository
  15. 15. Example Service #include <ServiceSkeleton.h> using namespace wso2wsf; class Echo: public ServiceSkeleton { public: WSF_EXTERN WSF_CALL Echo(){}; OMElement* WSF_CALL invoke(OMElement *message, MessageContext *msgCtx); OMElement* WSF_CALL onFault(OMElement *message); void WSF_CALL init(){}; }; OMElement* Echo::invoke(OMElement *msg, MessageContext *msgCtx) { if(!msg) return NULL; OMNamespace *inputNamespace = msg->getNamespace(); OMNamespace *ns = NULL; if(inputNamespace) { ns = new OMNamespace(inputNamespace->getURI(), inputNamespace->getPrefix()); } OMElement *childEle = dynamic_cast<OMElement*>(msg->getFirstChild()); if(childEle) { std::string childtext = childEle->getText(); OMElement *echoEle = new OMElement(msg->getLocalname(), ns); OMElement *text = new OMElement("text"); echoEle->addChild(text); text->setText(childtext); return echoEle; }else { std::cout<<"Casting Failed"<<std::endl; } return NULL; }
  16. 16. Code Generation Tool ● WSF/C++ code generation tool is available in two forms ➢ As an eclipse plug-in wizard ➢ As a command line tool ● Codegen tool generates ➢ Client Stubs ➢ Service Skeletons ➢ Service descriptor (services.xml) ➢ Build script for Linux ➢ Visual Studio project files for windows ● Handles wsdl imports and Xml Schema imports and most Xml Schema constructs
  17. 17. Eclipse Codegen Plug-in Wizard
  18. 18. Eclipse Codegen Plug-in
  19. 19. Eclipse Codegen Plug-in
  20. 20. Command line code generation tool ● In the windows binary distribution, code generation tool is available in the <WSFCPP_HOME>bintoolscodegenwsdl2cpp directory ● In the WSF/C++ source distribution, the source code of the code generation tool and build scripts are available. ● Install maven2 and run the build scripts to build the code generation tool from source ➢ On windows use build_codegen.bat and copy_codegen.bat ➢ On Linux use build_codegen.sh script
  21. 21. Code Generation tool options ● -uri ← WSDL URI ● -ss ← Generate server side code ● -sd ← Generate service descriptor ● -u ← Unpack classes ● -uw ← Unwrapped mode ● -o ← Output directory ● -d ← Data binding options ( adb or none ) ● Examples WSDL2CPP.bat -uri calculator.wsdl -u -d adb -o calc WSDL2CPP.bat -uri calculator.wsdl -d none -o calc WSDL2CPP.bat -uri calculator.wsdl -u -d adb -ss -sd -o calc
  22. 22. Code Generated Client int main(int argc,char *argv[]) { Environment::initialize("calculator.log", AXIS2_LOG_LEVEL_TRACE); string endpointUri = "http://localhost:9090/axis2/services/Calculator"; string clientHome = AXIS2_GETENV("WSFCPP_HOME"); if(clientHome.empty()) cout<<"Please Set WSFCPP_HOME environment variable"<<endl; /** * Create a new calculator stub and invoke the methods */ CalculatorStub *stub = NULL; stub = new CalculatorStub(clientHome, endpointUri); int addResult = stub->add(10,10); cout<<"Calculation 10 + 10 = " <<addResult<<endl; int subResult = stub->sub(20,10); cout<<"Calculation 20 – 10 = "<<subResult<<endl; int divResult = stub->div(100,10); cout<<"Calculation 100/10, = "<<divResult<<endl; int mulResult = stub->mul(15,15); cout<<"Calculation 15*15 = "<<mulResult<<endl; delete stub; }
  23. 23. Code Generated Service #include "CalculatorSkeleton.h" int main( using namespace localhost_axis_calculator; int argc, char *argv[]) int CalculatorSkeleton::mul(wso2wsf::MessageContext *outCtx ,int _a,int _b) {{ Environment::initialize("calculator.log", AXIS2_LOG_LEVEL_TRACE); return _a*_b; } string endpointUri = "http://localhost:9090/axis2/services/Calculator"; string clientHome = AXIS2_GETENV("WSFCPP_HOME"); if(clientHome.empty()) int CalculatorSkeleton::div(wso2wsf::MessageContext *outCtx ,int _a0,int _b1) { cout<<"Please Set WSFCPP_HOME environment variable"<<endl; /** if(_b1 != 0) * Create a new calculator stub and invoke the methods { */ return _a0/_b1; CalculatorStub *stub = NULL; } stub = new CalculatorStub(clientHome, endpointUri); else int addResult = stub->add(10,10); { cout<<"Calculation 10 + 10 = " <<addResult<<endl; std::cout<<"Cannot divide by zero"; return 0; int subResult = stub->sub(20,10); } cout<<"Calculation 20 – 10 = "<<subResult<<endl; } int divResult = stub->div(100,10); int CalculatorSkeleton::sub(wso2wsf::MessageContext *outCtx ,int _a2,int _b3) cout<<"Calculation 100/10, = "<<divResult<<endl; { return _a2 - _b3; int mulResult = stub->mul(15,15); } cout<<"Calculation 15*15 = "<<mulResult<<endl; int CalculatorSkeleton::add(wso2wsf::MessageContext *outCtx ,int _a4,int _b5) delete stub; { } return _a4 + _b5; }
  24. 24. Security in Web services ● Important confidential data exchanged need to be secured ● Security is an essential aspect for any enterprise software deployment ● Achieve security properties ➢ Confidentiality ● Assurance that the message has not been read by anyone other than the intended reader ➢ Integrity ● The assurance that data is complete and accurate ➢ Non-repudiation ● Prevent denial of action ➢ Authentication ● The verification of a claimed identity
  25. 25. Transport Level Security ● Achieved by using HTTPS ● Provides confidentiality through encryption ● Provides integrity through digital signature ● Service authenticate to client via certificates ● Client can authenticate to the service via certificates / basic, digest authentication
  26. 26. Configuring HTTPS in WSF/C++ ● HTTPS is configured in the axis2.xml <transportReceiver name="https" class="axis2_http_receiver"> <parameter name="port" locked="false">6060</parameter> </transportReceiver> <transportSender name="https" class="axis2_http_sender"> <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> <parameter name="xml-declaration" insert="false"/> </transportSender> <parameter name="SERVER_CERT">/path/to/ca/certificate</parameter> <parameter name="KEY_FILE">/path/to/client/certificate/chain/file</parameter> <parameter name="SSL_PASSPHRASE">passphrase</parameter>
  27. 27. WS-Security with WSF/C++ ● WS-Security 1.0 and 1.1 ➢ Base security standards mean that messages can be protected using Encryption, Authentication and Signature ● WS-Trust and WS-SecureConversation ➢ Advanced security standards allow single-sign on, more efficient encryption and more secure deployment ● WS-Policy and WS-SecurityPolicy ➢ Enables using industry standard XML to configure security
  28. 28. Configuring Client Security ● Client security is configured by specifying the policy file to the client ● WSF/C++ provides number of callback interfaces such as PasswordCallback, AuthenticationProvider for handling user security parameters. ● When implementing these callback handlers, extend from these classes and implement the abstract methods ServiceClient sc(client_repo, end_point); sc.engageModule(AXIS2_MODULE_ADDRESSING); sc.engageModule("rampart") sc.setPolicy(new NeethiPolicy(client_repo + "/" + policy_file));
  29. 29. Configuring Service Security ● Service security is configured in the services.xml <service name="sec_echo"> <parameter name="ServiceClass" locked="xsd:false">sec_echo</parameter> <module ref="rampart"/> <operation name="echoString"> <parameter name="wsamapping">http://example.com/ws/2004/09/policy/Test/EchoRequest</parameter> </operation> <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsp:ExactlyOne> <wsp:All> ........................ <rampc:RampartConfig xmlns:rampc="http://ws.apache.org/rampart/c/policy"> <rampc:User>Bob</rampc:User> <rampc:EncryptionUser>b</rampc:EncryptionUser> <rampc:PasswordType>Digest</rampc:PasswordType> <rampc:PasswordCallbackClass>E:wso2-wsf-cpp-bin-2.1.0- win32sampleslibpwcb.dll</rampc:PasswordCallbackClass> <rampc:ReceiverCertificate>E:wso2-wsf-cpp-bin-2.1.0- win32samplessrccrampartc/data/keys/bhome/alice_cert.cert</rampc:ReceiverCertificate> <rampc:Certificate>E:wso2-wsf-cpp-bin-2.1.0- win32samplessrccrampartcdatakeysbhomebob_cert.cert</rampc:Certificate> <rampc:PrivateKey>E:wso2-wsf-cpp-bin-2.1.0- win32samplessrccrampartcdatakeysbhomebob_key.pem</rampc:PrivateKey> </rampc:RampartConfig> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </service>
  30. 30. Web Service attachments ● Attachments ➢ Video, Images, Documents, ... ● There are two ways to transfer binary data in SOAP ➢ By Value (Encoded text of data within the xml) ● base64 – 4/3x original size ● hex – 2x original size ➢ Reference ● pointer to outside the XML ● MTOM/XOP ➢ Standardised approach to transfer binary data ● With WSF/C++ you can do Base64, SwA and MTOM ➢ Attachment caching enables users to handle large attachments with constant memory
  31. 31. Handling Binary Attachments with WSF/C++ ● DataHandler class is the main API for handling attachments ● DataHandler is associated with Axiom Text ServiceClient sc(end_point); sc.engageModule(AXIS2_MODULE_ADDRESSING); Options * op = sc.getOptions(); op->setEnableMTOM(true); OMNamespace * ns1 = new OMNamespace("http://wso2.org/wsf/cpp/samples/mtom", "ns1"); OMElement * payload = new OMElement(NULL,"mtomSample", NULL); OMElement * child1 = new OMElement(payload,"fileName", NULL); child1->setText("test.jpg"); OMElement * child2 = new OMElement(payload,"image", NULL); OMDataHandler * data_handler = new OMDataHandler(file_name, "image/jpeg"); OMText * child3 = new OMText(child2, data_handler); child3->optimize(true); try { OMElement * response = sc.request(payload, "http://wso2.org/wsf/cpp/samples/mtomSample"); } .......
  32. 32. Other Features in WSF/C++ ● Full REST support (GET, PUT, DELETE, POST) with custom URI Mapping ➢ Enables mapping a REST API easily and naturally ● WS-Reliable Messaging 1.0, 1.1 and WS-RMPolicy ➢ Enables reliability between platforms including message resending, duplicate detection and persistence ● XMPP, TCP, UDP,AMQP transports ● Useful tools ➢ wsclient ➢ Tcpmon
  33. 33. Deploying WSF/C++
  34. 34. Feature Comparison Package WSDL Security Attachments Reliability License RogueWave Partial Partial Partial No Proprietary HydraExpress EULA gSOAP Partial Partial Partial No GPL/ gSOAP Public License WSO2 WSF/C Partial Yes Yes Yes Apache2 WSO2 WSF/C++ Partial Yes Yes Yes Apache2
  35. 35. Performance Comparison 9000 8000 7000 6000 MessagesPerSecond 5000 WSAS WSF/CPP 4000 A proprietary stack Gsoap(CGI mode) 3000 2000 1000 0 150b 1k 10k 100k MessageSize
  36. 36. WSF/C++ is better • Open Source with Apache2 License • Best performance • Built on mature Apache projects • Support widest range of web services specifications • Multiple Deployment options - Apache Httpd, IIS or standalone • Proven interoperability with other implementations • Portability and platform support • Built-in code generation tool to support rapid development • Developer friendly tooling ➢ Eclipse code generation plug-in wizard • Fully commercially supported
  37. 37. Roadmap • Manageability using WSO2 Carbon console • Options to statically link WSF/C++ (Specially in Client side) • SAML 1.1 & 2.0 support • Improving https certificate handling • HTTP session support • Code generation tool enhancements ➢ Inheritance, WSPolicy, REST, MTOM, Docs, test cases
  38. 38. Summary • Rich API for implementing clients and services ➢ with code first approach ➢ with code generation tool • Securing web services using both SSL and WS-Security • Ability to handle binary attachments • Reliable Messaging support • Multiple deployment options – Apache httpd, Microsoft IIS • Outstanding performance with high throughput and low memory footprint
  39. 39. Useful Links • Project home page ➢ http://wso2.org/projects/wsf/cpp • Project forum ➢ http://wso2.org/forum/352 • Project Blog ➢ http://cppwebservices.blogspot.com/ • Articles and tutorials in oxygen tank library ➢ http://wso2.org/library/c • Project Mailing lists ➢ wsf-cpp-user@wso2.org ➢ wsf-dev@wso2.org • Support services ➢ http://wso2.com/support

×