bes Updated for version 3.20.10
DebugFunctions.cc
1// UgridFunctions.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) 2013 OPeNDAP, Inc.
7// Author: James Gallagher <jgallagher@opendap.org>
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 OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25#include "config.h"
26
27#include <sstream> // std::stringstream
28#include <stdlib.h> /* abort, NULL */
29#include <iostream>
30#include <signal.h>
31
32#include <sys/time.h>
33#include <unistd.h>
34
35#include "DebugFunctions.h"
36
37#include <libdap/ServerFunctionsList.h>
38#include "BESDebug.h"
39#include <libdap/Int32.h>
40#include <libdap/Structure.h>
41#include <libdap/Str.h>
42#include <BESError.h>
43#include <BESInternalError.h>
44#include <BESInternalFatalError.h>
45#include <BESSyntaxUserError.h>
46#include <BESForbiddenError.h>
47#include <BESNotFoundError.h>
48#include <BESTimeoutError.h>
49
50namespace debug_function {
51
52static string getFunctionNames()
53{
54 vector<string> names;
55 libdap::ServerFunctionsList::TheList()->getFunctionNames(&names);
56
57 string msg;
58 for (std::vector<string>::iterator it = names.begin(); it != names.end(); ++it) {
59 if (!msg.empty()) msg += ", ";
60
61 msg += *it;
62 }
63
64 return msg;
65}
66
67void DebugFunctions::initialize(const string &/*modname*/)
68{
69 BESDEBUG("DebugFunctions", "initialize() - BEGIN" << std::endl);
70 BESDEBUG("DebugFunctions", "initialize() - function names: " << getFunctionNames() << std::endl);
71
73 libdap::ServerFunctionsList::TheList()->add_function(abortFunc);
74
76 libdap::ServerFunctionsList::TheList()->add_function(sleepFunc);
77
79 libdap::ServerFunctionsList::TheList()->add_function(sumUntilFunc);
80
82 libdap::ServerFunctionsList::TheList()->add_function(errorFunc);
83
84 BESDEBUG("DebugFunctions", "initialize() - function names: " << getFunctionNames() << std::endl);
85
86 BESDEBUG("DebugFunctions", "initialize() - END" << std::endl);
87}
88
89void DebugFunctions::terminate(const string &/*modname*/)
90{
91 BESDEBUG("DebugFunctions", "Removing DebugFunctions Modules (this does nothing)." << std::endl);
92}
93
100void DebugFunctions::dump(ostream &strm) const
101{
102 strm << BESIndent::LMarg << "DebugFunctions::dump - (" << (void *) this << ")" << std::endl;
103}
104
105/*****************************************************************************************
106 *
107 * Abort Function (Debug Functions)
108 *
109 * This server side function calls abort(). (boom)
110 *
111 */
112string abort_usage = "abort(##) Where ## is the number of milliseconds to sleep before calling abort.";
113AbortFunc::AbortFunc()
114{
115 setName("abort");
116 setDescriptionString((string) "This function calls abort() killing the beslistner process.");
117 setUsageString(abort_usage);
118 setRole("http://services.opendap.org/dap4/server-side-function/debug/abort"); // 11/18/20 SBL - https not supported
119 setDocUrl("https://docs.opendap.org/index.php/Debug_Functions");
120 setFunction(debug_function::abort_ssf);
121 setVersion("1.0");
122}
123
124void abort_ssf(int argc, libdap::BaseType * argv[], libdap::DDS &, libdap::BaseType **btpp)
125{
126
127 std::stringstream msg;
128 libdap::Str *response = new libdap::Str("info");
129 *btpp = response;
130
131 if (argc != 1) {
132 msg << "Missing time parameter! USAGE: " << abort_usage;
133 }
134 else {
135 libdap::Int32 *param1 = dynamic_cast<libdap::Int32*>(argv[0]);
136 if (param1) {
137 libdap::dods_int32 milliseconds = param1->value();
138
139 msg << "abort in " << milliseconds << "ms" << endl;
140 response->set_value(msg.str());
141
142 usleep(milliseconds * 1000);
143 msg << "abort now. " << endl;
144 abort();
145 return;
146 }
147 else {
148 msg << "This function only accepts integer values " << "for the time (in milliseconds) parameter. USAGE: "
149 << abort_usage;
150 }
151
152 }
153
154 response->set_value(msg.str());
155 return;
156}
157
158/*****************************************************************************************
159 *
160 * Sleep Function (Debug Functions)
161 *
162 * This server side function calls sleep() for the number
163 * of millisecs passed in at argv[0]. (Zzzzzzzzzzzzzzz)
164 *
165 */
166
167string sleep_usage = "sleep(##) where ## is the number of milliseconds to sleep.";
168SleepFunc::SleepFunc()
169{
170 setName("sleep");
171 setDescriptionString((string) "This function calls sleep() for the specified number of millisecs.");
172 setUsageString(sleep_usage);
173 setRole("http://services.opendap.org/dap4/server-side-function/debug/sleep"); // 11/18/20 SBL - https not supported
174 setDocUrl("https://docs.opendap.org/index.php/Debug_Functions");
175 setFunction(debug_function::sleep_ssf);
176 setVersion("1.0");
177}
178
179void sleep_ssf(int argc, libdap::BaseType * argv[], libdap::DDS &, libdap::BaseType **btpp)
180{
181
182 std::stringstream msg;
183 libdap::Str *sleep_info = new libdap::Str("info");
184
185 //libdap::Structure *sleepResult = new libdap::Structure("sleep_result_unwrap");
186 //sleepResult->add_var_nocopy(sleep_info);
187 //*btpp = sleepResult;
188
189 *btpp = sleep_info;
190
191 if (argc != 1) {
192 msg << "Missing time parameter! USAGE: " << sleep_usage;
193 }
194 else {
195 libdap::Int32 *param1 = dynamic_cast<libdap::Int32*>(argv[0]);
196 if (param1) {
197 libdap::dods_int32 milliseconds = param1->value();
198 usleep(milliseconds * 1000);
199 msg << "Slept for " << milliseconds << " ms.";
200 }
201 else {
202 msg << "This function only accepts integer values " << "for the time (in milliseconds) parameter. USAGE: "
203 << sleep_usage;
204 }
205
206 }
207
208 sleep_info->set_value(msg.str());
209
210 /*
211 for (libdap::DDS::Vars_iter it = dds.var_begin(); it != dds.var_end(); ++it) {
212 libdap::BaseType *pBT = *it;
213 sleepResult->add_var(pBT);
214 }
215 */
216
217 return;
218}
219
220/*****************************************************************************************
221 *
222 * SumUntil (Debug Functions)
223 *
224 * This server side function computes a sum until the number of
225 * millisecs (passed in at argv[0]) has transpired. (+,+...+).
226 *
227 * @note Modified so that the actual sum value can be printed or not.
228 * When this is used in tests, the value reached can vary, so to make
229 * checking for success/failure, the value can be omitted.
230 *
231 */
232
233string sum_until_usage = "sum_until(<val> [,0|<true>]) Compute a sum until <val> of milliseconds has elapsed; 0|<true> print the sum value.";
234SumUntilFunc::SumUntilFunc()
235{
236 setName("sum_until");
237 setDescriptionString((string) "This function calls sleep() for the specified number of millisecs.");
238 setUsageString(sum_until_usage);
239 setRole("http://services.opendap.org/dap4/server-side-function/debug/sum_until"); // 11/18/20 SBL - https not supported
240 setDocUrl("https://docs.opendap.org/index.php/Debug_Functions");
241 setFunction(debug_function::sum_until_ssf);
242 setVersion("1.0");
243}
244
245void sum_until_ssf(int argc, libdap::BaseType * argv[], libdap::DDS &, libdap::BaseType **btpp)
246{
247
248 std::stringstream msg;
249 libdap::Str *response = new libdap::Str("info");
250 *btpp = response;
251
252 if (!(argc == 1 || argc == 2)) {
253 msg << "Missing time parameter! USAGE: " << sum_until_usage;
254
255 response->set_value(msg.str());
256 return;
257 }
258
259 libdap::Int32 *param1 = dynamic_cast<libdap::Int32*>(argv[0]);
260 // param1 is required
261 if (!param1) {
262 msg << "This function only accepts integer values " << "for the time (in milliseconds) parameter. USAGE: "
263 << sum_until_usage;
264
265 response->set_value(msg.str());
266 return;
267 }
268
269 bool print_sum_value = true;
270 // argument #2 is optional
271 if (argc == 2) {
272 libdap::Int32 *temp = dynamic_cast<libdap::Int32*>(argv[1]);
273 if (temp && temp->value() == 0)
274 print_sum_value = false;
275 }
276
277 libdap::dods_int32 milliseconds = param1->value();
278
279 struct timeval tv;
280 gettimeofday(&tv, NULL);
281 double start_time = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000; // convert tv_sec & tv_usec to millisecond
282 double end_time = start_time;
283
284 long fib;
285 long one_past = 1;
286 long two_past = 0;
287 long n = 1;
288
289 bool done = false;
290 while (!done) {
291 n++;
292 fib = one_past + two_past;
293 two_past = one_past;
294 one_past = fib;
295 gettimeofday(&tv, NULL);
296 end_time = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000; // convert tv_sec & tv_usec to millisecond
297 if (end_time - start_time >= milliseconds) {
298 done = true;
299 }
300 }
301
302 if (!print_sum_value)
303 msg << "Summed for " << end_time - start_time << " ms.";
304 else
305 msg << "Summed for " << end_time - start_time << " ms. n: " << n;
306
307 response->set_value(msg.str());
308 return;
309}
310
311/*****************************************************************************************
312 *
313 * Error Function (Debug Functions)
314 *
315 * This server side function calls calls sleep() for the number
316 * of ms passed in at argv[0]. (Zzzzzzzzzzzzzzz)
317 *
318 */
319string error_usage = "error(##) where ## is the BESError type to generate.";
320ErrorFunc::ErrorFunc()
321{
322 setName("error");
323 setDescriptionString((string) "This function triggers a BES Error of the type specified");
324 setUsageString(error_usage);
325 setRole("http://services.opendap.org/dap4/server-side-function/debug/error"); // 11/18/20 SBL - https not supported
326 setDocUrl("https://docs.opendap.org/index.php/Debug_Functions");
327 setFunction(debug_function::error_ssf);
328 setVersion("1.0");
329}
330
331void error_ssf(int argc, libdap::BaseType * argv[], libdap::DDS &, libdap::BaseType **btpp)
332{
333
334 std::stringstream msg;
335 libdap::Str *response = new libdap::Str("info");
336 *btpp = response;
337
338 string location = "error_ssf";
339
340 if (argc != 1) {
341 msg << "Missing error type parameter! USAGE: " << error_usage;
342 }
343 else {
344 libdap::Int32 *param1 = dynamic_cast<libdap::Int32*>(argv[0]);
345 if (param1) {
346 libdap::dods_int32 error_type = param1->value();
347
348 switch (error_type) {
349
350 case BES_INTERNAL_ERROR: {
351 msg << "A BESInternalError was requested.";
352 BESInternalError error(msg.str(), location, 0);
353 throw error;
354 }
355 break;
356
357 case BES_INTERNAL_FATAL_ERROR: {
358 msg << "A BESInternalFatalError was requested.";
359 BESInternalFatalError error(msg.str(), location, 0);
360 throw error;
361 }
362 break;
363
364 case BES_SYNTAX_USER_ERROR: {
365 msg << "A BESSyntaxUserError was requested.";
366 BESSyntaxUserError error(msg.str(), location, 0);
367 throw error;
368 }
369 break;
370
371 case BES_FORBIDDEN_ERROR: {
372 msg << "A BESForbiddenError was requested.";
373 BESForbiddenError error(msg.str(), location, 0);
374 throw error;
375 }
376 break;
377
378 case BES_NOT_FOUND_ERROR: {
379 msg << "A BESNotFoundError was requested.";
380 BESNotFoundError error(msg.str(), location, 0);
381 throw error;
382 }
383 break;
384
385 case BES_TIMEOUT_ERROR: {
386 msg << "A BESTimeOutError was requested.";
387 BESTimeoutError error(msg.str(), location, 0);
388 throw error;
389 }
390 break;
391
392 case 666: {
393 msg << "A Segmentation Fault has been requested.";
394 cerr << msg.str() << endl;
395 raise(SIGSEGV);
396 }
397 break;
398
399 default:
400 msg << "An unrecognized error_type parameter was received. Requested error_type: " << error_type;
401 break;
402 }
403
404 }
405 else {
406 msg << "This function only accepts integer values " << "for the error type parameter. USAGE: "
407 << error_usage;
408 }
409
410 }
411
412 response->set_value(msg.str());
413 return;
414
415}
416
417} // namespace debug_function
418
419extern "C" {
420BESAbstractModule *maker()
421{
423}
424}
error thrown if the BES is not allowed to access the resource requested
exception thrown if internal error encountered
exception thrown if an internal error is found and is fatal to the BES
error thrown if the resource requested cannot be found
error thrown if there is a user syntax error in the request or any other user error
error thrown if there is a user syntax error in the request or any other user error
virtual void dump(ostream &strm) const
dumps information about this object