Upload
wso2
View
5.860
Download
2
Embed Size (px)
DESCRIPTION
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++.
Citation preview
Better Open Source Enterprise C++ Web Services
Introducing WSO2 Web Services Framework for C++
Nandika JayawardanaProduct Manager
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
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
WSF/C++ Architecture
WSF/C++ Architecture
WSF/C++ Components
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
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
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;
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
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
WSF/C++ Repository
Service configuration
<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>
● services.xml
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
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;
}
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
Eclipse Codegen Plug-in Wizard
Eclipse Codegen Plug-in
Eclipse Codegen Plug-in
Command line code generation tool
● In the windows binary distribution, code generation tool is available in the <WSFCPP_HOME>\bin\tools\codegen\wsdl2cpp 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
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 )
● ExamplesWSDL2CPP.bat -uri calculator.wsdl -u -d adb -o calcWSDL2CPP.bat -uri calculator.wsdl -d none -o calcWSDL2CPP.bat -uri calculator.wsdl -u -d adb -ss -sd -o calc
Code Generated Clientint 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;
}
Code Generated Serviceint 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;}
#include "CalculatorSkeleton.h"using namespace localhost_axis_calculator; int CalculatorSkeleton::mul(wso2wsf::MessageContext *outCtx ,int _a,int _b) { return _a*_b; } int CalculatorSkeleton::div(wso2wsf::MessageContext *outCtx ,int _a0,int _b1){
if(_b1 != 0){
return _a0/_b1;}else{
std::cout<<"Cannot divide by zero";return 0;
}}int CalculatorSkeleton::sub(wso2wsf::MessageContext *outCtx ,int _a2,int _b3){
return _a2 - _b3;}int CalculatorSkeleton::add(wso2wsf::MessageContext *outCtx ,int _a4,int _b5){
return _a4 + _b5;}
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
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
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>
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
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));
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-win32\samples\lib\pwcb.dll</rampc:PasswordCallbackClass> <rampc:ReceiverCertificate>E:\wso2-wsf-cpp-bin-2.1.0-win32\samples\src\c\rampartc/data/keys/bhome/alice_cert.cert</rampc:ReceiverCertificate> <rampc:Certificate>E:\wso2-wsf-cpp-bin-2.1.0-win32\samples\src\c\rampartc\data\keys\bhome\bob_cert.cert</rampc:Certificate> <rampc:PrivateKey>E:\wso2-wsf-cpp-bin-2.1.0-win32\samples\src\c\rampartc\data\keys\bhome\bob_key.pem</rampc:PrivateKey> </rampc:RampartConfig> </wsp:All> </wsp:ExactlyOne> </wsp:Policy></service>
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
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"); } .......
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
Deploying WSF/C++
Feature Comparison
Package WSDL Security Attachments Reliability License
RogueWaveHydraExpress
Partial Partial Partial No Proprietary 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
Performance Comparison
150b 1k 10k 100k0
1000
2000
3000
4000
5000
6000
7000
8000
9000
WSASWSF/CPPA proprietary stackGsoap(CGI mode)
MessageSize
Mes
sage
sPer
Sec
ond
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
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
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
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➢ [email protected]➢ [email protected]
• Support services➢ http://wso2.com/support