bes Updated for version 3.20.10
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
34#include "config.h"
35
36#include <unistd.h>
37#include <getopt.h>
38#include <signal.h>
39
40#include <iostream>
41#include <string>
42#include <vector>
43#include <fstream>
44
45using std::cout;
46using std::cerr;
47using std::endl;
48using std::flush;
49using std::string;
50using std::vector;
51using std::ofstream;
52using std::ostream;
53using std::ifstream;
54
55#include "StandAloneApp.h"
56#include "StandAloneClient.h"
57#include "BESError.h"
58#include "BESDebug.h"
59#include "BESDefaultModule.h"
60#include "BESXMLDefaultCommands.h"
61#include "TheBESKeys.h"
62#include "BESCatalogUtils.h"
63#include "CmdTranslation.h"
64
65#define MODULE "standalone"
66#define prolog string("StandAloneApp::").append(__func__).append("() - ")
67
68StandAloneApp::StandAloneApp() :
69 BESModuleApp(), _cmd(""), _outputStrm(0), _repeat(0)
70{
71}
72
73StandAloneApp::~StandAloneApp()
74{
75 delete TheBESKeys::TheKeys();
76}
77
78void StandAloneApp::showVersion()
79{
80 cout << appName() << ": version 3.0" << endl;
81}
82
83void 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 " << endl;
89 cout << " to execute" << endl;
90 cout << " -i <file>, --inputfile=<file> - file with a sequence of input " << endl;
91 cout << " commands, may be used multiple times." << endl;
92 cout << " -f <file>, --outputfile=<file> - write output to this file" << endl;
93 cout << " -d, --debug - turn on debugging for the client session" << endl;
94 cout << " -r <num>, --repeat=<num> - repeat the command(s) <num> times" << endl;
95 cout << " -v, --version - return version information" << endl;
96 cout << " -?, --help - display help information" << endl;
97 cout << endl;
98 cout << "Note: You may provide a bes command with -x OR you may provide one " << endl;
99 cout << " or more BES command file names. One or the other, not neither, not both." << endl;
100 cout << endl;
101 BESDebug::Help(cout);
102}
103
104int 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 { "config", 1, 0, 'c' },
118 { "debug", 0, 0, 'd' },
119 { "version", 0, 0, 'v' },
120 { "execute", 1, 0, 'x' },
121 { "outputfile", 1, 0, 'f' },
122 { "inputfile", 1, 0, 'i' },
123 { "repeat", 1, 0, 'r' },
124 { "help", 0, 0, '?' },
125 { 0, 0, 0, 0 }
126 };
127 int option_index = 0;
128
129 while ((c = getopt_long(argc, argv, "?vc:d:x:f:i:r:", longopts, &option_index)) != -1) {
130 switch (c) {
131 case 'c':
132 TheBESKeys::ConfigFile = optarg;
133 break;
134 case 'd':
135 BESDebug::SetUp(optarg);
136 break;
137 case 'v': {
138 showVersion();
139 exit(0);
140 }
141 break;
142 case 'x':
143 _cmd = optarg;
144 break;
145 case 'f':
146 outputStr = optarg;
147 break;
148 case 'i':
149 _command_file_names.push_back(optarg);
150 break;
151 case 'r':
152 repeatStr = optarg;
153 break;
154 case '?': {
155 showUsage();
156 exit(0);
157 }
158 break;
159 }
160 }
161
162 if (outputStr != "") {
163 if (_cmd == "" && _command_file_names.empty()) {
164 cerr << "When specifying an output file you must either specify a command or an input file" << endl;
165 badUsage = true;
166 }
167 else if (_cmd != "" && !_command_file_names.empty()) {
168 cerr << "You must specify either a command or an input file on the command line, not both" << endl;
169 badUsage = true;
170 }
171 }
172
173 if (badUsage == true) {
174 showUsage();
175 return 1;
176 }
177
178 if (outputStr != "") {
179 _outputStrm = new ofstream(outputStr.c_str());
180 if (!(*_outputStrm)) {
181 cerr << "could not open the output file " << outputStr << endl;
182 badUsage = true;
183 }
184 }
185
186 if (!repeatStr.empty()) {
187 _repeat = atoi(repeatStr.c_str());
188 if (!_repeat && repeatStr != "0") {
189 cerr << "repeat number invalid: " << repeatStr << endl;
190 badUsage = true;
191 }
192 if (!_repeat) {
193 _repeat = 1;
194 }
195 }
196
197 if (badUsage == true) {
198 showUsage();
199 return 1;
200 }
201
202 try {
203 BESDEBUG(MODULE, prolog << "Initializing default module ... " << endl);
204 BESDefaultModule::initialize(argc, argv);
205 BESDEBUG(MODULE, prolog << "Done initializing default module" << endl);
206
207 BESDEBUG(MODULE, prolog << "Initializing default commands ... " << endl);
209 BESDEBUG(MODULE, prolog << "Done initializing default commands" << endl);
210
211 BESDEBUG(MODULE, prolog << "Initializing loaded modules ... " << endl);
212 int retval = BESModuleApp::initialize(argc, argv);
213 BESDEBUG(MODULE, prolog << "Done initializing loaded modules" << endl);
214 if (retval) return retval;
215 }
216 catch (BESError &e) {
217 cerr << prolog << "Failed to initialize stand alone app. Message : " << e.get_message() << endl;
218 return 1;
219 }
220
221 BESDEBUG(MODULE, prolog << "Initialized settings:" << endl << *this);
222
223 return 0;
224}
225
226
231{
233 string msg;
234 try {
235 if (_outputStrm) {
236 sac.setOutput(_outputStrm, true);
237 }
238 else {
239 sac.setOutput(&cout, false);
240 }
241 BESDEBUG(MODULE, prolog << "StandAloneClient instance created." << endl);
242 }
243 catch (BESError &e) {
244 msg = prolog + "FAILED to start StandAloneClient instance. Message: " + e.get_message();
245 BESDEBUG(MODULE, msg << endl);
246 cerr << msg << endl;
247 return 1;
248 }
249
250 try {
251 if (_cmd != "") {
252 sac.executeCommands(_cmd, _repeat);
253 }
254 else if (!_command_file_names.empty()) {
255 BESDEBUG(MODULE, prolog << "Found " << _command_file_names.size() << " command files." << endl);
256 for(unsigned index=0; index<_command_file_names.size(); index++){
257 string command_filename = _command_file_names[index];
258 BESDEBUG(MODULE, prolog << "Processing BES command file: " << command_filename<< endl);
259 if (!command_filename.empty()) {
260 ifstream cmdStrm(command_filename.c_str());
261 if (!cmdStrm.is_open()) {
262 cerr << prolog << "FAILED to open the input file '" << command_filename << "' SKIPPING." << endl;
263 }
264 else {
265 try {
266 sac.executeCommands(cmdStrm, _repeat);
267 }
268 catch (BESError &e) {
269 cerr << prolog << "Error processing commands. Message: " << e.get_message() << endl;
270 }
271 }
272 }
273 }
274 }
275 else {
276 sac.interact();
277 }
278 }
279 catch (BESError &e) {
280 cerr << prolog << "Error processing commands. Message: " << e.get_message() << endl;
281 }
282
283 return 0;
284}
285
292{
293 BESDEBUG(MODULE, "ServerApp: terminating loaded modules ... " << endl);
295 BESDEBUG(MODULE, "ServerApp: done terminating loaded modules" << endl);
296
297 BESDEBUG(MODULE, "ServerApp: terminating default commands ... " << endl);
299 BESDEBUG(MODULE, "ServerApp: done terminating default commands" << endl);
300
301 BESDEBUG(MODULE, "ServerApp: terminating default module ... " << endl);
302 BESDefaultModule::terminate();
303 BESDEBUG(MODULE, "ServerApp: done terminating default module" << endl);
304
305 CmdTranslation::terminate();
306
307 xmlCleanupParser();
308
309 return sig;
310}
311
318void StandAloneApp::dump(ostream &strm) const
319{
320 strm << BESIndent::LMarg << "StandAloneApp::dump - (" << (void *) this << ")" << endl;
321 BESIndent::Indent();
322
323 strm << BESIndent::LMarg << "command: " << _cmd << endl;
324 strm << BESIndent::LMarg << "output stream: " << (void *) _outputStrm << endl;
325 if(_command_file_names.empty()){
326 strm << BESIndent::LMarg << "No command filenames were identified." << endl;
327 }
328 else {
329 strm << BESIndent::LMarg << "Found " << _command_file_names.size() << " command file names." << endl;
330 BESIndent::Indent();
331 for (unsigned index = 0; index < _command_file_names.size(); index++) {
332 strm << BESIndent::LMarg << "command_filename["<<index<<"]: "<< _command_file_names[index] << endl;
333 }
334 BESIndent::UnIndent();
335 }
336 BESApp::dump(strm);
337 BESIndent::UnIndent();
338}
339
virtual void dump(std::ostream &strm) const =0
dumps information about this object
Definition: BESApp.cc:115
std::string appName(void) const
Returns the name of the application.
Definition: BESApp.h:128
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:98
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition: BESDebug.cc:162
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
Base application object for all BES applications.
Definition: BESModuleApp.h:56
virtual int terminate(int sig=0)
clean up after the application
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Definition: BESModuleApp.cc:69
static int terminate(void)
Removes the default set of BES XML commands from the list of possible commands.
static int initialize(int argc, char **argv)
Loads the default set of BES XML commands.
virtual int terminate(int sig=0)
clean up after the application
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
virtual int run()
The body of the application, implementing the primary functionality of the BES application.
void executeCommands(const std::string &cmd_list, int repeat)
Send the command(s) specified to the BES server after wrapping in request document.
void interact()
An interactive BES client that takes BES requests on the command line.
void setOutput(std::ostream *strm, bool created)
Set the output stream for responses from the BES server.
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:71
static std::string ConfigFile
Definition: TheBESKeys.h:185