bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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 <getopt.h>
37
38#include <iostream>
39#include <string>
40#include <vector>
41
42#include <libxml/parser.h>
43
44#include "StandAloneApp.h"
45#include "StandAloneClient.h"
46#include "BESError.h"
47#include "BESDebug.h"
48#include "BESDefaultModule.h"
49#include "BESXMLDefaultCommands.h"
50#include "TheBESKeys.h"
51#include "CmdTranslation.h"
52
53#define MODULE "standalone"
54#define prolog string("StandAloneApp::").append(__func__).append("() - ")
55
56using namespace std;
57
58void StandAloneApp::showVersion()
59{
60 cout << appName() << ": version 3.0" << endl;
61}
62
63void StandAloneApp::showUsage()
64{
65 cout << endl;
66 cout << appName() << ": the following options are available:" << endl;
67 cout << " -c <file>, --config=<file> - BES configuration file" << endl;
68 cout << " -x <command>, --execute=<command> - command for the server " << endl;
69 cout << " to execute" << endl;
70 cout << " -i <file>, --inputfile=<file> - file with a sequence of input " << endl;
71 cout << " commands, may be used multiple times." << endl;
72 cout << " -f <file>, --outputfile=<file> - write output to this file" << endl;
73 cout << " -d, --debug - turn on debugging for the client session" << endl;
74 cout << " -r <num>, --repeat=<num> - repeat the command(s) <num> times" << endl;
75 cout << " -v, --version - return version information" << endl;
76 cout << " -?, --help - display help information" << endl;
77 cout << endl;
78 cout << "Note: You may provide a bes command with -x OR you may provide one " << endl;
79 cout << " or more BES command file names. One or the other, not neither, not both." << endl;
80 cout << endl;
81 BESDebug::Help(cout);
82}
83
84int StandAloneApp::initialize(int argc, char **argv)
85{
86 CmdTranslation::initialize(argc, argv);
87
88 static struct option longopts[] = {
89 { "config", 1, 0, 'c' },
90 { "debug", 0, 0, 'd' },
91 { "version", 0, 0, 'v' },
92 { "execute", 1, 0, 'x' },
93 { "outputfile", 1, 0, 'f' },
94 { "inputfile", 1, 0, 'i' },
95 { "repeat", 1, 0, 'r' },
96 { "help", 0, 0, '?' },
97 { 0, 0, 0, 0 }
98 };
99
100 string outputStr;
101 string repeatStr;
102 int option_index = 0;
103 int c;
104 while ((c = getopt_long(argc, argv, "?vc:d:x:f:i:r:", longopts, &option_index)) != -1) {
105 switch (c) {
106 case 'c':
107 TheBESKeys::ConfigFile = optarg;
108 break;
109 case 'd':
110 BESDebug::SetUp(optarg);
111 break;
112 case 'x':
113 _cmd = optarg;
114 break;
115 case 'f':
116 outputStr = optarg;
117 break;
118 case 'i':
119 _command_file_names.emplace_back(optarg);
120 break;
121 case 'r':
122 repeatStr = optarg;
123 break;
124 case 'v':
125 showVersion();
126 exit(0);
127 case '?':
128 default:
129 showUsage();
130 exit(0);
131 }
132 }
133
134 bool badUsage = false;
135 if (!outputStr.empty()) {
136 if (_cmd.empty() && _command_file_names.empty()) {
137 cerr << "When specifying an output file you must either specify a command or an input file" << endl;
138 badUsage = true;
139 }
140 else if (!_cmd.empty() && !_command_file_names.empty()) {
141 cerr << "You must specify either a command or an input file on the command line, not both" << endl;
142 badUsage = true;
143 }
144 }
145
146 if (badUsage) {
147 showUsage();
148 return 1;
149 }
150
151 if (!outputStr.empty()) {
152 _outputStrm = new ofstream(outputStr.c_str());
153 if (!(*_outputStrm)) {
154 cerr << "could not open the output file " << outputStr << endl;
155 badUsage = true;
156 }
157 }
158
159 if (!repeatStr.empty()) {
160 _repeat = atoi(repeatStr.c_str());
161 if (!_repeat && repeatStr != "0") {
162 cerr << "repeat number invalid: " << repeatStr << endl;
163 badUsage = true;
164 }
165 if (!_repeat) {
166 _repeat = 1;
167 }
168 }
169
170 if (badUsage) {
171 showUsage();
172 return 1;
173 }
174
175 try {
176 BESDEBUG(MODULE, prolog << "Initializing default module ... " << endl);
177 BESDefaultModule::initialize(argc, argv);
178 BESDEBUG(MODULE, prolog << "Done initializing default module" << endl);
179
180 BESDEBUG(MODULE, prolog << "Initializing default commands ... " << endl);
182 BESDEBUG(MODULE, prolog << "Done initializing default commands" << endl);
183
184 BESDEBUG(MODULE, prolog << "Initializing loaded modules ... " << endl);
185 int retval = BESModuleApp::initialize(argc, argv);
186 BESDEBUG(MODULE, prolog << "Done initializing loaded modules" << endl);
187 if (retval) return retval;
188 }
189 catch (BESError &e) {
190 cerr << prolog << "Failed to initialize stand alone app. Message : " << e.get_message() << endl;
191 return 1;
192 }
193
194 BESDEBUG(MODULE, prolog << "Initialized settings:" << endl << *this);
195
196 return 0;
197}
198
199
204{
206 string msg;
207 try {
208 if (_outputStrm) {
209 sac.setOutput(_outputStrm, true);
210 }
211 else {
212 sac.setOutput(&cout, false);
213 }
214 BESDEBUG(MODULE, prolog << "StandAloneClient instance created." << endl);
215 }
216 catch (BESError &e) {
217 msg = prolog + "FAILED to start StandAloneClient instance. Message: " + e.get_message();
218 BESDEBUG(MODULE, msg << endl);
219 cerr << msg << endl;
220 return 1;
221 }
222
223 try {
224 if (!_cmd.empty()) {
225 sac.executeCommands(_cmd, _repeat);
226 }
227 else if (!_command_file_names.empty()) {
228 BESDEBUG(MODULE, prolog << "Found " << _command_file_names.size() << " command files." << endl);
229 unsigned int commands = 0;
230 for (auto &command_filename: _command_file_names) {
231 commands++;
232 BESDEBUG(MODULE, prolog << "Processing BES command file: " << command_filename<< endl);
233 if (!command_filename.empty()) {
234 ifstream cmdStrm(command_filename);
235 if (!cmdStrm.is_open()) {
236 cerr << prolog << "FAILED to open the input file '" << command_filename << "' SKIPPING." << endl;
237 }
238 else {
239 try {
240 sac.executeCommands(cmdStrm, _repeat);
241 if (commands < _command_file_names.size()) {
242 sac.getOutput() << "\nNext-Response:\n" << flush;
243 }
244 }
245 catch (BESError &e) {
246 cerr << prolog << "Error processing commands. Message: " << e.get_message() << endl;
247 }
248 }
249 }
250 }
251 }
252 else {
253 sac.interact();
254 }
255 }
256 catch (BESError &e) {
257 cerr << prolog << "Error processing commands. Message: " << e.get_message() << endl;
258 }
259
260 return 0;
261}
262
269{
270 BESDEBUG(MODULE, "ServerApp: terminating loaded modules ... " << endl);
272 BESDEBUG(MODULE, "ServerApp: done terminating loaded modules" << endl);
273
274 BESDEBUG(MODULE, "ServerApp: terminating default commands ... " << endl);
276 BESDEBUG(MODULE, "ServerApp: done terminating default commands" << endl);
277
278 BESDEBUG(MODULE, "ServerApp: terminating default module ... " << endl);
279 BESDefaultModule::terminate();
280 BESDEBUG(MODULE, "ServerApp: done terminating default module" << endl);
281
282 CmdTranslation::terminate();
283
284 xmlCleanupParser();
285
286 return sig;
287}
288
295void StandAloneApp::dump(ostream &strm) const
296{
297 strm << BESIndent::LMarg << "StandAloneApp::dump - (" << (void *) this << ")" << endl;
298 BESIndent::Indent();
299
300 strm << BESIndent::LMarg << "command: " << _cmd << endl;
301 strm << BESIndent::LMarg << "output stream: " << (void *) _outputStrm << endl;
302 if(_command_file_names.empty()){
303 strm << BESIndent::LMarg << "No command filenames were identified." << endl;
304 }
305 else {
306 strm << BESIndent::LMarg << "Found " << _command_file_names.size() << " command file names." << endl;
307 BESIndent::Indent();
308 for (unsigned index = 0; index < _command_file_names.size(); index++) {
309 strm << BESIndent::LMarg << "command_filename["<<index<<"]: "<< _command_file_names[index] << endl;
310 }
311 BESIndent::UnIndent();
312 }
313 BESApp::dump(strm);
314 BESIndent::UnIndent();
315}
316
std::string appName() const
Returns the name of the application.
Definition BESApp.h:130
void dump(std::ostream &strm) const override=0
dumps information about this object
Definition BESApp.cc:113
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition BESDebug.cc:91
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition BESDebug.cc:173
Base exception class for the BES with basic string message.
Definition BESError.h:66
std::string get_message() const
get the error message for this exception
Definition BESError.h:132
int terminate(int sig=0) override
clean up after the application
int initialize(int argC, char **argV) override
Load and initialize any BES modules.
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.
int terminate(int sig=0) override
clean up after the application
int initialize(int argC, char **argV) override
Load and initialize any BES modules.
void dump(std::ostream &strm) const override
dumps information about this object
int run() override
The body of the application, implementing the primary functionality of the BES application.
static std::string ConfigFile
Definition TheBESKeys.h:117