wsdlpull  1.23
wsdl.cpp
Go to the documentation of this file.
1 /*
2  * wsdlpull - A C++ parser for WSDL (Web services description language)
3  * Copyright (C) 2005-2007 Vivek Krishna
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 
21 //A generic web service invocation tool which uses the invocation API
22 #include "wsdlparser/WsdlInvoker.h"
23 //
24 #include <cstdlib>
25 
26 using namespace std;
27 using namespace WsdlPull;
28 
29 #ifdef _WIN32
30 #define PACKAGE_VERSION "1.x"
31 #endif
32 
33 void
34 usage(void)
35 {
36  std::cout<<"Usage wsdl [options] wsdl-uri [operation name] [method parameters] [xpath expression for response]"<<std::endl;
37  std::cout<<"Version "<<PACKAGE_VERSION<<std::endl;
38  std::cout<<"Options: "<<std::endl;
39  std::cout<<" -h Display this message"<<std::endl;
40  std::cout<<" -x host[:port] Use HTTP proxy on given port"<<std::endl;
41  std::cout<<" -U user[:password] Specify Proxy authentication"<<std::endl;
42  std::cout<<" -v Verbose mode,SOAP request and response are logged"<<std::endl;
43  std::cout<<" -d display WSDL operation's documentation"<<std::endl;
44  std::cout<<" -p display WSDL port types and their operations"<<std::endl;
45  std::cout<<" -l list all the WSDL operations "<<std::endl;
46  std::cout<<" -o Allow setting occurrence constraint (default is 1)"<<std::endl;
47  std::cout<<" -s Suppress printing type/element names in the output"<<std::endl;
48  std::cout<<" -t requesttimeout in seconds"<<std::endl;
49  std::cout<<" -e set SOAP headers in input"<<std::endl;
50  std::cout<<" -g generate sample SOAP message for the invocation"<<std::endl;
51  std::cout<<" -r Validate the response message with schema even when xpath selector is used(default is off)"<<std::endl;
52  std::cout<<"With no arguments,wsdl starts in the interactive mode accepting operation name and parameters from the standard input."<<std::endl<<std::endl;
53  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;
54 
55 
56 }
57 
58 bool
59 printPortTypes(std::string uri)
60 {
61 
62  WsdlParser wp (uri, cout);
63  while (wp.getEventType () != WsdlParser::END){
64 
65  if(wp.getNextElement () == WsdlParser::PORT_TYPE){
66 
67 
68  const PortType * p = wp.getPortType ();
69  cout << "Port Type :" << p->getName () << " has " <<
70  p->getNumOps () << " operations "<<endl;
71  Operation::cOpIterator from,to;
72  p->getOperations(from,to);
73  while(from!=to){
74 
75  const Message* in = (*from)->getMessage(Input);
76  const Message* out = (*from)->getMessage(Output);
77  MessageList * faults = (*from)->getFaults();
78  cout<<(*from)->getName()<<endl;
79  cout <<" Input Message:"<<in->getName()<<endl;
80  if (out)
81  cout <<" Output Message:"<<out->getName()<<endl;
82  if (faults) {
83  for (MessageList::iterator mli = faults->begin();
84  mli != faults->end();
85  mli++) {
86 
87  cout<<" Fault :"<<(*mli)->getName()<<endl;
88  }
89  }
90  from++;
91  }
92 
93  }
94  }
95  return true;
96 }
97 
98 
99 
100 int
101 main (int argc, char *argv[])
102 {
103  WsdlInvoker invoker;
104  bool brkloop =false;
105  bool showDoc = false;
106  bool verbose = false;
107  bool occurs = false;
108  bool listops = false;
109  bool generateSoapMsg = false;
110  bool accept_password =false;
111  bool accept_headers = false;
112  bool processResponse = false;
113  long timeout = 0;
114 
115 #ifdef _WIN32
117 #endif
118 
119 
120  int i =1;
121  for (;i<argc && !brkloop;){
122  switch(argv[i][0]){
123  case '-'://option
124  {
125  std::string options(argv[i]+1);
126  char n = options.length();
127  while(n--) {
128 
129  std::string opt(1,options[n]);
130 
131  if (opt=="v"){
132  invoker.setVerbose(true);
133  verbose = true;
134  showDoc = true;
135 
136  }
137  else if (opt == "s"){
138 
139  invoker.printTypeNames(false);
140 
141  }
142  else if (opt == "d"){
143 
144  showDoc = true;
145 
146  }
147  else if (opt == "e"){
148 
149  accept_headers = true;
150 
151  }
152  else if (opt == "l"){
153 
154  listops=true;
155 
156  }
157  else if (opt == "x"){
158  opt = argv[i+1];
159  size_t pos=opt.find(':');
161  if(pos==std::string::npos){
162 
164  }
165  XmlUtils::setProxy (true);
166  i+=1;
167  break;
168  }
169  else if (opt == "U"){
170  opt = argv[i+1];
171  size_t pos=opt.find(':');
172  XmlUtils::setProxyUser (opt.substr(0,pos));
173  if(pos!=std::string::npos)
174  XmlUtils::setProxyPass (opt.substr(pos+1));
175  else
176  accept_password = true;
177  i+=1;
178  XmlUtils::setProxy (true);
179  break;
180  }
181  else if (opt =="p"){
182 
183  if(printPortTypes(argv[i+1]))
184  return 0;
185  else
186  return 1;
187  }
188  else if (opt =="h"){
189  usage();
190  return 0;
191  }
192  else if (opt == "g"){
193 
194  generateSoapMsg = true;
195  }
196  else if(opt == "o"){
197 
198  occurs = true;//ask for occurrence constraints
199 
200  }
201  else if(opt == "t"){
202  opt = argv[i+1];
203  timeout=atoi(opt.c_str());
204  i+=1;
205  break;
206  }
207  else if(opt == "r"){
208  processResponse = true;
209  }
210  else{
211  std::cerr<<"Unknown option "<<argv[i]<<std::endl;
212  usage();
213  return 2;
214  }
215 
216  }
217  i++;
218  break;
219 
220  }
221  default:
222  brkloop = true;
223  //end of options
224  break;
225  }
226  }
227 
228  if (XmlUtils::getProxy () && accept_password){
229 
231  std::cout<<endl;
232  }
233 
234  if (i < argc){
235  if(!invoker.setWSDLUri(argv[i])) {
236 
237  std::cerr<<"Error processing "<<argv[i]<<std::endl;
238  std::cerr<<invoker.errors()<<std::endl;
239  return 1;
240  }
241 #ifdef LOGGING
242  std::cerr<<invoker.errors()<<std::endl;
243 #endif
244  i++;
245  }
246  else{
247 
248  usage();
249  return 2;
250  }
251 
252  if (verbose)
253  std::cout<<invoker.errors()<<std::endl;
254 
255  if (i<argc && !listops){
256 
257  if(!invoker.setOperation(argv[i])){
258 
259  std::cerr<<"Unkown operation name "<<argv[i]<<std::endl;
260  return 2;
261  }
262  i++;
263  }
264  else{
265 
266  std::vector<std::string> ops;
267  unsigned int choice = 0;
268  if (invoker.getOperations(ops)){
269 
270  for (size_t s = 0;s<ops.size();s++){
271 
272  std::cout<<s+1<<"."<<ops[s];
273 
274  if (showDoc) {
275 
276  std::string doc = invoker.getOpDocumentation(ops[s]);
277  if (!doc.empty())
278  std::cout<<"("<<doc<<")";
279  }
280  std::cout<<endl;
281  }
282  if (listops == true){
283 
284  return 0;
285  }
286  while (choice==0){
287 
288  std::cout<<"Choose one of the above operations [1-"<<ops.size()<<"] :";
289  std::cin>>choice;
290  if (choice>0 && choice<=ops.size())
291  break;
292  else
293  choice=0;
294  }
295  }
296  else {
297 
298  std::cerr<<"No operation found or missing <binding> section"<<std::endl;
299  return 2;
300  }
301  if (!invoker.setOperation(ops[choice-1])){
302 
303  std::cerr<<"Couldn't invoke operation "<<std::endl<<invoker.errors()<<std::endl;
304  return 1;
305  }
306  }
307  if(!accept_headers && invoker.nInputHeaders()>0){
308 
309  std::cout<<"Warning:This operation has some SOAP headers in its inputs!(use -e)"<<std::endl;
310  }
311 
312  if (invoker.status()){
313 
314  int id =0,minimum,maximum,n;
315  Schema::Type t;
316  std::string param;
317  std::string val;
318  std::vector<std::string> values;
319  std::vector<std::string> parents;
320 
321  do{
322 
323  if (accept_headers && invoker.nInputHeaders()>0){
324 
325  id = invoker.getNextHeaderInput(param,t,minimum,maximum,parents);
326  if (id == -1){
327  accept_headers=false;//done with headers
328  continue;
329  }
330  }
331  else{
332 
333  id = invoker.getNextInput(param,t,minimum,maximum,parents);
334  }
335  if (id == -1)
336  break;
337  n = minimum;
338  if (occurs && minimum < maximum) {
339  values.clear();
340  std::cout<<param<<"["<<minimum<<","<<maximum<<"] Enter number of occurrences:";
341  cin>>n;
342 
343  if (n<minimum || n>maximum){
344 
345  std::cerr<<"Didnt match occurrence constraints"<<std::endl;
346  return 2;
347  }
348  while(n--) {
349 
350  if (i <argc) {
351  val = argv[i++];
352  }
353  else {
354  std::cout<<param<<": ";
355  cin>>val;
356  }
357  values.push_back(val);
358  }
359  if (!invoker.setInputValue(id,values)){
360 
361  std::cerr<<"Incorrect input values "<<std::endl;
362  return 2;
363  }
364  }
365  else{
366 
367  if (i <argc) {
368 
369  val = argv[i++];
370  }
371  else{
372  size_t j = 0;
373  for (j=0;j<parents.size()-1;j++){
374 
375  std::cout<<parents[j]<<".";
376  }
377  std::cout<<parents[j]<<": ";
378  cin>>val;
379  }
380  if (!invoker.setInputValue(id,val)){
381 
382  std::cerr<<"Incorrect input value "<<val<<std::endl;
383  return 2;
384  }
385  }
386  }while(1);
387 
388 
389  if (generateSoapMsg) {
390 
391  //output the soap message and exit
392  std::cout <<invoker.getSoapMessage()<<std::endl;
393  return 0;
394 
395  }
396 
397 #ifndef WITH_CURL
398 #ifndef _WIN32
399  std::cerr<<"libcurl needs to be installed to proceed with invocation"<<std::endl;
400  std::cerr<<"Try using the -g option to just print the soap message"<<std::endl;
401  return 2;
402 #endif
403 #endif
404 
405  if (invoker.invoke(timeout,(i>=argc || processResponse))){
406 
407  TypeContainer* tc = 0;
408  std::string name;
409 
410  if (i <argc) {
411 
412  try {
413  //the last argument is an xpath expression to get the output
414  std::vector<std::string> arr=invoker.getValues<std::string>(argv[i++]);
415  for (size_t s = 0;s<arr.size();s++)
416  std::cout<<arr[s]<<std::endl;
417 
418  return 0;
419  }
420  catch (WsdlException we) {
421 
422  std::cerr<<we.description<<std::endl;
423  }
424  catch (XmlPullParserException xpe) {
425 
426  std::cerr<<xpe.description<<std::endl;
427  }
428  return 2;
429  }
430  while(invoker.getNextHeaderOutput(name,tc)) {
431 
432 
433  tc->print(std::cout);
434  std::cout<<std::endl;
435  }
436 
437  while (invoker.getNextOutput(name,tc)){
438 
439  tc->print(std::cout);
440  std::cout<<std::endl;
441  }
442  return 0;
443  }
444  else{
445  cerr<<invoker.errors()<<std::endl;
446  cerr<<"Run with -v option and see request.log and response.log"<<endl;
447  }
448  }
449  return 1;
450 }
451 
452 
453 
454 
int getNumOps(void) const
Definition: PortType.h:102
void printTypeNames(bool f)
std::string getOpDocumentation(const std::string &n)
void print(std::ostream &os)
bool setWSDLUri(const std::string &url, const std::string &schemaPath="")
Definition: WsdlInvoker.h:383
bool setInputValue(const int param, void *val)
void setVerbose(bool f)
Definition: WsdlInvoker.h:405
bool getNextOutput(std::string &name, TypeContainer *&tc)
int getNextHeaderInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
static bool useLocalSchema_
Definition: WsdlParser.h:259
STL namespace.
std::string getName() const
Definition: WsdlElement.h:110
bool invoke(long timeout=0, bool processResponse=true)
std::string errors()
Definition: WsdlInvoker.h:376
std::list< const Message * > MessageList
Definition: Operation.h:49
int getNextInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
void WSDLPULL_EXPORT setProxyPass(const std::string &sProxyPass)
Definition: XmlUtils.cpp:375
void WSDLPULL_EXPORT setProxyHost(const std::string &sProxyHost)
Definition: XmlUtils.cpp:347
std::string WSDLPULL_EXPORT getProxyHost()
Definition: XmlUtils.cpp:340
int main(int argc, char *argv[])
Definition: wsdl.cpp:101
void usage(void)
Definition: wsdl.cpp:34
bool setOperation(const std::string &operation, WsdlPull::MessageType mType=WsdlPull::Input)
set the operation to invoke
bool WSDLPULL_EXPORT getProxy()
Definition: XmlUtils.cpp:326
bool status() const
Definition: WsdlInvoker.h:391
const PortType * getPortType()
Definition: WsdlParser.cpp:269
bool getNextHeaderOutput(std::string &name, TypeContainer *&tc)
std::string getSoapMessage()
bool getOperations(Operation::cOpIterator &start, Operation::cOpIterator &finish) const
Definition: PortType.h:140
int getOperations(std::vector< std::string > &operations)
return names of operations (only for the SOAP binding portType)
Type
Definition: Schema.h:59
std::vector< Operation * >::const_iterator cOpIterator
Definition: Operation.h:57
std::string WSDLPULL_EXPORT acceptSecretKey(const std::string &field)
Definition: XmlUtils.cpp:250
void WSDLPULL_EXPORT setProxyUser(const std::string &sProxyUser)
Definition: XmlUtils.cpp:361
int nInputHeaders() const
Definition: WsdlInvoker.h:412
void WSDLPULL_EXPORT setProxy(const bool bProxy)
Definition: XmlUtils.cpp:333
std::vector< T > getValues(const std::string &xpath)
sets the param value for an operation by name of the parameter
Definition: WsdlInvoker.h:469
bool printPortTypes(std::string uri)
Definition: wsdl.cpp:59