wsdlpull 1.23
|
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