bes  Updated for version 3.19.1
StandAloneApp.cc
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 
58 StandAloneApp::StandAloneApp() :
59  BESModuleApp(), _client(0), _outputStrm(0), _inputStrm(0), _createdInputStrm( false), _repeat(0)
60 {
61 }
62 
63 StandAloneApp::~StandAloneApp()
64 {
65  if (_client) {
66  delete _client;
67  _client = 0;
68  }
69 
70  delete TheBESKeys::TheKeys();
71 
72  BESCatalogUtils::delete_all_catalogs();
73 }
74 
75 void StandAloneApp::showVersion()
76 {
77  cout << appName() << ": version 2.0" << endl;
78 }
79 
80 void StandAloneApp::showUsage()
81 {
82  cout << endl;
83  cout << appName() << ": the following options are available:" << endl;
84  cout << " -c <file>, --config=<file> - BES configuration file" << endl;
85  cout << " -x <command>, --execute=<command> - command for the server to execute" << endl;
86  cout << " -i <file>, --inputfile=<file> - file with a sequence of input commands" << endl;
87  cout << " -f <file>, --outputfile=<file> - write output to this file" << endl;
88  cout << " -d, --debug - turn on debugging for the client session" << endl;
89  cout << " -r <num>, --repeat=<num> - repeat the command(s) <num> times" << endl;
90  cout << " -v, --version - return version information" << endl;
91  cout << " -?, --help - display help information" << endl;
92  cout << endl;
93  BESDebug::Help(cout);
94 }
95 
96 int StandAloneApp::initialize(int argc, char **argv)
97 {
98  CmdTranslation::initialize(argc, argv);
99 
100  string outputStr = "";
101  string inputStr = "";
102  string repeatStr = "";
103 
104  bool badUsage = false;
105 
106  int c;
107 
108  static struct option longopts[] = { { "config", 1, 0, 'c' }, { "debug", 0, 0, 'd' }, { "version", 0, 0, 'v' }, {
109  "execute", 1, 0, 'x' }, { "outputfile", 1, 0, 'f' }, { "inputfile", 1, 0, 'i' }, { "repeat", 1, 0, 'r' }, {
110  "help", 0, 0, '?' }, { 0, 0, 0, 0 } };
111  int option_index = 0;
112 
113  while ((c = getopt_long(argc, argv, "?vc:d:x:f:i:r:", longopts, &option_index)) != -1) {
114  switch (c) {
115  case 'c':
116  TheBESKeys::ConfigFile = optarg;
117  break;
118  case 'd':
119  BESDebug::SetUp(optarg);
120  break;
121  case 'v': {
122  showVersion();
123  exit(0);
124  }
125  break;
126  case 'x':
127  _cmd = optarg;
128  break;
129  case 'f':
130  outputStr = optarg;
131  break;
132  case 'i':
133  inputStr = optarg;
134  break;
135  case 'r':
136  repeatStr = optarg;
137  break;
138  case '?': {
139  showUsage();
140  exit(0);
141  }
142  break;
143  }
144  }
145 
146  if (outputStr != "") {
147  if (_cmd == "" && inputStr == "") {
148  cerr << "When specifying an output file you must either " << "specify a command or an input file" << endl;
149  badUsage = true;
150  }
151  else if (_cmd != "" && inputStr != "") {
152  cerr << "You must specify either a command or an input file on " << "the command line, not both" << endl;
153  badUsage = true;
154  }
155  }
156 
157  if (badUsage == true) {
158  showUsage();
159  return 1;
160  }
161 
162  if (outputStr != "") {
163  _outputStrm = new ofstream(outputStr.c_str());
164  if (!(*_outputStrm)) {
165  cerr << "could not open the output file " << outputStr << endl;
166  badUsage = true;
167  }
168  }
169 
170  if (inputStr != "") {
171  _inputStrm = new ifstream(inputStr.c_str());
172  if (!(*_inputStrm)) {
173  cerr << "could not open the input file " << inputStr << endl;
174  badUsage = true;
175  }
176  _createdInputStrm = true;
177  }
178 
179  if (!repeatStr.empty()) {
180  _repeat = atoi(repeatStr.c_str());
181  if (!_repeat && repeatStr != "0") {
182  cerr << "repeat number invalid: " << repeatStr << endl;
183  badUsage = true;
184  }
185  if (!_repeat) {
186  _repeat = 1;
187  }
188  }
189 
190  if (badUsage == true) {
191  showUsage();
192  return 1;
193  }
194 
195  try {
196  BESDEBUG("standalone", "ServerApp: initializing default module ... " << endl);
197  BESDefaultModule::initialize(argc, argv);
198  BESDEBUG("standalone", "ServerApp: done initializing default module" << endl);
199 
200  BESDEBUG("standalone", "ServerApp: initializing default commands ... " << endl);
202  BESDEBUG("standalone", "ServerApp: done initializing default commands" << endl);
203 
204  BESDEBUG("standalone", "ServerApp: initializing loaded modules ... " << endl);
205  int retval = BESModuleApp::initialize(argc, argv);
206  BESDEBUG("standalone", "ServerApp: done initializing loaded modules" << endl);
207  if (retval) return retval;
208  }
209  catch (BESError &e) {
210  cerr << "Failed to initialize stand alone app" << endl;
211  cerr << e.get_message() << endl;
212  return 1;
213  }
214 
215  BESDEBUG("standalone", "StandAloneApp: initialized settings:" << endl << *this);
216 
217  return 0;
218 }
219 
221 {
222  try {
223  _client = new StandAloneClient;
224  if (_outputStrm) {
225  _client->setOutput(_outputStrm, true);
226  }
227  else {
228  _client->setOutput(&cout, false);
229  }
230  BESDEBUG("standalone", "OK" << endl);
231  }
232  catch (BESError &e) {
233  if (_client) {
234  delete _client;
235  _client = 0;
236  }
237  BESDEBUG("standalone", "FAILED" << endl);
238  cerr << "error starting the client" << endl;
239  cerr << e.get_message() << endl;
240  exit(1);
241  }
242 
243  try {
244  if (_cmd != "") {
245  _client->executeCommands(_cmd, _repeat);
246  }
247  else if (_inputStrm) {
248  _client->executeCommands(*_inputStrm, _repeat);
249  }
250  else {
251  _client->interact();
252  }
253  }
254  catch (BESError &e) {
255  cerr << "error processing commands" << endl;
256  cerr << e.get_message() << endl;
257  }
258 
259  try {
260  BESDEBUG("standalone", "StandAloneApp: shutting down client ... " << endl);
261  if (_client) {
262  delete _client;
263  _client = 0;
264  }
265  BESDEBUG("standalone", "OK" << endl);
266 
267  BESDEBUG("standalone", "StandAloneApp: closing input stream ... " << endl);
268  if (_createdInputStrm && _inputStrm) {
269  _inputStrm->close();
270  delete _inputStrm;
271  _inputStrm = 0;
272  }
273  BESDEBUG("standalone", "OK" << endl);
274  }
275  catch (BESError &e) {
276  BESDEBUG("standalone", "FAILED" << endl);
277  cerr << "error closing the client" << endl;
278  cerr << e.get_message() << endl;
279  return 1;
280  }
281 
282  return 0;
283 }
284 
291 {
292  BESDEBUG("standalone", "ServerApp: terminating loaded modules ... " << endl);
294  BESDEBUG("standalone", "ServerApp: done terminating loaded modules" << endl);
295 
296  BESDEBUG("standalone", "ServerApp: terminating default commands ... " << endl);
298  BESDEBUG("standalone", "ServerApp: done terminating default commands" << endl);
299 
300  BESDEBUG("standalone", "ServerApp: terminating default module ... " << endl);
301  BESDefaultModule::terminate();
302  BESDEBUG("standalone", "ServerApp: done terminating default module" << endl);
303 
304  CmdTranslation::terminate();
305 
306  xmlCleanupParser();
307 
308  return sig;
309 }
310 
317 void StandAloneApp::dump(ostream &strm) const
318 {
319  strm << BESIndent::LMarg << "StandAloneApp::dump - (" << (void *) this << ")" << endl;
320  BESIndent::Indent();
321  if (_client) {
322  strm << BESIndent::LMarg << "client: " << endl;
323  BESIndent::Indent();
324  _client->dump(strm);
325  BESIndent::UnIndent();
326  }
327  else {
328  strm << BESIndent::LMarg << "client: null" << endl;
329  }
330  strm << BESIndent::LMarg << "command: " << _cmd << endl;
331  strm << BESIndent::LMarg << "output stream: " << (void *) _outputStrm << endl;
332  strm << BESIndent::LMarg << "input stream: " << (void *) _inputStrm << endl;
333  strm << BESIndent::LMarg << "created input stream? " << _createdInputStrm << endl;
334  BESApp::dump(strm);
335  BESIndent::UnIndent();
336 }
337 
338 int main(int argc, char **argv)
339 {
340  try {
341  StandAloneApp app;
342  return app.main(argc, argv);
343  }
344  catch (BESError &e) {
345  cerr << "Caught BES Error while starting the command processor: " << e.get_message() << endl;
346  return 1;
347  }
348  catch (std::exception &e) {
349  cerr << "Caught C++ error while starting the command processor: " << e.what() << endl;
350  return 2;
351  }
352  catch (...) {
353  cerr << "Caught unknown error while starting the command processor." << endl;
354  return 3;
355  }
356 }
357 
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 body of the application, implementing the primary functionality of the BES application.
void setOutput(ostream *strm, bool created)
Set the output stream for responses from the BES server.
virtual void dump(ostream &strm) const
dumps information about this object
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:97
virtual void dump(std::ostream &strm) const =0
dumps information about this object
Definition: BESApp.cc:114
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:64
virtual int terminate(int sig=0)
clean up after the application
static int terminate(void)
Removes the default set of BES XML commands from the list of possible commands.
virtual void dump(ostream &strm) const
dumps information about this object
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:56
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
void interact()
An interactive BES client that takes BES requests on the command line.
virtual int main(int argC, char **argV)
main routine, the main entry point for any BES applications.
Definition: BESApp.cc:53
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition: BESDebug.cc:159
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
string appName(void) const
Returns the name of the application.
Definition: BESApp.h:134
virtual int terminate(int sig=0)
clean up after the application
static string ConfigFile
Definition: TheBESKeys.h:145