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