wsdl.cpp

Go to the documentation of this file.
00001 /* 
00002  * wsdlpull - A C++ parser  for WSDL  (Web services description language)
00003  * Copyright (C) 2005-2007 Vivek Krishna
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the Free
00017  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  */
00019 
00020 
00021 //A generic web service invocation tool which uses the invocation API
00022 #include "wsdlparser/WsdlInvoker.h"
00023 //
00024 #include <cstdlib>
00025 
00026 using namespace std;
00027 using namespace WsdlPull;
00028 
00029 #ifdef _WIN32
00030 #define PACKAGE_VERSION "1.x"
00031 #endif
00032 
00033 void
00034 usage(void)
00035 {
00036   std::cout<<"Usage wsdl [options] wsdl-uri [operation name] [method parameters] [xpath expression for response]"<<std::endl;
00037   std::cout<<"Version "<<PACKAGE_VERSION<<std::endl;
00038   std::cout<<"Options: "<<std::endl;
00039   std::cout<<"   -h  Display this message"<<std::endl;
00040   std::cout<<"   -x host[:port] Use HTTP proxy on given port"<<std::endl;
00041   std::cout<<"   -U user[:password] Specify Proxy authentication"<<std::endl;
00042   std::cout<<"   -v Verbose mode,SOAP request and response are logged"<<std::endl;
00043   std::cout<<"   -d display WSDL operation's documentation"<<std::endl;
00044   std::cout<<"   -p display WSDL port types and their operations"<<std::endl;
00045   std::cout<<"   -l list all the WSDL operations "<<std::endl;
00046   std::cout<<"   -o Allow setting occurrence constraint (default is 1)"<<std::endl;
00047   std::cout<<"   -s Suppress printing type/element names in the output"<<std::endl;
00048   std::cout<<"   -t requesttimeout in seconds"<<std::endl;
00049   std::cout<<"   -e set SOAP headers in input"<<std::endl;
00050   std::cout<<"   -g generate sample SOAP message for the invocation"<<std::endl;
00051   std::cout<<"   -r Validate the response message with schema even when xpath selector is used(default is off)"<<std::endl;
00052   std::cout<<"With no arguments,wsdl starts in the interactive mode accepting operation name and parameters from the standard input."<<std::endl<<std::endl;
00053   std::cout<<"An xpath expression can be used to extract elements from web service response.If the expression points to an element or an attribute,the element's text or attribute value will be returned.The expression will match all occurrences in the xml tree"<<std::endl;
00054 
00055 
00056 }
00057 
00058 bool
00059 printPortTypes(std::string uri)
00060 {
00061 
00062   WsdlParser wp (uri, cout);
00063   while (wp.getEventType () != WsdlParser::END){
00064 
00065       if(wp.getNextElement () == WsdlParser::PORT_TYPE){
00066 
00067           
00068         const PortType * p = wp.getPortType ();
00069         cout << "Port Type :" << p->getName () << "  has  " << 
00070           p->getNumOps () << " operations "<<endl;
00071         Operation::cOpIterator from,to;
00072         p->getOperations(from,to);
00073         while(from!=to){
00074           
00075           const Message* in = (*from)->getMessage(Input); 
00076           const Message* out = (*from)->getMessage(Output); 
00077           MessageList * faults = (*from)->getFaults();
00078           cout<<(*from)->getName()<<endl;
00079           cout <<"  Input Message:"<<in->getName()<<endl;
00080           if (out)
00081             cout <<"  Output Message:"<<out->getName()<<endl;
00082           if (faults) {
00083             for (MessageList::iterator mli = faults->begin();
00084                  mli != faults->end();
00085                  mli++) {
00086               
00087               cout<<"  Fault :"<<(*mli)->getName()<<endl;
00088             }
00089           }
00090           from++;
00091         }
00092 
00093       }
00094   }
00095   return true;
00096 }
00097 
00098 
00099 
00100 int 
00101 main (int argc, char *argv[]) 
00102 {
00103   WsdlInvoker invoker;
00104   bool brkloop =false;
00105   bool showDoc = false;
00106   bool verbose = false;
00107   bool occurs = false;
00108   bool listops = false;
00109   bool generateSoapMsg = false;
00110   bool accept_password =false;
00111   bool accept_headers = false;
00112   bool   processResponse = false;
00113   long timeout = 0;
00114 
00115 #ifdef _WIN32
00116   WsdlPull::WsdlParser::useLocalSchema_ = false;
00117 #endif
00118 
00119 
00120   int i =1;
00121   for (;i<argc && !brkloop;){
00122     switch(argv[i][0]){
00123     case '-'://option
00124       {
00125         std::string options(argv[i]+1);
00126         char n = options.length();
00127         while(n--) {
00128           
00129           std::string opt(1,options[n]);
00130           
00131           if (opt=="v"){
00132             invoker.setVerbose(true);
00133             verbose = true;
00134             showDoc = true;
00135 
00136           }
00137           else if (opt == "s"){
00138           
00139             invoker.printTypeNames(false);
00140 
00141           }
00142           else if (opt == "d"){
00143           
00144             showDoc = true;
00145 
00146           }
00147           else if (opt == "e"){
00148           
00149             accept_headers = true;
00150 
00151           }
00152           else if (opt == "l"){
00153           
00154             listops=true;
00155 
00156           }
00157           else if (opt == "x"){
00158             opt = argv[i+1];
00159             size_t pos=opt.find(':');
00160             XmlUtils::setProxyHost (opt);
00161             if(pos==std::string::npos){
00162             
00163               XmlUtils::setProxyHost (XmlUtils::getProxyHost () + ":80");
00164             }
00165             XmlUtils::setProxy (true);
00166             i+=1;
00167             break;
00168           }
00169           else if (opt == "U"){
00170             opt = argv[i+1];
00171             size_t pos=opt.find(':');
00172             XmlUtils::setProxyUser (opt.substr(0,pos));
00173             if(pos!=std::string::npos)
00174               XmlUtils::setProxyPass (opt.substr(pos+1));
00175             else
00176               accept_password = true;
00177             i+=1;
00178             XmlUtils::setProxy (true);
00179             break;
00180           }
00181           else if (opt =="p"){
00182             
00183             if(printPortTypes(argv[i+1]))
00184               return 0;
00185             else 
00186               return 1;
00187           }
00188           else if (opt =="h"){
00189             usage();
00190             return 0;
00191           }
00192           else if (opt == "g"){
00193 
00194             generateSoapMsg = true;
00195           }
00196           else if(opt == "o"){
00197           
00198             occurs = true;//ask for occurrence constraints
00199 
00200           }
00201           else if(opt == "t"){
00202             opt = argv[i+1];
00203             timeout=atoi(opt.c_str());
00204             i+=1;
00205             break;
00206           }
00207           else if(opt == "r"){
00208             processResponse = true;
00209           }
00210           else{
00211             std::cerr<<"Unknown option "<<argv[i]<<std::endl;
00212             usage();
00213             return 2;
00214           }
00215 
00216         }
00217         i++;
00218         break;
00219 
00220       }
00221     default:
00222       brkloop = true;
00223       //end of options
00224       break;
00225     }
00226   }
00227 
00228   if (XmlUtils::getProxy () && accept_password){
00229      
00230     XmlUtils::setProxyPass (XmlUtils::acceptSecretKey("Proxy Password"));
00231     std::cout<<endl;
00232   }
00233 
00234   if (i < argc){
00235     if(!invoker.setWSDLUri(argv[i])) {
00236 
00237       std::cerr<<"Error processing "<<argv[i]<<std::endl;
00238       std::cerr<<invoker.errors()<<std::endl;
00239       return 1;
00240     }
00241 #ifdef LOGGING
00242       std::cerr<<invoker.errors()<<std::endl;
00243 #endif
00244     i++;
00245   }
00246   else{
00247     
00248     usage();
00249     return 2;
00250   }
00251 
00252   if (verbose)
00253     std::cout<<invoker.errors()<<std::endl;
00254   
00255   if (i<argc && !listops){
00256     
00257     if(!invoker.setOperation(argv[i])){
00258       
00259       std::cerr<<"Unkown operation name "<<argv[i]<<std::endl;
00260       return 2;
00261     }
00262     i++;
00263   }
00264   else{
00265   
00266     std::vector<std::string> ops;
00267     unsigned int choice = 0;
00268     if (invoker.getOperations(ops)){
00269     
00270       for (size_t s = 0;s<ops.size();s++){
00271       
00272         std::cout<<s+1<<"."<<ops[s];
00273         
00274         if (showDoc) {
00275          
00276           std::string doc = invoker.getOpDocumentation(ops[s]);
00277           if (!doc.empty())
00278             std::cout<<"("<<doc<<")";
00279         }
00280         std::cout<<endl;
00281       }
00282       if (listops == true){
00283         
00284         return 0;
00285       }
00286       while (choice==0){
00287         
00288         std::cout<<"Choose one of the above operations [1-"<<ops.size()<<"] :";
00289         std::cin>>choice;
00290         if (choice>0 && choice<=ops.size())
00291           break;
00292         else
00293           choice=0;
00294       }
00295     }
00296     else {
00297 
00298       std::cerr<<"No operation found or missing <binding> section"<<std::endl;
00299       return 2;
00300     }
00301     if (!invoker.setOperation(ops[choice-1])){
00302       
00303       std::cerr<<"Couldn't invoke operation "<<std::endl<<invoker.errors()<<std::endl;
00304       return 1;
00305     }
00306   }
00307   if(!accept_headers && invoker.nInputHeaders()>0){
00308     
00309     std::cout<<"Warning:This operation has some SOAP headers in its inputs!(use -e)"<<std::endl;
00310   }
00311 
00312   if (invoker.status()){
00313   
00314     int id =0,minimum,maximum,n;
00315     Schema::Type t;
00316     std::string param;
00317     std::string val;
00318     std::vector<std::string> values;
00319     std::vector<std::string> parents;
00320     
00321     do{    
00322 
00323       if (accept_headers && invoker.nInputHeaders()>0){
00324         
00325         id = invoker.getNextHeaderInput(param,t,minimum,maximum,parents);
00326         if (id == -1){
00327           accept_headers=false;//done with headers
00328           continue;
00329         }
00330       }
00331       else{
00332         
00333         id = invoker.getNextInput(param,t,minimum,maximum,parents);
00334       }
00335       if (id == -1)
00336         break;
00337       n = minimum;
00338       if (occurs && minimum < maximum) {
00339         values.clear();
00340         std::cout<<param<<"["<<minimum<<","<<maximum<<"] Enter number of occurrences:";
00341         cin>>n;
00342         
00343         if (n<minimum || n>maximum){
00344           
00345           std::cerr<<"Didnt match occurrence constraints"<<std::endl;
00346           return 2;
00347         }
00348         while(n--) {
00349 
00350           if (i <argc) {
00351             val = argv[i++];
00352           }
00353           else {
00354             std::cout<<param<<": ";
00355             cin>>val;
00356           }
00357           values.push_back(val);
00358         }
00359         if (!invoker.setInputValue(id,values)){
00360 
00361           std::cerr<<"Incorrect input values "<<std::endl;
00362           return 2;
00363         }
00364       }
00365       else{
00366 
00367         if (i <argc) {
00368           
00369           val = argv[i++];
00370         }
00371         else{
00372           size_t j = 0;
00373           for (j=0;j<parents.size()-1;j++){
00374 
00375             std::cout<<parents[j]<<".";
00376           }
00377           std::cout<<parents[j]<<": ";
00378           cin>>val;
00379         }
00380         if (!invoker.setInputValue(id,val)){
00381 
00382           std::cerr<<"Incorrect input value "<<val<<std::endl;
00383           return 2;
00384         }
00385       }
00386     }while(1);
00387   
00388 
00389     if (generateSoapMsg) {
00390 
00391       //output the soap message and exit
00392       std::cout <<invoker.getSoapMessage()<<std::endl;
00393       return 0;
00394 
00395     }
00396 
00397 #ifndef WITH_CURL
00398 #ifndef _WIN32
00399     std::cerr<<"libcurl needs to be installed to proceed with invocation"<<std::endl;
00400     std::cerr<<"Try using the -g option to just print the soap message"<<std::endl;
00401     return 2;
00402 #endif
00403 #endif 
00404 
00405     if (invoker.invoke(timeout,(i>=argc || processResponse))){
00406 
00407       TypeContainer* tc = 0;
00408       std::string name;
00409       
00410       if (i <argc) {
00411         
00412         try {
00413         //the last argument is an xpath expression to get the output
00414           std::vector<std::string> arr=invoker.getValues<std::string>(argv[i++]);
00415           for (size_t s = 0;s<arr.size();s++) 
00416             std::cout<<arr[s]<<std::endl;
00417 
00418           return 0;
00419         }
00420         catch (WsdlException we) {
00421 
00422           std::cerr<<we.description<<std::endl;
00423         }
00424         catch (XmlPullParserException xpe) {
00425 
00426           std::cerr<<xpe.description<<std::endl;
00427         }
00428         return 2;
00429       }
00430       while(invoker.getNextHeaderOutput(name,tc)) {
00431         
00432 
00433         tc->print(std::cout);
00434         std::cout<<std::endl;
00435       }
00436       
00437       while (invoker.getNextOutput(name,tc)){
00438             
00439         tc->print(std::cout);
00440         std::cout<<std::endl;
00441       }
00442       return 0;
00443     }
00444     else{
00445       cerr<<invoker.errors()<<std::endl;
00446       cerr<<"Run with -v option and see request.log and response.log"<<endl;
00447     }
00448   }
00449   return 1;
00450 }
00451 
00452 
00453 
00454 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by  doxygen 1.6.2