artdaq  v3_08_00
xmlrpc_commander.cc
1 /* DarkSide 50 DAQ program
2  * This file add the xmlrpc commander as a client to the SC
3  * Author: Alessandro Razeto <Alessandro.Razeto@ge.infn.it>
4  */
5 
6 #pragma GCC diagnostic push
7 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
8 #define _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES 1
9 #include <xmlrpc-c/base.hpp>
10 #include <xmlrpc-c/client_simple.hpp>
11 #include <xmlrpc-c/girerr.hpp>
12 #include <xmlrpc-c/registry.hpp>
13 #include <xmlrpc-c/server_abyss.hpp>
14 #undef _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
15 #pragma GCC diagnostic pop
16 #include <cstdint>
17 #include <iostream>
18 #include <limits>
19 #include <memory>
20 #include <stdexcept>
21 #include "artdaq/DAQdata/Globals.hh"
22 #define TRACE_NAME (app_name + "_xmlrpc_commander").c_str()
23 #include "tracemf.h"
24 
25 #include <errno.h>
26 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <cstring>
29 #include <exception>
30 #include "artdaq-core/Utilities/ExceptionHandler.hh"
31 
32 #include "canvas/Persistency/Provenance/RunID.h"
33 #include "fhiclcpp/make_ParameterSet.h"
34 
35 #include "artdaq/ExternalComms/xmlrpc_commander.hh"
36 //#include "artdaq/Application/LoadParameterSet.hh"
37 
38 namespace {
42 class env_wrap
43 {
44 public:
45  env_wrap() { xmlrpc_env_init(&this->env_c); };
46  ~env_wrap() { xmlrpc_env_clean(&this->env_c); };
47  xmlrpc_env env_c;
48 };
49 } // namespace
50 static xmlrpc_c::paramList
51 pListFromXmlrpcArray(xmlrpc_value* const arrayP)
52 {
53  env_wrap env;
54  XMLRPC_ASSERT_ARRAY_OK(arrayP);
55  unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP);
56  assert(!env.env_c.fault_occurred);
57  xmlrpc_c::paramList paramList(arraySize);
58  for (unsigned int i = 0; i < arraySize; ++i)
59  {
60  xmlrpc_value* arrayItemP;
61  xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP);
62  assert(!env.env_c.fault_occurred);
63  paramList.add(xmlrpc_c::value(arrayItemP));
64  xmlrpc_DECREF(arrayItemP);
65  }
66  return paramList;
67 }
68 static xmlrpc_value*
69 c_executeMethod(xmlrpc_env* const envP,
70  xmlrpc_value* const paramArrayP,
71  void* const methodPtr,
72  void* const callInfoPtr)
73 {
74  xmlrpc_c::method* const methodP(static_cast<xmlrpc_c::method*>(methodPtr));
75  xmlrpc_c::paramList const paramList(pListFromXmlrpcArray(paramArrayP));
76  xmlrpc_c::callInfo* const callInfoP(static_cast<xmlrpc_c::callInfo*>(callInfoPtr));
77  xmlrpc_value* retval;
78  retval = NULL; // silence used-before-set warning
79  try
80  {
81  xmlrpc_c::value result;
82  try
83  {
84  xmlrpc_c::method2* const method2P(dynamic_cast<xmlrpc_c::method2*>(methodP));
85  if (method2P)
86  method2P->execute(paramList, callInfoP, &result);
87  else
88  methodP->execute(paramList, &result);
89  }
90  catch (xmlrpc_c::fault const& fault)
91  {
92  xmlrpc_env_set_fault(envP, fault.getCode(),
93  fault.getDescription().c_str());
94  }
95  if (!envP->fault_occurred)
96  {
97  if (result.isInstantiated())
98  retval = result.cValue();
99  else
100  girerr::throwf(
101  "Xmlrpc-c user's xmlrpc_c::method object's "
102  "'execute method' failed to set the RPC result "
103  "value.");
104  }
105  }
106  catch (std::exception const& e)
107  {
108  xmlrpc_faultf(envP,
109  "Unexpected error executing code for "
110  "particular method, detected by Xmlrpc-c "
111  "method registry code. Method did not "
112  "fail; rather, it did not complete at all. %s",
113  e.what());
114  }
115  catch (...)
116  {
117  xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
118  "Unexpected error executing code for "
119  "particular method, detected by Xmlrpc-c "
120  "method registry code. Method did not "
121  "fail; rather, it did not complete at all.");
122  }
123  return retval;
124 }
125 
126 namespace artdaq {
133 std::string exception_msg(const std::runtime_error& er,
134  const std::string& helpText = "execute request")
135 {
136  std::string msg("Exception when trying to ");
137  msg.append(helpText);
138  msg.append(": ");
139  msg.append(er.what()); //std::string(er.what ()).substr (2);
140  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
141  return msg;
142 }
143 
150 std::string exception_msg(const art::Exception& er,
151  const std::string& helpText)
152 {
153  std::string msg("Exception when trying to ");
154  msg.append(helpText);
155  msg.append(": ");
156  msg.append(er.what());
157  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
158  return msg;
159 }
160 
167 std::string exception_msg(const cet::exception& er,
168  const std::string& helpText)
169 {
170  std::string msg("Exception when trying to ");
171  msg.append(helpText);
172  msg.append(": ");
173  msg.append(er.what());
174  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
175  return msg;
176 }
177 
184 std::string exception_msg(const std::string& erText,
185  const std::string& helpText)
186 {
187  std::string msg("Exception when trying to ");
188  msg.append(helpText);
189  msg.append(": ");
190  msg.append(erText);
191  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
192  return msg;
193 }
194 
212 class cmd_ : public xmlrpc_c::method
213 {
214 public:
215  // Can't seem to initialize "_signature" and "_help" in the initialization list...
222  cmd_(xmlrpc_commander& c, const std::string& signature, const std::string& description)
223  : _c(c)
224  {
225  _signature = signature;
226  _help = description;
227  }
228 
234  void execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) final;
235 
236 protected:
238 
244  virtual bool execute_(const xmlrpc_c::paramList&, xmlrpc_c::value* const retvalP) = 0;
245 
255  template<typename T>
256  T getParam(const xmlrpc_c::paramList& paramList, int index);
257 
281  template<typename T>
282  T getParam(const xmlrpc_c::paramList& paramList, int index, T default_value);
283 };
284 
285 // Users are only allowed to call getParam for predefined types; see
286 // template specializations below this default function
287 
288 template<typename T>
289 T cmd_::getParam(const xmlrpc_c::paramList&, int)
290 {
291  throw cet::exception("cmd_") << "Error in cmd_::getParam(): value type not supported" << std::endl;
292 }
293 
302 template<>
303 uint64_t cmd_::getParam<uint64_t>(const xmlrpc_c::paramList& paramList, int index)
304 {
305  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint64_t.";
306  TLOG(TLVL_TRACE) << "Param value: " << paramList.getI8(index);
307  return static_cast<uint64_t>(paramList.getI8(index));
308 }
309 
318 template<>
319 uint32_t cmd_::getParam<uint32_t>(const xmlrpc_c::paramList& paramList, int index)
320 {
321  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint32_t.";
322  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
323  return static_cast<uint32_t>(paramList.getInt(index));
324 }
325 
334 template<>
335 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
336 {
337  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as string.";
338  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
339  return static_cast<std::string>(paramList.getString(index));
340 }
341 
350 template<>
351 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
352 {
353  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as Run Number.";
354  art::RunNumber_t run_number;
355  try {
356  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
357  run_number = art::RunNumber_t(paramList.getInt(index));
358  }
359  catch (...) {
360  TLOG(TLVL_TRACE) << "Parameter is not an int. Trying string...";
361 
362  auto runNumber = paramList.getString(index);
363  TLOG(TLVL_TRACE) << "Got run number string " << runNumber;
364  run_number = art::RunNumber_t(std::stoi(runNumber));
365  }
366 
367  art::RunID run_id(run_number);
368  return run_id;
369 }
370 
379 template<>
380 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
381 {
382  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as ParameterSet.";
383  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
384  std::string configString = std::string(paramList.getString(index).c_str());
385  TLOG(TLVL_DEBUG) << "Loading Parameter Set from string: " << configString << std::endl;
386  fhicl::ParameterSet pset;
387 
388  try
389  {
390  fhicl::make_ParameterSet(configString, pset);
391  }
392  catch (const fhicl::exception& e)
393  {
394  if (getenv("FHICL_FILE_PATH") == nullptr)
395  {
396  std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
397  setenv("FHICL_FILE_PATH", ".", 0);
398  }
399  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
400  fhicl::make_ParameterSet(configString, lookup_policy, pset);
401  }
402 
403  TLOG(TLVL_INFO) << "Parameter Set Loaded." << std::endl;
404  return pset;
405 }
406 
407 template<typename T>
408 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
409  T default_value)
410 {
411  T val = default_value;
412 
413  try
414  {
415  val = getParam<T>(paramList, index);
416  }
417  catch (const cet::exception& exception)
418  {
419  throw exception;
420  }
421  catch (...)
422  {}
423 
424  return val;
425 }
426 
427 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
428 {
429  std::unique_lock<std::timed_mutex> lk(_c.mutex_, std::chrono::milliseconds(250));
430  if (lk.owns_lock())
431  {
432  try
433  {
434  // JCF, 9/4/14
435 
436  // Assuming the execute_ function returns true, then if the
437  // retvalP argument was untouched, assign it the string
438  // "Success"
439 
440  // See
441  // http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#isinstantiated
442  // for more on the concept of instantiation in xmlrpc_c::value objects
443 
444  if (execute_(paramList, retvalP))
445  {
446  if (!retvalP->isInstantiated())
447  {
448  *retvalP = xmlrpc_c::value_string("Success");
449  }
450  }
451  else
452  {
453  std::string problemReport = _c._commandable.report("transition_status");
454  *retvalP = xmlrpc_c::value_string(problemReport);
455  }
456  }
457  catch (std::runtime_error& er)
458  {
459  std::string msg = exception_msg(er, _help);
460  *retvalP = xmlrpc_c::value_string(msg);
461  TLOG(TLVL_ERROR) << msg;
462  }
463  catch (art::Exception& er)
464  {
465  std::string msg = exception_msg(er, _help);
466  *retvalP = xmlrpc_c::value_string(msg);
467  TLOG(TLVL_ERROR) << msg;
468  }
469  catch (cet::exception& er)
470  {
471  std::string msg = exception_msg(er, _help);
472  *retvalP = xmlrpc_c::value_string(msg);
473  TLOG(TLVL_ERROR) << msg;
474  }
475  catch (...)
476  {
477  std::string msg = exception_msg("Unknown exception", _help);
478  *retvalP = xmlrpc_c::value_string(msg);
479  TLOG(TLVL_ERROR) << msg;
480  }
481  }
482  else
483  {
484  *retvalP = xmlrpc_c::value_string("busy");
485  }
486 }
487 
489 
490 // JCF, 9/5/14
491 
492 // The three "init" transitions all take a FHiCL parameter list, and
493 // optionally a timeout and a timestamp; thus we can kill three birds
494 // with one stone in the GENERATE_INIT_TRANSITION macro
495 
496 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
497  \
498  class NAME##_ : public cmd_ \
499  { \
500  public: \
501  \
504  explicit NAME##_(xmlrpc_commander& c) : cmd_(c, "s:sII", DESCRIPTION) {} \
505  \
506  \
507  static const uint64_t defaultTimeout = 45; \
508  \
509  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
510  \
511  private: \
512  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) \
513  { \
514  fhicl::ParameterSet ps; \
515  try \
516  { \
517  ps = getParam<fhicl::ParameterSet>(paramList, 0); \
518  } \
519  catch (...) \
520  { \
521  *retvalP = xmlrpc_c::value_string("Error: The " #NAME " message requires a single argument that is a string containing the initialization ParameterSet"); \
522  return true; \
523  } \
524  \
525  return _c._commandable.CALL(ps, \
526  getParam<uint64_t>(paramList, 1, defaultTimeout), \
527  getParam<uint64_t>(paramList, 2, defaultTimestamp)); \
528  } \
529  };
530 
531 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
532 
533 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
534 
535 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
536 
537 #undef GENERATE_INIT_TRANSITION
538 
540 
544 class start_ : public cmd_
545 {
546 public:
552  : cmd_(c, "s:iII", "start the run")
553  {}
554 
556  static const uint64_t defaultTimeout = 45;
558  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
559 
560 private:
561  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
562  {
563  try
564  {
565  getParam<art::RunID>(paramList, 0);
566  }
567  catch (...)
568  {
569  *retvalP = xmlrpc_c::value_string("Error: The start message requires the run number as an argument.");
570  return true;
571  }
572 
573  return _c._commandable.start(getParam<art::RunID>(paramList, 0),
574  getParam<uint64_t>(paramList, 1, defaultTimeout),
575  getParam<uint64_t>(paramList, 2, defaultTimestamp));
576  }
577 };
578 
580 
581 // JCF, 9/5/14
582 
583 // "pause", "resume" and "stop" all take an optional timeout and
584 // timestamp parameter, so we can generate them all with the
585 // GENERATE_TIMEOUT_TIMESTAMP_TRANSITION macro
586 
587 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
588  \
589  class NAME##_ : public cmd_ \
590  { \
591  public: \
592  \
594  NAME##_(xmlrpc_commander& c) : cmd_(c, "s:II", DESCRIPTION) {} \
595  \
596  \
597  static const uint64_t defaultTimeout = TIMEOUT; \
598  \
599  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
600  \
601  private: \
602  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const) \
603  { \
604  return _c._commandable.CALL(getParam<uint64_t>(paramList, 0, defaultTimeout), \
605  getParam<uint64_t>(paramList, 1, defaultTimestamp)); \
606  } \
607  };
608 
609 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
610 
611 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
612 
613 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
614 
615 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
616 
620 class shutdown_ : public cmd_
621 {
622 public:
628  : cmd_(c, "s:i", "shutdown the program")
629  {}
630 
632  static const uint64_t defaultTimeout = 45;
633 
634 private:
635  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const)
636  {
637  auto ret = _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
638 
639 #if 1
640  if (_c.server) _c.server->terminate();
641 #endif
642 
643  return ret;
644  }
645 };
646 
650 class status_ : public cmd_
651 {
652 public:
658  : cmd_(c, "s:n", "report the current state")
659  {}
660 
661 private:
662  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
663  {
664  *retvalP = xmlrpc_c::value_string(_c._commandable.status());
665  return true;
666  }
667 };
668 
672 class report_ : public cmd_
673 {
674 public:
680  : cmd_(c, "s:s", "report statistics")
681  {}
682 
683 private:
684  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
685  {
686  try
687  {
688  getParam<std::string>(paramList, 0);
689  }
690  catch (...)
691  {
692  *retvalP = xmlrpc_c::value_string("Error: The report message requires a single argument that selects the type of statistics to be reported.");
693  return true;
694  }
695 
696  *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
697  return true;
698  }
699 };
700 
704 class legal_commands_ : public cmd_
705 {
706 public:
712  : cmd_(c, "s:n", "return the currently legal commands")
713  {}
714 
715 private:
716  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
717  {
718  std::vector<std::string> cmdList = _c._commandable.legal_commands();
719  std::string resultString;
720 
721  for (auto& cmd : cmdList)
722  {
723  resultString.append(cmd + " ");
724  if (cmd == "shutdown")
725  {
726  resultString.append(" reset");
727  }
728  }
729  *retvalP = xmlrpc_c::value_string(resultString);
730 
731  return true;
732  }
733 };
734 
738 class register_monitor_ : public cmd_
739 {
740 public:
746  : cmd_(c, "s:s", "Get notified of a new monitor")
747  {}
748 
749 private:
750  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
751  {
752  try
753  {
754  getParam<fhicl::ParameterSet>(paramList, 0);
755  }
756  catch (...)
757  {
758  *retvalP = xmlrpc_c::value_string("Error: The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
759  return true;
760  }
761 
762  *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
763  return true;
764  }
765 };
766 
770 class unregister_monitor_ : public cmd_
771 {
772 public:
778  : cmd_(c, "s:s", "Remove a monitor")
779  {}
780 
781 private:
782  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
783  {
784  try
785  {
786  getParam<std::string>(paramList, 0);
787  }
788  catch (...)
789  {
790  *retvalP = xmlrpc_c::value_string("Error: The unregister_monitor command expects a string representing the label of the monitor to be removed");
791  return true;
792  }
793 
794  *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
795  return true;
796  }
797 };
798 
802 class trace_set_ : public cmd_
803 {
804 public:
810  : cmd_(c, "s:ssI", "Set TRACE mask")
811  {}
812 
813 private:
814  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
815  {
816  try
817  {
818  getParam<std::string>(paramList, 0);
819  getParam<std::string>(paramList, 1);
820  getParam<std::string>(paramList, 2);
821  }
822  catch (...)
823  {
824  *retvalP = xmlrpc_c::value_string("Error: The trace_set command expects a name (ALL for all), a mask type (M, S , or T), and a mask");
825  return true;
826  }
827 
828  return _c._commandable.do_trace_set(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1), getParam<std::string>(paramList, 2));
829  }
830 };
831 
835 class trace_get_ : public cmd_
836 {
837 public:
843  : cmd_(c, "s:s", "Get TRACE mask")
844  {}
845 
846 private:
847  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
848  {
849  try
850  {
851  getParam<std::string>(paramList, 0);
852  }
853  catch (...)
854  {
855  *retvalP = xmlrpc_c::value_string("Error: The trace_get command expects a name (ALL for all)");
856  return true;
857  }
858 
859  *retvalP = xmlrpc_c::value_string(_c._commandable.do_trace_get(getParam<std::string>(paramList, 0)));
860  return true;
861  }
862 };
863 
867 class meta_command_ : public cmd_
868 {
869 public:
875  : cmd_(c, "s:ss", "Run custom command")
876  {}
877 
878 private:
879  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
880  {
881  try
882  {
883  getParam<std::string>(paramList, 0);
884  getParam<std::string>(paramList, 1);
885  }
886  catch (...)
887  {
888  *retvalP = xmlrpc_c::value_string("Error: The meta_command command expects a string command and a string argument");
889  return true;
890  }
891 
892  return _c._commandable.do_meta_command(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
893  }
894 };
895 
899 class rollover_subrun_ : public cmd_
900 {
901 public:
907  : cmd_(c, "s:Ii", "create a new subrun")
908  {}
909 
910  static const uint64_t defaultSequenceID = 0xFFFFFFFFFFFFFFFF;
911  static const uint32_t defaultSubrunNumber = 1;
912 
913 private:
914  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const)
915  {
916  auto ret = _c._commandable.do_rollover_subrun(getParam<uint64_t>(paramList, 0, defaultSequenceID), getParam<uint32_t>(paramList, 1, defaultSubrunNumber));
917  return ret;
918  }
919 };
920 
925 {
926 public:
932  : cmd_(c, "s:ss", "Add an entry to the configuration archive list")
933  {}
934 
935 private:
936  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
937  {
938  try
939  {
940  getParam<std::string>(paramList, 0);
941  getParam<std::string>(paramList, 1);
942  }
943  catch (...)
944  {
945  *retvalP = xmlrpc_c::value_string("Error: The add_config_archive_entry command expects a string key and a string value");
946  return true;
947  }
948 
949  return _c._commandable.do_add_config_archive_entry(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
950  }
951 };
952 
957 {
958 public:
964  : cmd_(c, "s:n", "Clear the configuration archive list")
965  {}
966 
967 private:
968  bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const)
969  {
971  }
972 };
973 
974 // JCF, 9/4/14
975 
976 // Not sure if anyone was planning to resurrect this code by changing
977 // the preprocessor decision; as such, I'll leave it in for now...
978 
979 #if 0
980  class shutdown_ : public xmlrpc_c::registry::shutdown
981  {
982  public:
983  shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
984 
985  virtual void doit(const std::string& paramString, void*) const
986  {
987  TLOG(TLVL_INFO) << "A shutdown command was sent "
988  << "with parameter "
989  << paramString << "\"";
990  _server->terminate();
991  }
992  private:
993  xmlrpc_c::serverAbyss *_server;
994  };
995 #endif
996 
997 xmlrpc_commander::xmlrpc_commander(fhicl::ParameterSet ps, artdaq::Commandable& commandable)
998  : CommanderInterface(ps, commandable)
999  , port_(ps.get<int>("id", 0))
1000  , serverUrl_(ps.get<std::string>("server_url", ""))
1001  , server(nullptr)
1002 {
1003  if (serverUrl_ == "")
1004  {
1005  char hostname[HOST_NAME_MAX];
1006  gethostname(hostname, HOST_NAME_MAX);
1007  serverUrl_ = std::string(hostname);
1008  }
1009  if (serverUrl_.find("http") == std::string::npos)
1010  {
1011  serverUrl_ = "http://" + serverUrl_;
1012  }
1013  if (serverUrl_.find(std::to_string(port_)) == std::string::npos && serverUrl_.find(':', 7) == std::string::npos)
1014  {
1015  serverUrl_ = serverUrl_ + ":" + std::to_string(port_);
1016  }
1017  if (serverUrl_.find("RPC2") == std::string::npos)
1018  {
1019  serverUrl_ = serverUrl_ + "/RPC2";
1020  }
1021  TLOG(TLVL_INFO) << "XMLRPC COMMANDER CONSTRUCTOR: Port: " << port_ << ", Server Url: " << serverUrl_;
1022 }
1023 
1025 {
1026  //std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1027  xmlrpc_c::registry registry;
1028  struct xmlrpc_method_info3 methodInfo;
1029  memset(&methodInfo, 0, sizeof(methodInfo));
1030 
1031  /*#define register_method(m) \
1032  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1033  registry.addMethod ("daq." #m, ptr_ ## m) */
1034 #define register_method(m) register_method2(m, 0x400000)
1035 
1036  xmlrpc_env env; // xmlrpc_env_init(&env);
1037  xmlrpc_registry*** c_registryPPP;
1038  c_registryPPP = (xmlrpc_registry***)(((char*)&registry) + sizeof(girmem::autoObject));
1039 
1040 #define register_method2(m, ss) \
1041  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1042  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1043  methodInfo.methodName = "daq." #m; \
1044  methodInfo.methodFunction = &c_executeMethod; \
1045  methodInfo.serverInfo = ptr_##m; \
1046  methodInfo.stackSize = ss; \
1047  methodInfo.signatureString = &m##signature[0]; \
1048  methodInfo.help = &m##help[0]; \
1049  xmlrpc_env_init(&env); \
1050  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1051  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1052  xmlrpc_env_clean(&env)
1053 
1054  register_method2(init, 0x200000);
1055  register_method(soft_init);
1056  register_method(reinit);
1057  register_method(start);
1058  register_method(status);
1059  register_method(report);
1060  register_method(stop);
1061  register_method(pause);
1062  register_method(resume);
1063  register_method(register_monitor);
1064  register_method(unregister_monitor);
1065  register_method(legal_commands);
1066  register_method(trace_set);
1067  register_method(trace_get);
1068  register_method(meta_command);
1069  register_method(rollover_subrun);
1070  register_method(add_config_archive_entry);
1071  register_method(clear_config_archive);
1072 
1073  register_method(shutdown);
1074 
1075  // alias "daq.reset" to the internal shutdown transition
1076  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1077  registry.addMethod("daq.reset", ptr_reset);
1078 
1079 #undef register_method
1080 
1081  // JCF, 6/3/15
1082 
1083  // In the following code, I configure a socket to have the
1084  // SO_REUSEADDR option so that once an artdaq process closes, the
1085  // port it was communicating on becomes immediately available
1086  // (desirable if, say, the DAQ program is terminated and then
1087  // immediately restarted)
1088 
1089  // Much of the following code is cribbed from
1090  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1091 
1092  // Below, "0" is the default protocol (in this case, given the IPv4
1093  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1094  // method)
1095 
1096  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1097 
1098  if (socket_file_descriptor < 0)
1099  {
1100  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")";
1101  }
1102 
1103  int enable = 1;
1104  int retval = setsockopt(socket_file_descriptor,
1105  SOL_SOCKET, SO_REUSEADDR,
1106  &enable, sizeof(int));
1107 
1108  if (retval < 0)
1109  {
1110  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")";
1111  }
1112 
1113  struct sockaddr_in sockAddr;
1114 
1115  sockAddr.sin_family = AF_INET;
1116  sockAddr.sin_port = htons(port_);
1117  sockAddr.sin_addr.s_addr = 0;
1118 
1119  retval = bind(socket_file_descriptor,
1120  reinterpret_cast<struct sockaddr*>(&sockAddr),
1121  sizeof(sockAddr));
1122 
1123  if (retval != 0)
1124  {
1125  close(socket_file_descriptor);
1126  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")";
1127  }
1128 
1129  server.reset(new xmlrpc_c::serverAbyss(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor)));
1130 
1131 #if 0
1132  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1133  registry.setShutdown(&shutdown_obj);
1134 #endif
1135 
1136  TLOG(TLVL_DEBUG) << "running server";
1137 
1138  // JCF, 6/3/15
1139 
1140  // Use a catch block to clean up (i.e., close the socket). An
1141  // opportunity for RAII, although all control paths are limited to
1142  // this section of the file...
1143 
1144  try
1145  {
1146  running_ = true;
1147  server->run();
1148  running_ = false;
1149  }
1150  catch (...)
1151  {
1152  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1153  running_ = false;
1154  close(socket_file_descriptor);
1155  throw;
1156  }
1157 
1158  close(socket_file_descriptor);
1159  TLOG(TLVL_DEBUG) << "server terminated";
1160 }
1161 catch (...)
1162 {
1163  throw;
1164 }
1165 
1166 std::string xmlrpc_commander::send_command_(std::string command)
1167 {
1168  if (serverUrl_ == "")
1169  {
1170  std::stringstream errmsg;
1171  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1172  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1173  }
1174  xmlrpc_c::clientSimple myClient;
1175  xmlrpc_c::value result;
1176 
1177  try
1178  {
1179  myClient.call(serverUrl_, "daq." + command, "", &result);
1180  }
1181  catch (...)
1182  {
1183  std::stringstream errmsg;
1184  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1185  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1186  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1187  }
1188 
1189  return xmlrpc_c::value_string(result);
1190 }
1191 
1192 std::string xmlrpc_commander::send_command_(std::string command, std::string arg)
1193 {
1194  if (serverUrl_ == "")
1195  {
1196  std::stringstream errmsg;
1197  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1198  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1199  }
1200  xmlrpc_c::clientSimple myClient;
1201  xmlrpc_c::value result;
1202 
1203  try
1204  {
1205  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1206  }
1207  catch (...)
1208  {
1209  std::stringstream errmsg;
1210  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1211  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1212  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1213  }
1214 
1215  return xmlrpc_c::value_string(result);
1216 }
1217 
1218 std::string xmlrpc_commander::send_command_(std::string command, fhicl::ParameterSet pset, uint64_t timestamp, uint64_t timeout)
1219 {
1220  if (serverUrl_ == "")
1221  {
1222  std::stringstream errmsg;
1223  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1224  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1225  }
1226  xmlrpc_c::clientSimple myClient;
1227  xmlrpc_c::value result;
1228 
1229  try
1230  {
1231  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1232  }
1233  catch (...)
1234  {
1235  std::stringstream errmsg;
1236  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1237  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1238  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1239  }
1240 
1241  return xmlrpc_c::value_string(result);
1242 }
1243 
1244 std::string artdaq::xmlrpc_commander::send_command_(std::string command, uint64_t a, uint64_t b)
1245 {
1246  if (serverUrl_ == "")
1247  {
1248  std::stringstream errmsg;
1249  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1250  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1251  }
1252  xmlrpc_c::clientSimple myClient;
1253  xmlrpc_c::value result;
1254 
1255  try
1256  {
1257  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1258  }
1259  catch (...)
1260  {
1261  std::stringstream errmsg;
1262  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1263  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1264  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1265  }
1266 
1267  return xmlrpc_c::value_string(result);
1268 }
1269 
1270 std::string artdaq::xmlrpc_commander::send_command_(std::string command, art::RunID r, uint64_t a, uint64_t b)
1271 {
1272  if (serverUrl_ == "")
1273  {
1274  std::stringstream errmsg;
1275  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1276  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1277  }
1278  xmlrpc_c::clientSimple myClient;
1279  xmlrpc_c::value result;
1280 
1281  try
1282  {
1283  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1284  }
1285  catch (...)
1286  {
1287  std::stringstream errmsg;
1288  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1289  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1290  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1291  }
1292 
1293  return xmlrpc_c::value_string(result);
1294 }
1295 
1296 std::string artdaq::xmlrpc_commander::send_command_(std::string command, uint64_t arg1)
1297 {
1298  if (serverUrl_ == "")
1299  {
1300  std::stringstream errmsg;
1301  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1302  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1303  }
1304  xmlrpc_c::clientSimple myClient;
1305  xmlrpc_c::value result;
1306 
1307  try
1308  {
1309  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1310  }
1311  catch (...)
1312  {
1313  std::stringstream errmsg;
1314  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1315  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1316  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1317  }
1318 
1319  return xmlrpc_c::value_string(result);
1320 }
1321 
1322 std::string artdaq::xmlrpc_commander::send_command_(std::string command, std::string arg1, std::string arg2)
1323 {
1324  if (serverUrl_ == "")
1325  {
1326  std::stringstream errmsg;
1327  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1328  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1329  }
1330  xmlrpc_c::clientSimple myClient;
1331  xmlrpc_c::value result;
1332 
1333  try
1334  {
1335  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1336  }
1337  catch (...)
1338  {
1339  std::stringstream errmsg;
1340  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1341  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1342  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1343  }
1344 
1345  return xmlrpc_c::value_string(result);
1346 }
1347 
1348 std::string artdaq::xmlrpc_commander::send_command_(std::string command, std::string arg1, std::string arg2, std::string arg3)
1349 {
1350  if (serverUrl_ == "")
1351  {
1352  std::stringstream errmsg;
1353  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1354  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1355  }
1356  xmlrpc_c::clientSimple myClient;
1357  xmlrpc_c::value result;
1358 
1359  try
1360  {
1361  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1362  }
1363  catch (...)
1364  {
1365  std::stringstream errmsg;
1366  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1367  << "; possible causes are bad arguments or nonexistent process at requested port";
1368  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1369  }
1370 
1371  return xmlrpc_c::value_string(result);
1372 }
1373 
1374 std::string xmlrpc_commander::send_register_monitor(std::string monitor_fhicl)
1375 {
1376  return send_command_("register_monitor", monitor_fhicl);
1377 }
1378 std::string xmlrpc_commander::send_unregister_monitor(std::string monitor_label)
1379 {
1380  return send_command_("unregister_monitor", monitor_label);
1381 }
1382 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1383 {
1384  return send_command_("init", ps, timeout, timestamp);
1385 }
1386 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1387 {
1388  return send_command_("soft_init", ps, timeout, timestamp);
1389 }
1390 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp)
1391 {
1392  return send_command_("reinit", ps, timeout, timestamp);
1393 }
1394 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1395 {
1396  return send_command_("start", run, timeout, timestamp);
1397 }
1398 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1399 {
1400  return send_command_("pause", timeout, timestamp);
1401 }
1402 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1403 {
1404  return send_command_("resume", timeout, timestamp);
1405 }
1406 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1407 {
1408  return send_command_("stop", timeout, timestamp);
1409 }
1410 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1411 {
1412  return send_command_("shutdown", timeout);
1413 }
1415 {
1416  return send_command_("status");
1417 }
1418 std::string xmlrpc_commander::send_report(std::string what)
1419 {
1420  return send_command_("report", what);
1421 }
1423 {
1424  return send_command_("legal_commands");
1425 }
1426 std::string xmlrpc_commander::send_trace_get(std::string name)
1427 {
1428  return send_command_("trace_get", name);
1429 }
1430 std::string xmlrpc_commander::send_trace_set(std::string name, std::string type, std::string mask)
1431 {
1432  return send_command_("trace_set", name, type, mask);
1433 }
1434 std::string xmlrpc_commander::send_meta_command(std::string command, std::string arg)
1435 {
1436  return send_command_("meta_command", command, arg);
1437 }
1438 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1439 {
1440  return send_command_("rollover_subrun", when, sr);
1441 }
1442 } // namespace artdaq
1443 
1444 DEFINE_ARTDAQ_COMMANDER(artdaq::xmlrpc_commander)
virtual bool do_add_config_archive_entry(std::string const &, std::string const &)
Add the specified key-value pair to the configuration archive list.
Definition: Commandable.cc:499
std::string send_rollover_subrun(uint64_t seq, uint32_t subrunNumber) override
Send a send_rollover_subrun command over XMLRPC
This interface defines the functions used to transfer data between artdaq applications.
cmd_(xmlrpc_commander &c, const std::string &signature, const std::string &description)
cmd_ Constructor
static const uint64_t defaultTimeout
std::string send_trace_get(std::string name) override
Send an send_trace_get command over XMLRPC
std::string send_unregister_monitor(std::string monitor_label) override
Send an unregister_monitor command over XMLRPC
std::string send_register_monitor(std::string monitor_fhicl) override
Send a register_monitor command over XMLRPC
virtual std::string report(std::string const &) const
Default report implementation returns current report_string.
Definition: Commandable.hh:121
Commandable is the base class for all artdaq components which implement the artdaq state machine...
Definition: Commandable.hh:20
legal_commands_(xmlrpc_commander &c)
legal_commands_ Constructor
virtual bool do_clear_config_archive()
Clears the configuration archive list.
Definition: Commandable.cc:505
xmlrpc_commander(fhicl::ParameterSet ps, artdaq::Commandable &commandable)
xmlrpc_commander Constructor
Command class representing a start transition.
rollover_subrun_(xmlrpc_commander &c)
shutdown_ Constructor
status_ Command class
report_ Command class
std::string send_stop(uint64_t timeout, uint64_t timestamp) override
Send a stop command over XMLRPC
virtual std::string clear_config_archive()
Using the transport mechanism, send a clear_config_archive command
virtual std::string unregister_monitor(std::string const &)
Perform the unregister_monitor action.
Definition: Commandable.hh:150
meta_command_ Command class
std::string send_status() override
Send a status command over XMLRPC
std::string send_legal_commands() override
Send a legal_commands command over XMLRPC
The xmlrpc_commander class serves as the XMLRPC server run in each artdaq application.
static const uint64_t defaultTimestamp
static const uint32_t defaultSubrunNumber
Default subrun number for command.
std::string send_meta_command(std::string command, std::string argument) override
Send an send_meta_command command over XMLRPC
The &quot;cmd_&quot; class serves as the base class for all artdaq&#39;s XML-RPC commands.
trace_set_(xmlrpc_commander &c)
unregister_monitor_ Constructor
shutdown_ Command class
void run_server() override
Run the XMLRPC server.
meta_command_(xmlrpc_commander &c)
meta_command_ Constructor
std::unique_ptr< xmlrpc_c::serverAbyss > server
XMLRPC server.
std::string status() const
Returns the current state of the Commandable.
Definition: Commandable.cc:272
std::string send_shutdown(uint64_t timeout) override
Send a shutdown command over XMLRPC
std::string send_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send an init command over XMLRPC
std::string exception_msg(const std::runtime_error &er, const std::string &helpText="execute request")
Write an exception message.
static const uint64_t defaultSequenceID
Default Sequence ID for command.
add_config_archive_entry_(xmlrpc_commander &c)
add_config_archive_entry_ Constructor
virtual std::string register_monitor(fhicl::ParameterSet const &)
Perform the register_monitor action.
Definition: Commandable.hh:139
virtual bool do_meta_command(std::string const &command, std::string const &args)
Run a module-defined command with the given parameter string.
Definition: Commandable.cc:486
virtual bool do_trace_set(std::string const &name, std::string const &type, std::string const &mask_in_string_form)
Set the given TRACE mask for the given TRACE name.
Definition: Commandable.cc:433
register_monitor_ Command class
add_config_archive_entry_ Command class
legal_commands_ Command class
std::string send_pause(uint64_t timeout, uint64_t timestamp) override
Send a pause command over XMLRPC
artdaq::Commandable & _commandable
Reference to the Commandable that this Commander Commands.
std::string send_trace_set(std::string name, std::string type, std::string mask) override
Send an send_trace_msgfacility_set command over XMLRPC
xmlrpc_commander & _c
The xmlrpc_commander instance that the command will be sent to.
std::string send_start(art::RunID runNumber, uint64_t timeout, uint64_t timestamp) override
Send a start command over XMLRPC
clear_config_archive_ Command class
trace_get_ Command class
std::string send_soft_init(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send a soft_init command over XMLRPC
status_(xmlrpc_commander &c)
status_ Constructor
clear_config_archive_(xmlrpc_commander &c)
clear_config_archive_ Constructor
virtual std::string add_config_archive_entry(std::string key, std::string value)
Using the transport mechanism, send an add_config_archive_entry command
virtual bool execute_(const xmlrpc_c::paramList &, xmlrpc_c::value *const retvalP)=0
&quot;execute_&quot; is a wrapper function around the call to the commandable object&#39;s function ...
Wrapper for XMLRPC environment construction/destruction
std::timed_mutex mutex_
XMLRPC mutex.
register_monitor_(xmlrpc_commander &c)
register_monitor_ Constructor
static const uint64_t defaultTimeout
unregister_monitor_(xmlrpc_commander &c)
unregister_monitor_ Constructor
void execute(const xmlrpc_c::paramList &paramList, xmlrpc_c::value *const retvalP) final
Execute trhe command with the given parameters.
shutdown_(xmlrpc_commander &c)
shutdown_ Constructor
std::vector< std::string > legal_commands() const
Get the legal transition commands from the current state.
Definition: Commandable.cc:285
rollover_subrun_ Command class
std::string send_resume(uint64_t timeout, uint64_t timestamp) override
Send a resume command over XMLRPC
bool start(art::RunID id, uint64_t timeout, uint64_t timestamp)
Processes the start transition.
Definition: Commandable.cc:59
report_(xmlrpc_commander &c)
report_ Constructor
trace_set_ Command class
std::string send_report(std::string which) override
Send a report command over XMLRPC
start_(xmlrpc_commander &c)
start_ Command (cmd_ derived class) Constructor
virtual std::string do_trace_get(std::string const &name)
Get the TRACE mask for the given TRACE name If name is &quot;ALL&quot;, then all TRACE masks will be printed...
Definition: Commandable.cc:404
trace_get_(xmlrpc_commander &c)
trace_msgfacility_set_ Constructor
std::string send_reinit(fhicl::ParameterSet ps, uint64_t timeout, uint64_t timestamp) override
Send a reinit command over XMLRPC
std::atomic< bool > running_
Whether the server is running and able to respond to requests.
virtual bool do_rollover_subrun(uint64_t eventNum, uint32_t subrunNum)
Perform the rollover_subrun transition.
Definition: Commandable.cc:492
unregister_monitor_ Command class
T getParam(const xmlrpc_c::paramList &paramList, int index)
Get a parameter from the parameter list.
bool shutdown(uint64_t timeout)
Processes the shutdown transition.
Definition: Commandable.cc:166