src/tools/wsdl.cpp

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 using namespace std;
00024 using namespace WsdlPull;
00025 
00026 #ifdef _WIN32
00027 #define PACKAGE_VERSION "1.x"
00028 #endif
00029 
00030 void
00031 usage(void)
00032 {
00033   std::cout<<"Usage wsdl [options] wsdl-uri [operation name] [method parameters]"<<std::endl;
00034   std::cout<<"Version "<<PACKAGE_VERSION<<std::endl;
00035   std::cout<<"Options: "<<std::endl;
00036   std::cout<<"   -h  Display this message"<<std::endl;
00037   std::cout<<"   -x host[:port] Use HTTP proxy on given port"<<std::endl;
00038   std::cout<<"   -U user[:password] Specify Proxy authentication"<<std::endl;
00039   std::cout<<"   -v Verbose mode,SOAP request and response are logged"<<std::endl;
00040   std::cout<<"   -d display WSDL operation's documentation"<<std::endl;
00041   std::cout<<"   -p display WSDL port types and their operations"<<std::endl;
00042   std::cout<<"   -l list all the WSDL operations "<<std::endl;
00043   std::cout<<"   -o Allow setting occurrence constraint (default is 1)"<<std::endl;
00044   std::cout<<"   -s Suppress printing type/element names in the output"<<std::endl;
00045   std::cout<<"   -t requesttimeout in seconds"<<std::endl;
00046   std::cout<<"   -e set SOAP headers in input"<<std::endl;
00047   std::cout<<"   -g generate sample SOAP message for the invocation"<<std::endl;
00048   std::cout<<"With no arguments,wsdl starts in the interactive mode accepting"<<std::endl;  
00049   std::cout<<"operation name and parameters from the standard input"<<std::endl;
00050 }
00051 
00052 bool
00053 printPortTypes(std::string uri)
00054 {
00055 
00056   WsdlParser wp (uri, cout);
00057   while (wp.getEventType () != WsdlParser::END){
00058 
00059       if(wp.getNextElement () == WsdlParser::PORT_TYPE){
00060 
00061           
00062         const PortType * p = wp.getPortType ();
00063         cout << "Port Type :" << p->getName () << "  has  " << 
00064           p->getNumOps () << " operations "<<endl;
00065         Operation::cOpIterator from,to;
00066         p->getOperations(from,to);
00067         while(from!=to){
00068           
00069           const Message* in = (*from)->getMessage(Input); 
00070           const Message* out = (*from)->getMessage(Output); 
00071           MessageList * faults = (*from)->getFaults();
00072           cout<<(*from)->getName()<<endl;
00073           cout <<"  Input Message:"<<in->getName()<<endl;
00074           if (out)
00075             cout <<"  Output Message:"<<out->getName()<<endl;
00076           if (faults) {
00077             for (MessageList::iterator mli = faults->begin();
00078                  mli != faults->end();
00079                  mli++) {
00080               
00081               cout<<"  Fault :"<<(*mli)->getName()<<endl;
00082             }
00083           }
00084           from++;
00085         }
00086 
00087       }
00088   }
00089   return true;
00090 }
00091 
00092 
00093 
00094 int 
00095 main (int argc, char *argv[]) 
00096 {
00097   WsdlInvoker invoker;
00098   bool brkloop =false;
00099   bool showDoc = false;
00100   bool verbose = false;
00101   bool occurs = false;
00102   bool listops = false;
00103   bool generateSoapMsg = false;
00104   bool accept_password =false;
00105   bool accept_headers = false;
00106   long timeout = 0;
00107 
00108 #ifdef _WIN32
00109   WsdlPull::WsdlParser::useLocalSchema_ = false;
00110 #endif
00111 
00112 
00113   int i =1;
00114   for (;i<argc && !brkloop;){
00115     switch(argv[i][0]){
00116     case '-'://option
00117       {
00118         std::string options(argv[i]+1);
00119         char n = options.length();
00120         while(n--) {
00121           
00122           std::string opt(1,options[n]);
00123           
00124           if (opt=="v"){
00125             invoker.setVerbose(true);
00126             verbose = true;
00127             showDoc = true;
00128 
00129           }
00130           else if (opt == "s"){
00131           
00132             invoker.printTypeNames(false);
00133 
00134           }
00135           else if (opt == "d"){
00136           
00137             showDoc = true;
00138 
00139           }
00140           else if (opt == "e"){
00141           
00142             accept_headers = true;
00143 
00144           }
00145           else if (opt == "l"){
00146           
00147             listops=true;
00148 
00149           }
00150           else if (opt == "x"){
00151             opt = argv[i+1];
00152             size_t pos=opt.find(':');
00153             XmlUtils::setProxyHost (opt);
00154             if(pos==std::string::npos){
00155             
00156               XmlUtils::setProxyHost (XmlUtils::getProxyHost () + ":80");
00157             }
00158             XmlUtils::setProxy (true);
00159             i+=1;
00160             break;
00161           }
00162           else if (opt == "U"){
00163             opt = argv[i+1];
00164             size_t pos=opt.find(':');
00165             XmlUtils::setProxyUser (opt.substr(0,pos));
00166             if(pos!=std::string::npos)
00167               XmlUtils::setProxyPass (opt.substr(pos+1));
00168             else
00169               accept_password = true;
00170             i+=1;
00171             XmlUtils::setProxy (true);
00172             break;
00173           }
00174           else if (opt =="p"){
00175             
00176             if(printPortTypes(argv[i+1]))
00177               exit(0);
00178             else 
00179               exit(1);
00180           }
00181           else if (opt =="h"){
00182             usage();
00183             exit(0);
00184           }
00185           else if (opt == "g"){
00186 
00187             generateSoapMsg = true;
00188           }
00189           else if(opt == "o"){
00190           
00191             occurs = true;//ask for occurrence constraints
00192 
00193           }
00194           else if(opt == "t"){
00195             opt = argv[i+1];
00196             timeout=atoi(opt.c_str());
00197             i+=1;
00198             break;
00199           }
00200           else{
00201             std::cerr<<"Unknown option "<<argv[i]<<std::endl;
00202             usage();
00203             exit(2);
00204           }
00205 
00206         }
00207         i++;
00208         break;
00209 
00210       }
00211     default:
00212       brkloop = true;
00213       //end of options
00214       break;
00215     }
00216   }
00217 
00218   if (XmlUtils::getProxy () && accept_password){
00219      
00220     XmlUtils::setProxyPass (XmlUtils::acceptSecretKey("Proxy Password"));
00221     std::cout<<endl;
00222   }
00223 
00224   if (i < argc){
00225     if(!invoker.setWSDLUri(argv[i])) {
00226 
00227       std::cerr<<"Error processing "<<argv[i]<<std::endl;
00228       std::cerr<<invoker.errors()<<std::endl;
00229       return 1;
00230     }
00231 #ifdef LOGGING
00232       std::cerr<<invoker.errors()<<std::endl;
00233 #endif
00234     i++;
00235   }
00236   else{
00237     
00238     usage();
00239     exit (2);
00240   }
00241 
00242   if (verbose)
00243     std::cout<<invoker.errors()<<std::endl;
00244   
00245   if (i<argc && !listops){
00246     
00247     if(!invoker.setOperation(argv[i])){
00248       
00249       std::cerr<<"Unkown operation name "<<argv[i]<<std::endl;
00250       return 2;
00251     }
00252     i++;
00253   }
00254   else{
00255   
00256     std::vector<std::string> ops;
00257     unsigned int choice = 0;
00258     if (invoker.getOperations(ops)){
00259     
00260       for (size_t s = 0;s<ops.size();s++){
00261       
00262         std::cout<<s+1<<"."<<ops[s];
00263         
00264         if (showDoc) {
00265          
00266           std::string doc = invoker.getOpDocumentation(ops[s]);
00267           if (!doc.empty())
00268             std::cout<<"("<<doc<<")";
00269         }
00270         std::cout<<endl;
00271       }
00272       if (listops == true){
00273         
00274         return 0;
00275       }
00276       while (choice==0){
00277         
00278         std::cout<<"Choose one of the above operations [1-"<<ops.size()<<"] :";
00279         std::cin>>choice;
00280         if (choice>0 && choice<=ops.size())
00281           break;
00282         else
00283           choice=0;
00284       }
00285     }
00286     else {
00287 
00288       std::cerr<<"No operation found or missing <binding> section"<<std::endl;
00289       return 2;
00290     }
00291     if (!invoker.setOperation(ops[choice-1])){
00292       
00293       std::cerr<<"Couldn't invoke operation "<<std::endl;
00294       return 1;
00295     }
00296   }
00297   if(!accept_headers && invoker.nInputHeaders()>0){
00298     
00299     std::cout<<"Warning:This operation has some SOAP headers in its inputs!(use -e)"<<std::endl;
00300   }
00301 
00302   if (invoker.status()){
00303   
00304     int id =0,minimum,maximum,n;
00305     Schema::Type t;
00306     std::string param;
00307     std::string val;
00308     std::vector<std::string> values;
00309     std::vector<std::string> parents;
00310     
00311     do{    
00312 
00313       if (accept_headers && invoker.nInputHeaders()>0){
00314         
00315         id = invoker.getNextHeaderInput(param,t,minimum,maximum,parents);
00316         if (id == -1){
00317           accept_headers=false;//done with headers
00318           continue;
00319         }
00320       }
00321       else{
00322         
00323         id = invoker.getNextInput(param,t,minimum,maximum,parents);
00324       }
00325       if (id == -1)
00326         break;
00327       n = minimum;
00328       if (occurs && minimum < maximum) {
00329         values.clear();
00330         std::cout<<param<<"["<<minimum<<","<<maximum<<"] Enter number of occurrences:";
00331         cin>>n;
00332         
00333         if (n<minimum || n>maximum){
00334           
00335           std::cerr<<"Didnt match occurrence constraints"<<std::endl;
00336           return 2;
00337         }
00338         while(n--) {
00339 
00340           if (i <argc) {
00341             val = argv[i++];
00342           }
00343           else {
00344             std::cout<<param<<": ";
00345             cin>>val;
00346           }
00347           values.push_back(val);
00348         }
00349         if (!invoker.setInputValue(id,values)){
00350 
00351           std::cerr<<"Incorrect input values "<<std::endl;
00352           return 2;
00353         }
00354       }
00355       else{
00356 
00357         if (i <argc) {
00358           
00359           val = argv[i++];
00360         }
00361         else{
00362           size_t j = 0;
00363           for (j=0;j<parents.size()-1;j++){
00364 
00365             std::cout<<parents[j]<<".";
00366           }
00367           std::cout<<parents[j]<<": ";
00368           cin>>val;
00369         }
00370         if (!invoker.setInputValue(id,val)){
00371 
00372           std::cerr<<"Incorrect input value "<<val<<std::endl;
00373           return 2;
00374         }
00375       }
00376     }while(1);
00377   
00378 
00379     if (generateSoapMsg) {
00380 
00381       //output the soap message and exit
00382       std::cout <<invoker.getSoapMessage()<<std::endl;
00383       return 0;
00384 
00385     }
00386 
00387 #ifndef WITH_CURL
00388 #ifndef _WIN32
00389     std::cerr<<"libcurl needs to be installed to proceed with invocation"<<std::endl;
00390     std::cerr<<"Try using the -g option to just print the soap message"<<std::endl;
00391     exit(2);
00392 #endif
00393 #endif 
00394 
00395     if (invoker.invoke(timeout)){
00396 
00397       TypeContainer* tc = 0;
00398       std::string name;
00399       while(invoker.getNextHeaderOutput(name,tc)) {
00400         
00401 
00402         tc->print(std::cout);
00403         std::cout<<std::endl;
00404       }
00405       
00406       while (invoker.getNextOutput(name,tc)){
00407             
00408         tc->print(std::cout);
00409         std::cout<<std::endl;
00410       }
00411       return 0;
00412     }
00413     else{
00414       cerr<<invoker.errors()<<std::endl;
00415       cerr<<"Run with -v option and see request.log and response.log"<<endl;
00416     }
00417   }
00418   return 1;
00419 }
00420 
00421 
00422 
00423 

Generated on Sat May 3 16:29:00 2008 for wsdlpull by  doxygen 1.4.6