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