bes  Updated for version 3.20.6
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 using std::ostream;
48 using std::ifstream;
49 
50 #include "StandAloneApp.h"
51 #include "StandAloneClient.h"
52 #include "BESError.h"
53 #include "BESDebug.h"
54 #include "BESDefaultModule.h"
55 #include "BESXMLDefaultCommands.h"
56 #include "TheBESKeys.h"
57 #include "BESCatalogUtils.h"
58 #include "CmdTranslation.h"
59 
60 StandAloneApp::StandAloneApp() :
61  BESModuleApp(), _client(0), _outputStrm(0), _inputStrm(0), _createdInputStrm( false), _repeat(0)
62 {
63 }
64 
65 StandAloneApp::~StandAloneApp()
66 {
67  if (_client) {
68  delete _client;
69  _client = 0;
70  }
71 
72  delete TheBESKeys::TheKeys();
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 
BESModuleApp::initialize
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Definition: BESModuleApp.cc:69
StandAloneApp::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: StandAloneApp.cc:317
TheBESKeys::ConfigFile
static std::string ConfigFile
Definition: TheBESKeys.h:149
BESModuleApp
Base application object for all BES applications.
Definition: BESModuleApp.h:56
BESError::get_message
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
StandAloneApp::run
virtual int run()
The body of the application, implementing the primary functionality of the BES application.
Definition: StandAloneApp.cc:220
BESApp::main
virtual int main(int argC, char **argV)
main routine, the main entry point for any BES applications.
Definition: BESApp.cc:54
BESModuleApp::terminate
virtual int terminate(int sig=0)
clean up after the application
Definition: BESModuleApp.cc:201
BESDebug::SetUp
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:64
TheBESKeys::TheKeys
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
BESXMLDefaultCommands::terminate
static int terminate(void)
Removes the default set of BES XML commands from the list of possible commands.
Definition: BESXMLDefaultCommands.cc:130
StandAloneClient
Definition: StandAloneClient.h:69
StandAloneApp
Definition: StandAloneApp.h:39
BESApp::dump
virtual void dump(std::ostream &strm) const =0
dumps information about this object
Definition: BESApp.cc:115
StandAloneApp::terminate
virtual int terminate(int sig=0)
clean up after the application
Definition: StandAloneApp.cc:290
BESDebug::Help
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition: BESDebug.cc:148
StandAloneClient::setOutput
void setOutput(std::ostream *strm, bool created)
Set the output stream for responses from the BES server.
Definition: StandAloneClient.cc:128
StandAloneApp::initialize
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Definition: StandAloneApp.cc:96
BESError
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
BESXMLDefaultCommands::initialize
static int initialize(int argc, char **argv)
Loads the default set of BES XML commands.
Definition: BESXMLDefaultCommands.cc:73