bes  Updated for version 3.20.5
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 }
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
exception thrown if an internal error is found and is fatal to the BES
exception thrown if inernal error encountered
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
error thrown if the BES is not allowed to access the resource requested