artdaq  v3_11_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 <memory>
10 #include <xmlrpc-c/base.hpp>
11 #include <xmlrpc-c/client_simple.hpp>
12 #include <xmlrpc-c/girerr.hpp>
13 #include <xmlrpc-c/registry.hpp>
14 #include <xmlrpc-c/server_abyss.hpp>
15 #undef _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
16 #pragma GCC diagnostic pop
17 #include <cstdint>
18 #include <iostream>
19 #include <limits>
20 #include <memory>
21 #include <stdexcept>
22 #include "artdaq/DAQdata/Globals.hh"
23 #define TRACE_NAME (app_name + "_xmlrpc_commander").c_str()
24 #include "tracemf.h"
25 
26 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <cerrno>
29 #include <cstring>
30 #include <exception>
31 #include "artdaq-core/Utilities/ExceptionHandler.hh"
32 
33 #include "artdaq-utilities/Plugins/MakeParameterSet.hh"
34 #include "canvas/Persistency/Provenance/RunID.h"
35 
36 #include "artdaq/ExternalComms/xmlrpc_commander.hh"
37 //#include "artdaq/Application/LoadParameterSet.hh"
38 
39 namespace {
43 class env_wrap
44 {
45 public:
46  env_wrap() { xmlrpc_env_init(&this->env_c); };
47  ~env_wrap() { xmlrpc_env_clean(&this->env_c); };
48  xmlrpc_env env_c;
49 private:
50  env_wrap(env_wrap const&) = delete;
51  env_wrap(env_wrap&&) = delete;
52  env_wrap& operator=(env_wrap const&) = delete;
53  env_wrap& operator=(env_wrap&&) = delete;
54 };
55 } // namespace
56 static xmlrpc_c::paramList
57 pListFromXmlrpcArray(xmlrpc_value* const arrayP)
58 {
59  env_wrap env;
60  XMLRPC_ASSERT_ARRAY_OK(arrayP);
61  unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP);
62  assert(!env.env_c.fault_occurred);
63  xmlrpc_c::paramList paramList(arraySize);
64  for (unsigned int i = 0; i < arraySize; ++i)
65  {
66  xmlrpc_value* arrayItemP;
67  xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP);
68  assert(!env.env_c.fault_occurred);
69  paramList.add(xmlrpc_c::value(arrayItemP));
70  xmlrpc_DECREF(arrayItemP);
71  }
72  return paramList;
73 }
74 static xmlrpc_value*
75 c_executeMethod(xmlrpc_env* const envP,
76  xmlrpc_value* const paramArrayP,
77  void* const methodPtr,
78  void* const callInfoPtr)
79 {
80  auto* const methodP(static_cast<xmlrpc_c::method*>(methodPtr));
81  xmlrpc_c::paramList const paramList(pListFromXmlrpcArray(paramArrayP));
82  auto* const callInfoP(static_cast<xmlrpc_c::callInfo*>(callInfoPtr));
83  xmlrpc_value* retval;
84  retval = nullptr; // silence used-before-set warning
85  try
86  {
87  xmlrpc_c::value result;
88  try
89  {
90  auto* const method2P(dynamic_cast<xmlrpc_c::method2*>(methodP));
91  if (method2P != nullptr)
92  {
93  method2P->execute(paramList, callInfoP, &result);
94  }
95  else
96  {
97  methodP->execute(paramList, &result);
98  }
99  }
100  catch (xmlrpc_c::fault const& fault)
101  {
102  xmlrpc_env_set_fault(envP, fault.getCode(),
103  fault.getDescription().c_str());
104  }
105  if (envP->fault_occurred == 0)
106  {
107  if (result.isInstantiated())
108  {
109  retval = result.cValue();
110  }
111  else
112  {
113  girerr::throwf(
114  "Xmlrpc-c user's xmlrpc_c::method object's "
115  "'execute method' failed to set the RPC result "
116  "value.");
117  }
118  }
119  }
120  catch (std::exception const& e)
121  {
122  xmlrpc_faultf(envP,
123  "Unexpected error executing code for "
124  "particular method, detected by Xmlrpc-c "
125  "method registry code. Method did not "
126  "fail; rather, it did not complete at all. %s",
127  e.what());
128  }
129  catch (...)
130  {
131  xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
132  "Unexpected error executing code for "
133  "particular method, detected by Xmlrpc-c "
134  "method registry code. Method did not "
135  "fail; rather, it did not complete at all.");
136  }
137  return retval;
138 }
139 
140 namespace artdaq {
147 std::string exception_msg(const std::runtime_error& er,
148  const std::string& helpText = "execute request")
149 {
150  std::string msg("Exception when trying to ");
151  msg.append(helpText);
152  msg.append(": ");
153  msg.append(er.what()); //std::string(er.what ()).substr (2);
154  if (msg[msg.size() - 1] == '\n')
155  {
156  msg.erase(msg.size() - 1);
157  }
158  return msg;
159 }
160 
167 std::string exception_msg(const art::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')
175  {
176  msg.erase(msg.size() - 1);
177  }
178  return msg;
179 }
180 
187 std::string exception_msg(const cet::exception& er,
188  const std::string& helpText)
189 {
190  std::string msg("Exception when trying to ");
191  msg.append(helpText);
192  msg.append(": ");
193  msg.append(er.what());
194  if (msg[msg.size() - 1] == '\n')
195  {
196  msg.erase(msg.size() - 1);
197  }
198  return msg;
199 }
200 
207 std::string exception_msg(const boost::exception& er,
208  const std::string& helpText)
209 {
210  std::string msg("Exception when trying to ");
211  msg.append(helpText);
212  msg.append(": ");
213  msg.append(boost::diagnostic_information(er));
214  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
215  return msg;
216 }
223 std::string exception_msg(const std::exception& er,
224  const std::string& helpText)
225 {
226  std::string msg("Exception when trying to ");
227  msg.append(helpText);
228  msg.append(": ");
229  msg.append(er.what());
230  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
231  return msg;
232 }
233 
240 std::string exception_msg(const std::string& erText,
241  const std::string& helpText)
242 {
243  std::string msg("Exception when trying to ");
244  msg.append(helpText);
245  msg.append(": ");
246  msg.append(erText);
247  if (msg[msg.size() - 1] == '\n')
248  {
249  msg.erase(msg.size() - 1);
250  }
251  return msg;
252 }
253 
271 class cmd_ : public xmlrpc_c::method
272 {
273 public:
274  // Can't seem to initialize "_signature" and "_help" in the initialization list...
281  cmd_(xmlrpc_commander& c, const std::string& signature, const std::string& description)
282  : _c(c)
283  {
284  _signature = signature;
285  _help = description;
286  }
287 
293  void execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* retvalP) final;
294 
295 protected:
297 
303  virtual bool execute_(const xmlrpc_c::paramList&, xmlrpc_c::value* retvalP) = 0;
304 
314  template<typename T>
315  T getParam(const xmlrpc_c::paramList& paramList, int index);
316 
340  template<typename T>
341  T getParam(const xmlrpc_c::paramList& paramList, int index, T default_value);
342 };
343 
344 // Users are only allowed to call getParam for predefined types; see
345 // template specializations below this default function
346 
347 template<typename T>
348 T cmd_::getParam(const xmlrpc_c::paramList& /*unused*/, int /*unused*/)
349 {
350  throw cet::exception("cmd_") << "Error in cmd_::getParam(): value type not supported" << std::endl; // NOLINT(cert-err60-cpp)
351 }
352 
361 template<>
362 uint64_t cmd_::getParam<uint64_t>(const xmlrpc_c::paramList& paramList, int index)
363 {
364  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint64_t.";
365  try
366  {
367  TLOG(TLVL_TRACE) << "Param value: " << paramList.getI8(index);
368  return static_cast<uint64_t>(paramList.getI8(index));
369  }
370  catch (...)
371  {
372  TLOG(TLVL_TRACE) << "Param value (int): " << paramList.getInt(index);
373  return static_cast<uint64_t>(paramList.getInt(index));
374  }
375 }
376 
385 template<>
386 uint32_t cmd_::getParam<uint32_t>(const xmlrpc_c::paramList& paramList, int index)
387 {
388  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint32_t.";
389  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
390  return static_cast<uint32_t>(paramList.getInt(index));
391 }
392 
401 template<>
402 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
403 {
404  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as string.";
405  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
406  return static_cast<std::string>(paramList.getString(index));
407 }
408 
417 template<>
418 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
419 {
420  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as Run Number.";
421  art::RunNumber_t run_number;
422  try
423  {
424  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
425  run_number = art::RunNumber_t(paramList.getInt(index));
426  }
427  catch (...)
428  {
429  TLOG(TLVL_TRACE) << "Parameter is not an int. Trying string...";
430 
431  auto runNumber = paramList.getString(index);
432  TLOG(TLVL_TRACE) << "Got run number string " << runNumber;
433  run_number = art::RunNumber_t(std::stoi(runNumber));
434  }
435 
436  art::RunID run_id(run_number);
437  return run_id;
438 }
439 
448 template<>
449 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
450 {
451  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as ParameterSet.";
452  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
453  std::string configString = std::string(paramList.getString(index));
454  TLOG(TLVL_DEBUG) << "Loading Parameter Set from string: " << configString << std::endl;
455  fhicl::ParameterSet pset;
456 
457  try
458  {
459  pset = artdaq::make_pset(configString);
460  }
461  catch (const fhicl::exception& e)
462  {
463  if (getenv("FHICL_FILE_PATH") == nullptr)
464  {
465  TLOG(TLVL_ERROR) << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"";
466  std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"" << std::endl;
467  setenv("FHICL_FILE_PATH", ".", 0);
468  }
469  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
470  pset = artdaq::make_pset(configString, lookup_policy);
471  }
472 
473  TLOG(TLVL_INFO) << "Parameter Set Loaded." << std::endl;
474  return pset;
475 }
476 
477 template<typename T>
478 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
479  T default_value)
480 {
481  T val = default_value;
482 
483  if (static_cast<unsigned>(index) < paramList.size())
484  {
485  val = getParam<T>(paramList, index);
486  }
487  return val;
488 }
489 
490 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
491 {
492  TLOG(TLVL_TRACE) << "Received Request to " << _help << ", attempting to get lock";
493  std::unique_lock<std::timed_mutex> lk(_c.mutex_, std::defer_lock);
494  lk.try_lock_for(std::chrono::milliseconds(250));
495 
496  if (lk.owns_lock())
497  {
498  try
499  {
500  // JCF, 9/4/14
501 
502  // Assuming the execute_ function returns true, then if the
503  // retvalP argument was untouched, assign it the string
504  // "Success"
505 
506  // See
507  // http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#isinstantiated
508  // for more on the concept of instantiation in xmlrpc_c::value objects
509 
510  if (execute_(paramList, retvalP))
511  {
512  if (!retvalP->isInstantiated())
513  {
514  *retvalP = xmlrpc_c::value_string("Success");
515  }
516  }
517  else
518  {
519  std::string problemReport = _c._commandable.report("transition_status");
520  *retvalP = xmlrpc_c::value_string(problemReport);
521  }
522  }
523  catch (std::runtime_error& er)
524  {
525  std::string msg = exception_msg(er, _help);
526  *retvalP = xmlrpc_c::value_string(msg);
527  TLOG(TLVL_ERROR) << msg;
528  }
529  catch (art::Exception& er)
530  {
531  std::string msg = exception_msg(er, _help);
532  *retvalP = xmlrpc_c::value_string(msg);
533  TLOG(TLVL_ERROR) << msg;
534  }
535  catch (cet::exception& er)
536  {
537  std::string msg = exception_msg(er, _help);
538  *retvalP = xmlrpc_c::value_string(msg);
539  TLOG(TLVL_ERROR) << msg;
540  }
541  catch (boost::exception& er)
542  {
543  std::string msg = exception_msg(er, _help);
544  *retvalP = xmlrpc_c::value_string(msg);
545  TLOG(TLVL_ERROR) << msg;
546  }
547  catch (std::exception& er)
548  {
549  std::string msg = exception_msg(er, _help);
550  *retvalP = xmlrpc_c::value_string(msg);
551  TLOG(TLVL_ERROR) << msg;
552  }
553  catch (...)
554  {
555  std::string msg = exception_msg("Unknown exception (not from std, boost, cet, or art)", _help);
556  *retvalP = xmlrpc_c::value_string(msg);
557  TLOG(TLVL_ERROR) << msg;
558  }
559 
560  lk.unlock();
561  }
562  else
563  {
564  TLOG(TLVL_ERROR) << "Unable to get lock while trying to " << _help << ", returning busy";
565  *retvalP = xmlrpc_c::value_string("busy");
566  }
567 }
568 
570 
571 // JCF, 9/5/14
572 
573 // The three "init" transitions all take a FHiCL parameter list, and
574 // optionally a timeout and a timestamp; thus we can kill three birds
575 // with one stone in the GENERATE_INIT_TRANSITION macro
576 
577 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
578  \
579  class NAME##_ : public cmd_ \
580  { \
581  public: \
582  \
585  explicit NAME##_(xmlrpc_commander& c) : cmd_(c, "s:sII", DESCRIPTION) {} \
586  \
587  \
588  static const uint64_t defaultTimeout = 45; \
589  \
590  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
591  \
592  private: \
593  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) \
594  { \
595  fhicl::ParameterSet ps; \
596  try \
597  { \
598  ps = getParam<fhicl::ParameterSet>(paramList, 0); \
599  } \
600  catch (...) \
601  { \
602  *retvalP = xmlrpc_c::value_string("Error: The " #NAME " message requires a single argument that is a string containing the initialization ParameterSet"); \
603  return true; \
604  } \
605  \
606  return _c._commandable.CALL(ps, \
607  getParam<uint64_t>(paramList, 1, defaultTimeout), \
608  getParam<uint64_t>(paramList, 2, defaultTimestamp)); \
609  } \
610  };
611 
612 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
613 
614 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
615 
616 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
617 
618 #undef GENERATE_INIT_TRANSITION
619 
621 
625 class start_ : public cmd_
626 {
627 public:
633  : cmd_(c, "s:iII", "start the run")
634  {}
635 
637  static const uint64_t defaultTimeout = 45;
639  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
640 
641 private:
642  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
643  {
644  try
645  {
646  getParam<art::RunID>(paramList, 0);
647  }
648  catch (...)
649  {
650  *retvalP = xmlrpc_c::value_string("Error: The start message requires the run number as an argument.");
651  return true;
652  }
653 
654  return _c._commandable.start(getParam<art::RunID>(paramList, 0),
655  getParam<uint64_t>(paramList, 1, defaultTimeout),
656  getParam<uint64_t>(paramList, 2, defaultTimestamp));
657  }
658 };
659 
661 
662 // JCF, 9/5/14
663 
664 // "pause", "resume" and "stop" all take an optional timeout and
665 // timestamp parameter, so we can generate them all with the
666 // GENERATE_TIMEOUT_TIMESTAMP_TRANSITION macro
667 
668 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
669  \
670  class NAME##_ : public cmd_ \
671  { \
672  public: \
673  \
675  NAME##_(xmlrpc_commander& c) : cmd_(c, "s:II", DESCRIPTION) {} \
676  \
677  \
678  static const uint64_t defaultTimeout = TIMEOUT; \
679  \
680  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
681  \
682  private: \
683  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const) \
684  { \
685  return _c._commandable.CALL(getParam<uint64_t>(paramList, 0, defaultTimeout), \
686  getParam<uint64_t>(paramList, 1, defaultTimestamp)); \
687  } \
688  };
689 
690 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
691 
692 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
693 
694 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
695 
696 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
697 
701 class shutdown_ : public cmd_
702 {
703 public:
709  : cmd_(c, "s:i", "shutdown the program")
710  {}
711 
713  static const uint64_t defaultTimeout = 45;
714 
715 private:
716  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
717  {
718  auto ret = _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
719 
720 #if 1
721  if (_c.server)
722  {
723  _c.server->terminate();
724  }
725 #endif
726 
727  return ret;
728  }
729 };
730 
734 class status_ : public cmd_
735 {
736 public:
742  : cmd_(c, "s:n", "report the current state")
743  {}
744 
745 private:
746  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
747  {
748  *retvalP = xmlrpc_c::value_string(_c._commandable.status());
749  return true;
750  }
751 };
752 
756 class report_ : public cmd_
757 {
758 public:
764  : cmd_(c, "s:s", "report statistics")
765  {}
766 
767 private:
768  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
769  {
770  try
771  {
772  getParam<std::string>(paramList, 0);
773  }
774  catch (...)
775  {
776  *retvalP = xmlrpc_c::value_string("Error: The report message requires a single argument that selects the type of statistics to be reported.");
777  return true;
778  }
779 
780  *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
781  return true;
782  }
783 };
784 
788 class legal_commands_ : public cmd_
789 {
790 public:
796  : cmd_(c, "s:n", "return the currently legal commands")
797  {}
798 
799 private:
800  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
801  {
802  std::vector<std::string> cmdList = _c._commandable.legal_commands();
803  std::string resultString;
804 
805  for (auto& cmd : cmdList)
806  {
807  resultString.append(cmd + " ");
808  if (cmd == "shutdown")
809  {
810  resultString.append(" reset");
811  }
812  }
813  *retvalP = xmlrpc_c::value_string(resultString);
814 
815  return true;
816  }
817 };
818 
822 class register_monitor_ : public cmd_
823 {
824 public:
830  : cmd_(c, "s:s", "Get notified of a new monitor")
831  {}
832 
833 private:
834  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
835  {
836  try
837  {
838  getParam<fhicl::ParameterSet>(paramList, 0);
839  }
840  catch (...)
841  {
842  *retvalP = xmlrpc_c::value_string("Error: The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
843  return true;
844  }
845 
846  *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
847  return true;
848  }
849 };
850 
854 class unregister_monitor_ : public cmd_
855 {
856 public:
862  : cmd_(c, "s:s", "Remove a monitor")
863  {}
864 
865 private:
866  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
867  {
868  try
869  {
870  getParam<std::string>(paramList, 0);
871  }
872  catch (...)
873  {
874  *retvalP = xmlrpc_c::value_string("Error: The unregister_monitor command expects a string representing the label of the monitor to be removed");
875  return true;
876  }
877 
878  *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
879  return true;
880  }
881 };
882 
886 class trace_set_ : public cmd_
887 {
888 public:
894  : cmd_(c, "s:ssI", "Set TRACE mask")
895  {}
896 
897 private:
898  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
899  {
900  try
901  {
902  getParam<std::string>(paramList, 0);
903  getParam<std::string>(paramList, 1);
904  getParam<std::string>(paramList, 2);
905  }
906  catch (...)
907  {
908  *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");
909  return true;
910  }
911 
912  return _c._commandable.do_trace_set(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1), getParam<std::string>(paramList, 2));
913  }
914 };
915 
919 class trace_get_ : public cmd_
920 {
921 public:
927  : cmd_(c, "s:s", "Get TRACE mask")
928  {}
929 
930 private:
931  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
932  {
933  try
934  {
935  getParam<std::string>(paramList, 0);
936  }
937  catch (...)
938  {
939  *retvalP = xmlrpc_c::value_string("Error: The trace_get command expects a name (ALL for all)");
940  return true;
941  }
942 
943  *retvalP = xmlrpc_c::value_string(_c._commandable.do_trace_get(getParam<std::string>(paramList, 0)));
944  return true;
945  }
946 };
947 
951 class meta_command_ : public cmd_
952 {
953 public:
959  : cmd_(c, "s:ss", "Run custom command")
960  {}
961 
962 private:
963  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
964  {
965  try
966  {
967  getParam<std::string>(paramList, 0);
968  getParam<std::string>(paramList, 1);
969  }
970  catch (...)
971  {
972  *retvalP = xmlrpc_c::value_string("Error: The meta_command command expects a string command and a string argument");
973  return true;
974  }
975 
976  return _c._commandable.do_meta_command(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
977  }
978 };
979 
983 class rollover_subrun_ : public cmd_
984 {
985 public:
991  : cmd_(c, "s:Ii", "create a new subrun")
992  {}
993 
994  static const uint64_t defaultSequenceID = 0xFFFFFFFFFFFFFFFF;
995  static const uint32_t defaultSubrunNumber = 1;
996 
997 private:
998  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
999  {
1000  auto ret = _c._commandable.do_rollover_subrun(getParam<uint64_t>(paramList, 0, defaultSequenceID), getParam<uint32_t>(paramList, 1, defaultSubrunNumber));
1001  return ret;
1002  }
1003 };
1004 
1009 {
1010 public:
1016  : cmd_(c, "s:ss", "Add an entry to the configuration archive list")
1017  {}
1018 
1019 private:
1020  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1021  {
1022  try
1023  {
1024  getParam<std::string>(paramList, 0);
1025  getParam<std::string>(paramList, 1);
1026  }
1027  catch (...)
1028  {
1029  *retvalP = xmlrpc_c::value_string("Error: The add_config_archive_entry command expects a string key and a string value");
1030  return true;
1031  }
1032 
1033  return _c._commandable.do_add_config_archive_entry(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
1034  }
1035 };
1036 
1041 {
1042 public:
1048  : cmd_(c, "s:n", "Clear the configuration archive list")
1049  {}
1050 
1051 private:
1052  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const /*retvalP*/) override
1053  {
1055  }
1056 };
1057 
1058 // JCF, 9/4/14
1059 
1060 // Not sure if anyone was planning to resurrect this code by changing
1061 // the preprocessor decision; as such, I'll leave it in for now...
1062 
1063 #if 0
1064  class shutdown_ : public xmlrpc_c::registry::shutdown
1065  {
1066  public:
1067  shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
1068 
1069  virtual void doit(const std::string& paramString, void*) const
1070  {
1071  TLOG(TLVL_INFO) << "A shutdown command was sent "
1072  << "with parameter "
1073  << paramString << "\"";
1074  _server->terminate();
1075  }
1076  private:
1077  xmlrpc_c::serverAbyss *_server;
1078  };
1079 #endif
1080 
1081 xmlrpc_commander::xmlrpc_commander(const fhicl::ParameterSet& ps, artdaq::Commandable& commandable)
1082  : CommanderInterface(ps, commandable)
1083  , port_(ps.get<int>("id", 0))
1084  , serverUrl_(ps.get<std::string>("server_url", ""))
1085  , server(nullptr)
1086 {
1087  if (serverUrl_.empty())
1088  {
1089  char hostname[HOST_NAME_MAX];
1090  gethostname(hostname, HOST_NAME_MAX);
1091  serverUrl_ = std::string(hostname);
1092  }
1093  if (serverUrl_.find("http") == std::string::npos)
1094  {
1095  serverUrl_ = "http://" + serverUrl_;
1096  }
1097  if (serverUrl_.find(std::to_string(port_)) == std::string::npos && serverUrl_.find(':', 7) == std::string::npos)
1098  {
1099  serverUrl_ = serverUrl_ + ":" + std::to_string(port_);
1100  }
1101  if (serverUrl_.find("RPC2") == std::string::npos)
1102  {
1103  serverUrl_ = serverUrl_ + "/RPC2";
1104  }
1105  TLOG(TLVL_INFO) << "XMLRPC COMMANDER CONSTRUCTOR: Port: " << port_ << ", Server Url: " << serverUrl_;
1106 }
1107 
1109 {
1110  //std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1111  xmlrpc_c::registry registry;
1112  struct xmlrpc_method_info3 methodInfo;
1113  memset(&methodInfo, 0, sizeof(methodInfo));
1114 
1115  /*#define register_method(m) \
1116  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1117  registry.addMethod ("daq." #m, ptr_ ## m) */
1118 #define register_method(m) register_method2(m, 0x400000)
1119 
1120  xmlrpc_env env; // xmlrpc_env_init(&env);
1121  xmlrpc_registry*** c_registryPPP;
1122  c_registryPPP = reinterpret_cast<xmlrpc_registry***>(reinterpret_cast<char*>(&registry) + sizeof(girmem::autoObject)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
1123 
1124 #define register_method2(m, ss) \
1125  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1126  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1127  methodInfo.methodName = "daq." #m; \
1128  methodInfo.methodFunction = &c_executeMethod; \
1129  methodInfo.serverInfo = ptr_##m; \
1130  methodInfo.stackSize = ss; \
1131  methodInfo.signatureString = &m##signature[0]; \
1132  methodInfo.help = &m##help[0]; \
1133  xmlrpc_env_init(&env); \
1134  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1135  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1136  xmlrpc_env_clean(&env)
1137 
1138 #define unregister_method(m) delete ptr_##m;
1139 
1140  register_method2(init, 0x200000);
1141  register_method(soft_init);
1142  register_method(reinit);
1143  register_method(start);
1144  register_method(status);
1145  register_method(report);
1146  register_method(stop);
1147  register_method(pause);
1148  register_method(resume);
1149  register_method(register_monitor);
1150  register_method(unregister_monitor);
1151  register_method(legal_commands);
1152  register_method(trace_set);
1153  register_method(trace_get);
1154  register_method(meta_command);
1155  register_method(rollover_subrun);
1156  register_method(add_config_archive_entry);
1157  register_method(clear_config_archive);
1158 
1159  register_method(shutdown);
1160 
1161  // alias "daq.reset" to the internal shutdown transition
1162  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1163  registry.addMethod("daq.reset", ptr_reset);
1164 
1165 #undef register_method
1166 
1167  // JCF, 6/3/15
1168 
1169  // In the following code, I configure a socket to have the
1170  // SO_REUSEADDR option so that once an artdaq process closes, the
1171  // port it was communicating on becomes immediately available
1172  // (desirable if, say, the DAQ program is terminated and then
1173  // immediately restarted)
1174 
1175  // Much of the following code is cribbed from
1176  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1177 
1178  // Below, "0" is the default protocol (in this case, given the IPv4
1179  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1180  // method)
1181 
1182  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1183 
1184  if (socket_file_descriptor < 0)
1185  {
1186  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1187  }
1188 
1189  int enable = 1;
1190  int retval = setsockopt(socket_file_descriptor,
1191  SOL_SOCKET, SO_REUSEADDR,
1192  &enable, sizeof(int));
1193 
1194  if (retval < 0)
1195  {
1196  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1197  }
1198 
1199  struct sockaddr_in sockAddr;
1200 
1201  sockAddr.sin_family = AF_INET;
1202  sockAddr.sin_port = htons(port_);
1203  sockAddr.sin_addr.s_addr = 0;
1204 
1205  retval = bind(socket_file_descriptor,
1206  reinterpret_cast<struct sockaddr*>(&sockAddr), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1207  sizeof(sockAddr));
1208 
1209  if (retval != 0)
1210  {
1211  close(socket_file_descriptor);
1212  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1213  }
1214 
1215  server = std::make_unique<xmlrpc_c::serverAbyss>(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor));
1216 
1217 #if 0
1218  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1219  registry.setShutdown(&shutdown_obj);
1220 #endif
1221 
1222  TLOG(TLVL_DEBUG) << "running server";
1223 
1224  // JCF, 6/3/15
1225 
1226  // Use a catch block to clean up (i.e., close the socket). An
1227  // opportunity for RAII, although all control paths are limited to
1228  // this section of the file...
1229 
1230  try
1231  {
1232  running_ = true;
1233  server->run();
1234  running_ = false;
1235  }
1236  catch (...)
1237  {
1238  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1239  running_ = false;
1240  close(socket_file_descriptor);
1241  throw;
1242  }
1243 
1244  close(socket_file_descriptor);
1245 
1246  unregister_method(init);
1247  unregister_method(soft_init);
1248  unregister_method(reinit);
1249  unregister_method(start);
1250  unregister_method(status);
1251  unregister_method(report);
1252  unregister_method(stop);
1253  unregister_method(pause);
1254  unregister_method(resume);
1255  unregister_method(register_monitor);
1256  unregister_method(unregister_monitor);
1257  unregister_method(legal_commands);
1258  unregister_method(trace_set);
1259  unregister_method(trace_get);
1260  unregister_method(meta_command);
1261  unregister_method(rollover_subrun);
1262  unregister_method(add_config_archive_entry);
1263  unregister_method(clear_config_archive);
1264 
1265  unregister_method(shutdown);
1266 
1267  TLOG(TLVL_DEBUG) << "server terminated";
1268 }
1269 catch (...)
1270 {
1271  throw;
1272 }
1273 
1274 std::string xmlrpc_commander::send_command_(const std::string& command)
1275 {
1276  if (serverUrl_.empty())
1277  {
1278  std::stringstream errmsg;
1279  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1280  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1281  }
1282  xmlrpc_c::clientSimple myClient;
1283  xmlrpc_c::value result;
1284 
1285  try
1286  {
1287  myClient.call(serverUrl_, "daq." + command, "", &result);
1288  }
1289  catch (...)
1290  {
1291  std::stringstream errmsg;
1292  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1293  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1294  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1295  }
1296 
1297  return xmlrpc_c::value_string(result);
1298 }
1299 
1300 std::string xmlrpc_commander::send_command_(const std::string& command, const std::string& arg)
1301 {
1302  if (serverUrl_.empty())
1303  {
1304  std::stringstream errmsg;
1305  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1306  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1307  }
1308  xmlrpc_c::clientSimple myClient;
1309  xmlrpc_c::value result;
1310 
1311  try
1312  {
1313  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1314  }
1315  catch (...)
1316  {
1317  std::stringstream errmsg;
1318  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1319  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1320  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1321  }
1322 
1323  return xmlrpc_c::value_string(result);
1324 }
1325 
1326 std::string xmlrpc_commander::send_command_(const std::string& command, const fhicl::ParameterSet& pset, uint64_t timestamp, uint64_t timeout)
1327 {
1328  if (serverUrl_.empty())
1329  {
1330  std::stringstream errmsg;
1331  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1332  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1333  }
1334  xmlrpc_c::clientSimple myClient;
1335  xmlrpc_c::value result;
1336 
1337  try
1338  {
1339  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1340  }
1341  catch (...)
1342  {
1343  std::stringstream errmsg;
1344  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1345  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1346  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1347  }
1348 
1349  return xmlrpc_c::value_string(result);
1350 }
1351 
1352 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint64_t b)
1353 {
1354  if (serverUrl_.empty())
1355  {
1356  std::stringstream errmsg;
1357  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1358  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1359  }
1360  xmlrpc_c::clientSimple myClient;
1361  xmlrpc_c::value result;
1362 
1363  try
1364  {
1365  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1366  }
1367  catch (...)
1368  {
1369  std::stringstream errmsg;
1370  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1371  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1372  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1373  }
1374 
1375  return xmlrpc_c::value_string(result);
1376 }
1377 
1378 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint32_t b)
1379 {
1380  if (serverUrl_.empty())
1381  {
1382  std::stringstream errmsg;
1383  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1384  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1385  }
1386  xmlrpc_c::clientSimple myClient;
1387  xmlrpc_c::value result;
1388 
1389  try
1390  {
1391  myClient.call(serverUrl_, "daq." + command, "Ii", &result, a, b);
1392  }
1393  catch (...)
1394  {
1395  std::stringstream errmsg;
1396  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1397  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1398  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1399  }
1400 
1401  return xmlrpc_c::value_string(result);
1402 }
1403 
1404 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, art::RunID r, uint64_t a, uint64_t b)
1405 {
1406  if (serverUrl_.empty())
1407  {
1408  std::stringstream errmsg;
1409  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1410  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1411  }
1412  xmlrpc_c::clientSimple myClient;
1413  xmlrpc_c::value result;
1414 
1415  try
1416  {
1417  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1418  }
1419  catch (...)
1420  {
1421  std::stringstream errmsg;
1422  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1423  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1424  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1425  }
1426 
1427  return xmlrpc_c::value_string(result);
1428 }
1429 
1430 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t arg1)
1431 {
1432  if (serverUrl_.empty())
1433  {
1434  std::stringstream errmsg;
1435  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1436  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1437  }
1438  xmlrpc_c::clientSimple myClient;
1439  xmlrpc_c::value result;
1440 
1441  try
1442  {
1443  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1444  }
1445  catch (...)
1446  {
1447  std::stringstream errmsg;
1448  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1449  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1450  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1451  }
1452 
1453  return xmlrpc_c::value_string(result);
1454 }
1455 
1456 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2)
1457 {
1458  if (serverUrl_.empty())
1459  {
1460  std::stringstream errmsg;
1461  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1462  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1463  }
1464  xmlrpc_c::clientSimple myClient;
1465  xmlrpc_c::value result;
1466 
1467  try
1468  {
1469  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1470  }
1471  catch (...)
1472  {
1473  std::stringstream errmsg;
1474  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1475  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1476  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1477  }
1478 
1479  return xmlrpc_c::value_string(result);
1480 }
1481 
1482 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2, const std::string& arg3)
1483 {
1484  if (serverUrl_.empty())
1485  {
1486  std::stringstream errmsg;
1487  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1488  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1489  }
1490  xmlrpc_c::clientSimple myClient;
1491  xmlrpc_c::value result;
1492 
1493  try
1494  {
1495  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1496  }
1497  catch (...)
1498  {
1499  std::stringstream errmsg;
1500  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1501  << "; possible causes are bad arguments or nonexistent process at requested port";
1502  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1503  }
1504 
1505  return xmlrpc_c::value_string(result);
1506 }
1507 
1508 std::string xmlrpc_commander::send_register_monitor(std::string const& monitor_fhicl)
1509 {
1510  return send_command_("register_monitor", monitor_fhicl);
1511 }
1512 std::string xmlrpc_commander::send_unregister_monitor(std::string const& monitor_label)
1513 {
1514  return send_command_("unregister_monitor", monitor_label);
1515 }
1516 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1517 {
1518  return send_command_("init", ps, timeout, timestamp);
1519 }
1520 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1521 {
1522  return send_command_("soft_init", ps, timeout, timestamp);
1523 }
1524 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1525 {
1526  return send_command_("reinit", ps, timeout, timestamp);
1527 }
1528 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1529 {
1530  return send_command_("start", run, timeout, timestamp);
1531 }
1532 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1533 {
1534  return send_command_("pause", timeout, timestamp);
1535 }
1536 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1537 {
1538  return send_command_("resume", timeout, timestamp);
1539 }
1540 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1541 {
1542  return send_command_("stop", timeout, timestamp);
1543 }
1544 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1545 {
1546  return send_command_("shutdown", timeout);
1547 }
1549 {
1550  return send_command_("status");
1551 }
1552 std::string xmlrpc_commander::send_report(std::string const& what)
1553 {
1554  return send_command_("report", what);
1555 }
1557 {
1558  return send_command_("legal_commands");
1559 }
1560 std::string xmlrpc_commander::send_trace_get(std::string const& name)
1561 {
1562  return send_command_("trace_get", name);
1563 }
1564 std::string xmlrpc_commander::send_trace_set(std::string const& name, std::string const& type, std::string const& mask)
1565 {
1566  return send_command_("trace_set", name, type, mask);
1567 }
1568 std::string xmlrpc_commander::send_meta_command(std::string const& command, std::string const& arg)
1569 {
1570  return send_command_("meta_command", command, arg);
1571 }
1572 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1573 {
1574  return send_command_("rollover_subrun", when, sr);
1575 }
1576 } // namespace artdaq
1577 
1578 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:538
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
virtual std::string report(std::string const &) const
Default report implementation returns current report_string.
Definition: Commandable.hh:124
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:544
Command class representing a start transition.
rollover_subrun_(xmlrpc_commander &c)
shutdown_ Constructor
xmlrpc_commander(const fhicl::ParameterSet &ps, artdaq::Commandable &commandable)
xmlrpc_commander Constructor
std::string send_trace_set(std::string const &name, std::string const &type, std::string const &mask) override
Send an send_trace_msgfacility_set command over XMLRPC
status_ Command class
std::string send_register_monitor(std::string const &monitor_fhicl) override
Send a register_monitor command over XMLRPC
std::string send_init(fhicl::ParameterSet const &ps, uint64_t timeout, uint64_t timestamp) override
Send an init command over XMLRPC
std::string send_meta_command(std::string const &command, std::string const &argument) override
Send an send_meta_command command over XMLRPC
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:153
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.
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:299
std::string send_shutdown(uint64_t timeout) override
Send a shutdown command over XMLRPC
std::string send_reinit(fhicl::ParameterSet const &ps, uint64_t timeout, uint64_t timestamp) override
Send a reinit 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
std::string send_trace_get(std::string const &name) override
Send an send_trace_get command over XMLRPC
virtual std::string register_monitor(fhicl::ParameterSet const &)
Perform the register_monitor action.
Definition: Commandable.hh:142
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:472
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.
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
virtual std::string add_config_archive_entry(std::string const &key, std::string const &value)
Using the transport mechanism, send an add_config_archive_entry command
void execute(const xmlrpc_c::paramList &paramList, xmlrpc_c::value *retvalP) final
Execute trhe command with the given parameters.
status_(xmlrpc_commander &c)
status_ Constructor
clear_config_archive_(xmlrpc_commander &c)
clear_config_archive_ Constructor
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
std::string send_rollover_subrun(uint64_t when, uint32_t sr) override
Send a send_rollover_subrun command over XMLRPC
unregister_monitor_(xmlrpc_commander &c)
unregister_monitor_ Constructor
virtual bool execute_(const xmlrpc_c::paramList &, xmlrpc_c::value *retvalP)=0
&quot;execute_&quot; is a wrapper function around the call to the commandable object&#39;s function ...
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:312
std::string send_soft_init(fhicl::ParameterSet const &ps, uint64_t timeout, uint64_t timestamp) override
Send a soft_init command over XMLRPC
rollover_subrun_ Command class
std::string send_resume(uint64_t timeout, uint64_t timestamp) override
Send a resume command over XMLRPC
std::string send_unregister_monitor(std::string const &monitor_label) override
Send an unregister_monitor command over XMLRPC
std::string send_report(std::string const &what) override
Send a report command over XMLRPC
bool start(art::RunID id, uint64_t timeout, uint64_t timestamp)
Processes the start transition.
Definition: Commandable.cc:62
report_(xmlrpc_commander &c)
report_ Constructor
trace_set_ Command class
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:435
virtual bool do_meta_command(std::string const &cmd, std::string const &args)
Run a module-defined command with the given parameter string.
Definition: Commandable.cc:525
trace_get_(xmlrpc_commander &c)
trace_msgfacility_set_ Constructor
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:531
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:181