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