OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
StandAloneApp.cc
Go to the documentation of this file.
1 // StandAloneApp.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include <unistd.h>
34 #include <getopt.h>
35 #include <signal.h>
36 
37 #include <iostream>
38 #include <string>
39 #include <fstream>
40 
41 using std::cout ;
42 using std::cerr ;
43 using std::endl ;
44 using std::flush ;
45 using std::string ;
46 using std::ofstream ;
47 
48 #include "StandAloneApp.h"
49 #include "StandAloneClient.h"
50 #include "BESError.h"
51 #include "BESDebug.h"
52 #include "BESDefaultModule.h"
53 #include "BESXMLDefaultCommands.h"
54 #include "TheBESKeys.h"
55 #include "BESCatalogUtils.h"
56 #include "CmdTranslation.h"
57 
59  : BESModuleApp(),
60  _client( 0 ),
61  _outputStrm( 0 ),
62  _inputStrm( 0 ),
63  _createdInputStrm( false ),
64  _repeat( 0 )
65 {
66 }
67 
69 {
70  if (_client) {
71  delete _client;
72  _client = 0;
73  }
74 
75  delete TheBESKeys::TheKeys();
76 
78 }
79 
80 void
81 StandAloneApp::showVersion()
82 {
83  cout << appName() << ": version 2.0" << endl ;
84 }
85 
86 void
87 StandAloneApp::showUsage( )
88 {
89  cout << endl ;
90  cout << appName() << ": the following options are available:" << endl ;
91  cout << " -c <file>, --config=<file> - BES configuration file" << endl ;
92  cout << " -x <command>, --execute=<command> - command for the server to execute" << endl ;
93  cout << " -i <file>, --inputfile=<file> - file with a sequence of input commands" << endl ;
94  cout << " -f <file>, --outputfile=<file> - write output to this file" << endl ;
95  cout << " -d, --debug - turn on debugging for the client session" << endl ;
96  cout << " -r <num>, --repeat=<num> - repeat the command(s) <num> times" << endl ;
97  cout << " -v, --version - return version information" << endl;
98  cout << " -?, --help - display help information" << endl ;
99  cout << endl ;
100  BESDebug::Help( cout ) ;
101 }
102 
103 int
104 StandAloneApp::initialize( int argc, char **argv )
105 {
106  CmdTranslation::initialize( argc, argv ) ;
107 
108  string outputStr = "" ;
109  string inputStr = "" ;
110  string repeatStr = "" ;
111 
112  bool badUsage = false ;
113 
114  int c ;
115 
116  static struct option longopts[] =
117  {
118  {"config", 1, 0, 'c'},
119  {"debug", 0, 0, 'd'},
120  {"version", 0, 0, 'v'},
121  {"execute", 1, 0, 'x'},
122  {"outputfile", 1, 0, 'f'},
123  {"inputfile", 1, 0, 'i'},
124  {"repeat", 1, 0, 'r'},
125  {"help", 0, 0, '?'},
126  {0,0,0,0}
127  };
128  int option_index = 0;
129 
130  while( ( c = getopt_long( argc, argv, "?vc:d:x:f:i:r:", longopts, &option_index) ) != EOF )
131  {
132  switch( c )
133  {
134  case 'c':
135  TheBESKeys::ConfigFile = optarg ;
136  break ;
137  case 'd':
138  BESDebug::SetUp( optarg ) ;
139  break ;
140  case 'v':
141  {
142  showVersion() ;
143  exit( 0 ) ;
144  }
145  break ;
146  case 'x':
147  _cmd = optarg ;
148  break ;
149  case 'f':
150  outputStr = optarg ;
151  break ;
152  case 'i':
153  inputStr = optarg ;
154  break ;
155  case 'r':
156  repeatStr = optarg ;
157  break ;
158  case '?':
159  {
160  showUsage() ;
161  exit( 0 ) ;
162  }
163  break ;
164  }
165  }
166 
167  if( outputStr != "" )
168  {
169  if( _cmd == "" && inputStr == "" )
170  {
171  cerr << "When specifying an output file you must either "
172  << "specify a command or an input file"
173  << endl ;
174  badUsage = true ;
175  }
176  else if( _cmd != "" && inputStr != "" )
177  {
178  cerr << "You must specify either a command or an input file on "
179  << "the command line, not both"
180  << endl ;
181  badUsage = true ;
182  }
183  }
184 
185  if( badUsage == true )
186  {
187  showUsage( ) ;
188  return 1 ;
189  }
190 
191  if( outputStr != "" )
192  {
193  _outputStrm = new ofstream( outputStr.c_str() ) ;
194  if( !(*_outputStrm) )
195  {
196  cerr << "could not open the output file " << outputStr << endl ;
197  badUsage = true ;
198  }
199  }
200 
201  if( inputStr != "" )
202  {
203  _inputStrm = new ifstream( inputStr.c_str() ) ;
204  if( !(*_inputStrm) )
205  {
206  cerr << "could not open the input file " << inputStr << endl ;
207  badUsage = true ;
208  }
209  _createdInputStrm = true ;
210  }
211 
212  if( !repeatStr.empty() )
213  {
214  _repeat = atoi( repeatStr.c_str() ) ;
215  if( !_repeat && repeatStr != "0" )
216  {
217  cerr << "repeat number invalid: " << repeatStr << endl ;
218  badUsage = true ;
219  }
220  if( !_repeat )
221  {
222  _repeat = 1 ;
223  }
224  }
225 
226  if( badUsage == true )
227  {
228  showUsage( ) ;
229  return 1 ;
230  }
231 
232  try
233  {
234  BESDEBUG( "standalone", "ServerApp: initializing default module ... "
235  << endl ) ;
236  BESDefaultModule::initialize( argc, argv ) ;
237  BESDEBUG( "standalone", "ServerApp: done initializing default module"
238  << endl ) ;
239 
240  BESDEBUG( "standalone", "ServerApp: initializing default commands ... "
241  << endl ) ;
242  BESXMLDefaultCommands::initialize( argc, argv ) ;
243  BESDEBUG( "standalone", "ServerApp: done initializing default commands"
244  << endl ) ;
245 
246  BESDEBUG( "standalone", "ServerApp: initializing loaded modules ... "
247  << endl ) ;
248  int retval = BESModuleApp::initialize( argc, argv ) ;
249  BESDEBUG( "standalone", "ServerApp: done initializing loaded modules"
250  << endl ) ;
251  if( retval )
252  return retval ;
253  }
254  catch( BESError &e )
255  {
256  cerr << "Failed to initialize stand alone app" << endl ;
257  cerr << e.get_message() << endl ;
258  return 1 ;
259  }
260 
261  BESDEBUG( "standalone", "StandAloneApp: initialized settings:"
262  << endl << *this ) ;
263 
264  return 0 ;
265 }
266 
267 int
269 {
270  try
271  {
272  _client = new StandAloneClient ;
273  if( _outputStrm )
274  {
275  _client->setOutput( _outputStrm, true ) ;
276  }
277  else
278  {
279  _client->setOutput( &cout, false ) ;
280  }
281  BESDEBUG( "standalone", "OK" << endl ) ;
282  }
283  catch( BESError &e )
284  {
285  if( _client )
286  {
287  delete _client ;
288  _client = 0 ;
289  }
290  BESDEBUG( "standalone", "FAILED" << endl ) ;
291  cerr << "error starting the client" << endl ;
292  cerr << e.get_message() << endl ;
293  exit( 1 ) ;
294  }
295 
296  try
297  {
298  if( _cmd != "" )
299  {
300  _client->executeCommands( _cmd, _repeat ) ;
301  }
302  else if( _inputStrm )
303  {
304  _client->executeCommands( *_inputStrm, _repeat ) ;
305  }
306  else
307  {
308  _client->interact() ;
309  }
310  }
311  catch( BESError &e )
312  {
313  cerr << "error processing commands" << endl ;
314  cerr << e.get_message() << endl ;
315  }
316 
317  try
318  {
319  BESDEBUG( "standalone", "StandAloneApp: shutting down client ... "
320  << endl ) ;
321  if( _client )
322  {
323  delete _client ;
324  _client = 0 ;
325  }
326  BESDEBUG( "standalone", "OK" << endl ) ;
327 
328  BESDEBUG( "standalone", "StandAloneApp: closing input stream ... "
329  << endl ) ;
330  if( _createdInputStrm )
331  {
332  _inputStrm->close() ;
333  delete _inputStrm ;
334  _inputStrm = 0 ;
335  }
336  BESDEBUG( "standalone", "OK" << endl ) ;
337  }
338  catch( BESError &e )
339  {
340  BESDEBUG( "standalone", "FAILED" << endl ) ;
341  cerr << "error closing the client" << endl ;
342  cerr << e.get_message() << endl ;
343  return 1 ;
344  }
345 
346  return 0 ;
347 }
348 
354 int
356 {
357  BESDEBUG( "standalone", "ServerApp: terminating loaded modules ... "
358  << endl ) ;
359  BESModuleApp::terminate( sig ) ;
360  BESDEBUG( "standalone", "ServerApp: done terminating loaded modules"
361  << endl ) ;
362 
363  BESDEBUG( "standalone", "ServerApp: terminating default commands ... "
364  << endl ) ;
366  BESDEBUG( "standalone", "ServerApp: done terminating default commands"
367  << endl ) ;
368 
369  BESDEBUG( "standalone", "ServerApp: terminating default module ... "
370  << endl ) ;
372  BESDEBUG( "standalone", "ServerApp: done terminating default module"
373  << endl ) ;
374 
376 
377  return sig ;
378 }
379 
386 void
387 StandAloneApp::dump( ostream &strm ) const
388 {
389  strm << BESIndent::LMarg << "StandAloneApp::dump - ("
390  << (void *)this << ")" << endl ;
392  if( _client )
393  {
394  strm << BESIndent::LMarg << "client: " << endl ;
396  _client->dump( strm ) ;
398  }
399  else
400  {
401  strm << BESIndent::LMarg << "client: null" << endl ;
402  }
403  strm << BESIndent::LMarg << "command: " << _cmd << endl ;
404  strm << BESIndent::LMarg << "output stream: " << (void *)_outputStrm << endl ;
405  strm << BESIndent::LMarg << "input stream: " << (void *)_inputStrm << endl ;
406  strm << BESIndent::LMarg << "created input stream? " << _createdInputStrm << endl ;
407  BESBaseApp::dump( strm ) ;
409 }
410 
411 int
412 main( int argc, char **argv )
413 {
414  StandAloneApp app ;
415  return app.main( argc, argv ) ;
416 }
417 
void executeCommands(const string &cmd_list, int repeat)
Send the command(s) specified to the BES server after wrapping in request document.
virtual int run()
the applications functionality is implemented in the run method
void setOutput(ostream *strm, bool created)
Set the output stream for responses from the BES server.
static void SetUp(const string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:68
virtual ~StandAloneApp()
static int initialize(int argc, char **argv)
virtual void dump(ostream &strm) const
dumps information about this object
virtual int main(int argC, char **argV)
main method of the BES application
Definition: BESBaseApp.cc:74
static int terminate(void)
virtual int terminate(int sig=0)
clean up after the application
StandAloneClient is an object that handles the connection to, sending requests to, and receiving response from a specified OpenDAP server running either on this machine or another machine.
static int terminate(void)
Removes the default set of BES XML commands from the list of possible commands.
static void Indent()
Definition: BESIndent.cc:38
string appName(void) const
Returns the name of the application.
Definition: BESApp.h:132
virtual string get_message()
get the error message for this exception
Definition: BESError.h:94
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
static int initialize(int argc, char **argv)
Loads the default set of BES XML commands.
Abstract exception class for the BES with basic string message.
Definition: BESError.h:51
void interact()
An interactive BES client that takes BES requests on the command line.
static void Help(ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition: BESDebug.cc:163
static int terminate(void)
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESBaseApp.cc:140
Base application object for all BES applications.
Definition: BESModuleApp.h:59
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Definition: BESModuleApp.cc:70
virtual int terminate(int sig=0)
clean up after the application
static int initialize(int argc, char **argv)
virtual void dump(ostream &strm) const
dumps information about this object
int main(int argc, char **argv)
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
static void delete_all_catalogs()
static void UnIndent()
Definition: BESIndent.cc:44
static BESKeys * TheKeys()
Definition: TheBESKeys.cc:48
static string ConfigFile
Definition: TheBESKeys.h:50