artdaq  v3_09_04
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 "canvas/Persistency/Provenance/RunID.h"
34 #include "fhiclcpp/make_ParameterSet.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  TLOG(TLVL_TRACE) << "Param value: " << paramList.getI8(index);
366  return static_cast<uint64_t>(paramList.getI8(index));
367 }
368 
377 template<>
378 uint32_t cmd_::getParam<uint32_t>(const xmlrpc_c::paramList& paramList, int index)
379 {
380  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as uint32_t.";
381  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
382  return static_cast<uint32_t>(paramList.getInt(index));
383 }
384 
393 template<>
394 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
395 {
396  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as string.";
397  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
398  return static_cast<std::string>(paramList.getString(index));
399 }
400 
409 template<>
410 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
411 {
412  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as Run Number.";
413  art::RunNumber_t run_number;
414  try
415  {
416  TLOG(TLVL_TRACE) << "Param value: " << paramList.getInt(index);
417  run_number = art::RunNumber_t(paramList.getInt(index));
418  }
419  catch (...)
420  {
421  TLOG(TLVL_TRACE) << "Parameter is not an int. Trying string...";
422 
423  auto runNumber = paramList.getString(index);
424  TLOG(TLVL_TRACE) << "Got run number string " << runNumber;
425  run_number = art::RunNumber_t(std::stoi(runNumber));
426  }
427 
428  art::RunID run_id(run_number);
429  return run_id;
430 }
431 
440 template<>
441 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
442 {
443  TLOG(TLVL_TRACE) << "Getting parameter " << index << " from list as ParameterSet.";
444  TLOG(TLVL_TRACE) << "Param value: " << paramList.getString(index);
445  std::string configString = std::string(paramList.getString(index));
446  TLOG(TLVL_DEBUG) << "Loading Parameter Set from string: " << configString << std::endl;
447  fhicl::ParameterSet pset;
448 
449  try
450  {
451  fhicl::make_ParameterSet(configString, pset);
452  }
453  catch (const fhicl::exception& e)
454  {
455  if (getenv("FHICL_FILE_PATH") == nullptr)
456  {
457  std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
458  setenv("FHICL_FILE_PATH", ".", 0);
459  }
460  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
461  fhicl::make_ParameterSet(configString, lookup_policy, pset);
462  }
463 
464  TLOG(TLVL_INFO) << "Parameter Set Loaded." << std::endl;
465  return pset;
466 }
467 
468 template<typename T>
469 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
470  T default_value)
471 {
472  T val = default_value;
473 
474  if (static_cast<unsigned>(index) < paramList.size())
475  {
476  val = getParam<T>(paramList, index);
477  }
478  return val;
479 }
480 
481 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
482 {
483  TLOG(TLVL_TRACE) << "Received Request to " << _help << ", attempting to get lock";
484  std::unique_lock<std::timed_mutex> lk(_c.mutex_, std::defer_lock);
485  lk.try_lock_for(std::chrono::milliseconds(250));
486 
487  if (lk.owns_lock())
488  {
489  try
490  {
491  // JCF, 9/4/14
492 
493  // Assuming the execute_ function returns true, then if the
494  // retvalP argument was untouched, assign it the string
495  // "Success"
496 
497  // See
498  // http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#isinstantiated
499  // for more on the concept of instantiation in xmlrpc_c::value objects
500 
501  if (execute_(paramList, retvalP))
502  {
503  if (!retvalP->isInstantiated())
504  {
505  *retvalP = xmlrpc_c::value_string("Success");
506  }
507  }
508  else
509  {
510  std::string problemReport = _c._commandable.report("transition_status");
511  *retvalP = xmlrpc_c::value_string(problemReport);
512  }
513  }
514  catch (std::runtime_error& er)
515  {
516  std::string msg = exception_msg(er, _help);
517  *retvalP = xmlrpc_c::value_string(msg);
518  TLOG(TLVL_ERROR) << msg;
519  }
520  catch (art::Exception& er)
521  {
522  std::string msg = exception_msg(er, _help);
523  *retvalP = xmlrpc_c::value_string(msg);
524  TLOG(TLVL_ERROR) << msg;
525  }
526  catch (cet::exception& er)
527  {
528  std::string msg = exception_msg(er, _help);
529  *retvalP = xmlrpc_c::value_string(msg);
530  TLOG(TLVL_ERROR) << msg;
531  }
532  catch (boost::exception& er)
533  {
534  std::string msg = exception_msg(er, _help);
535  *retvalP = xmlrpc_c::value_string(msg);
536  TLOG(TLVL_ERROR) << msg;
537  }
538  catch (std::exception& er)
539  {
540  std::string msg = exception_msg(er, _help);
541  *retvalP = xmlrpc_c::value_string(msg);
542  TLOG(TLVL_ERROR) << msg;
543  }
544  catch (...)
545  {
546  std::string msg = exception_msg("Unknown exception (not from std, boost, cet, or art)", _help);
547  *retvalP = xmlrpc_c::value_string(msg);
548  TLOG(TLVL_ERROR) << msg;
549  }
550 
551  lk.unlock();
552  }
553  else
554  {
555  TLOG(TLVL_ERROR) << "Unable to get lock while trying to " << _help << ", returning busy";
556  *retvalP = xmlrpc_c::value_string("busy");
557  }
558 }
559 
561 
562 // JCF, 9/5/14
563 
564 // The three "init" transitions all take a FHiCL parameter list, and
565 // optionally a timeout and a timestamp; thus we can kill three birds
566 // with one stone in the GENERATE_INIT_TRANSITION macro
567 
568 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
569  \
570  class NAME##_ : public cmd_ \
571  { \
572  public: \
573  \
576  explicit NAME##_(xmlrpc_commander& c) : cmd_(c, "s:sII", DESCRIPTION) {} \
577  \
578  \
579  static const uint64_t defaultTimeout = 45; \
580  \
581  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
582  \
583  private: \
584  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) \
585  { \
586  fhicl::ParameterSet ps; \
587  try \
588  { \
589  ps = getParam<fhicl::ParameterSet>(paramList, 0); \
590  } \
591  catch (...) \
592  { \
593  *retvalP = xmlrpc_c::value_string("Error: The " #NAME " message requires a single argument that is a string containing the initialization ParameterSet"); \
594  return true; \
595  } \
596  \
597  return _c._commandable.CALL(ps, \
598  getParam<uint64_t>(paramList, 1, defaultTimeout), \
599  getParam<uint64_t>(paramList, 2, defaultTimestamp)); \
600  } \
601  };
602 
603 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
604 
605 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
606 
607 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
608 
609 #undef GENERATE_INIT_TRANSITION
610 
612 
616 class start_ : public cmd_
617 {
618 public:
624  : cmd_(c, "s:iII", "start the run")
625  {}
626 
628  static const uint64_t defaultTimeout = 45;
630  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
631 
632 private:
633  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
634  {
635  try
636  {
637  getParam<art::RunID>(paramList, 0);
638  }
639  catch (...)
640  {
641  *retvalP = xmlrpc_c::value_string("Error: The start message requires the run number as an argument.");
642  return true;
643  }
644 
645  return _c._commandable.start(getParam<art::RunID>(paramList, 0),
646  getParam<uint64_t>(paramList, 1, defaultTimeout),
647  getParam<uint64_t>(paramList, 2, defaultTimestamp));
648  }
649 };
650 
652 
653 // JCF, 9/5/14
654 
655 // "pause", "resume" and "stop" all take an optional timeout and
656 // timestamp parameter, so we can generate them all with the
657 // GENERATE_TIMEOUT_TIMESTAMP_TRANSITION macro
658 
659 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
660  \
661  class NAME##_ : public cmd_ \
662  { \
663  public: \
664  \
666  NAME##_(xmlrpc_commander& c) : cmd_(c, "s:II", DESCRIPTION) {} \
667  \
668  \
669  static const uint64_t defaultTimeout = TIMEOUT; \
670  \
671  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
672  \
673  private: \
674  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const) \
675  { \
676  return _c._commandable.CALL(getParam<uint64_t>(paramList, 0, defaultTimeout), \
677  getParam<uint64_t>(paramList, 1, defaultTimestamp)); \
678  } \
679  };
680 
681 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
682 
683 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
684 
685 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
686 
687 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
688 
692 class shutdown_ : public cmd_
693 {
694 public:
700  : cmd_(c, "s:i", "shutdown the program")
701  {}
702 
704  static const uint64_t defaultTimeout = 45;
705 
706 private:
707  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
708  {
709  auto ret = _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
710 
711 #if 1
712  if (_c.server)
713  {
714  _c.server->terminate();
715  }
716 #endif
717 
718  return ret;
719  }
720 };
721 
725 class status_ : public cmd_
726 {
727 public:
733  : cmd_(c, "s:n", "report the current state")
734  {}
735 
736 private:
737  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
738  {
739  *retvalP = xmlrpc_c::value_string(_c._commandable.status());
740  return true;
741  }
742 };
743 
747 class report_ : public cmd_
748 {
749 public:
755  : cmd_(c, "s:s", "report statistics")
756  {}
757 
758 private:
759  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
760  {
761  try
762  {
763  getParam<std::string>(paramList, 0);
764  }
765  catch (...)
766  {
767  *retvalP = xmlrpc_c::value_string("Error: The report message requires a single argument that selects the type of statistics to be reported.");
768  return true;
769  }
770 
771  *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
772  return true;
773  }
774 };
775 
779 class legal_commands_ : public cmd_
780 {
781 public:
787  : cmd_(c, "s:n", "return the currently legal commands")
788  {}
789 
790 private:
791  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
792  {
793  std::vector<std::string> cmdList = _c._commandable.legal_commands();
794  std::string resultString;
795 
796  for (auto& cmd : cmdList)
797  {
798  resultString.append(cmd + " ");
799  if (cmd == "shutdown")
800  {
801  resultString.append(" reset");
802  }
803  }
804  *retvalP = xmlrpc_c::value_string(resultString);
805 
806  return true;
807  }
808 };
809 
813 class register_monitor_ : public cmd_
814 {
815 public:
821  : cmd_(c, "s:s", "Get notified of a new monitor")
822  {}
823 
824 private:
825  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
826  {
827  try
828  {
829  getParam<fhicl::ParameterSet>(paramList, 0);
830  }
831  catch (...)
832  {
833  *retvalP = xmlrpc_c::value_string("Error: The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
834  return true;
835  }
836 
837  *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
838  return true;
839  }
840 };
841 
845 class unregister_monitor_ : public cmd_
846 {
847 public:
853  : cmd_(c, "s:s", "Remove a monitor")
854  {}
855 
856 private:
857  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
858  {
859  try
860  {
861  getParam<std::string>(paramList, 0);
862  }
863  catch (...)
864  {
865  *retvalP = xmlrpc_c::value_string("Error: The unregister_monitor command expects a string representing the label of the monitor to be removed");
866  return true;
867  }
868 
869  *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
870  return true;
871  }
872 };
873 
877 class trace_set_ : public cmd_
878 {
879 public:
885  : cmd_(c, "s:ssI", "Set TRACE mask")
886  {}
887 
888 private:
889  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
890  {
891  try
892  {
893  getParam<std::string>(paramList, 0);
894  getParam<std::string>(paramList, 1);
895  getParam<std::string>(paramList, 2);
896  }
897  catch (...)
898  {
899  *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");
900  return true;
901  }
902 
903  return _c._commandable.do_trace_set(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1), getParam<std::string>(paramList, 2));
904  }
905 };
906 
910 class trace_get_ : public cmd_
911 {
912 public:
918  : cmd_(c, "s:s", "Get TRACE mask")
919  {}
920 
921 private:
922  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
923  {
924  try
925  {
926  getParam<std::string>(paramList, 0);
927  }
928  catch (...)
929  {
930  *retvalP = xmlrpc_c::value_string("Error: The trace_get command expects a name (ALL for all)");
931  return true;
932  }
933 
934  *retvalP = xmlrpc_c::value_string(_c._commandable.do_trace_get(getParam<std::string>(paramList, 0)));
935  return true;
936  }
937 };
938 
942 class meta_command_ : public cmd_
943 {
944 public:
950  : cmd_(c, "s:ss", "Run custom command")
951  {}
952 
953 private:
954  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
955  {
956  try
957  {
958  getParam<std::string>(paramList, 0);
959  getParam<std::string>(paramList, 1);
960  }
961  catch (...)
962  {
963  *retvalP = xmlrpc_c::value_string("Error: The meta_command command expects a string command and a string argument");
964  return true;
965  }
966 
967  return _c._commandable.do_meta_command(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
968  }
969 };
970 
974 class rollover_subrun_ : public cmd_
975 {
976 public:
982  : cmd_(c, "s:Ii", "create a new subrun")
983  {}
984 
985  static const uint64_t defaultSequenceID = 0xFFFFFFFFFFFFFFFF;
986  static const uint32_t defaultSubrunNumber = 1;
987 
988 private:
989  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
990  {
991  auto ret = _c._commandable.do_rollover_subrun(getParam<uint64_t>(paramList, 0, defaultSequenceID), getParam<uint32_t>(paramList, 1, defaultSubrunNumber));
992  return ret;
993  }
994 };
995 
1000 {
1001 public:
1007  : cmd_(c, "s:ss", "Add an entry to the configuration archive list")
1008  {}
1009 
1010 private:
1011  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1012  {
1013  try
1014  {
1015  getParam<std::string>(paramList, 0);
1016  getParam<std::string>(paramList, 1);
1017  }
1018  catch (...)
1019  {
1020  *retvalP = xmlrpc_c::value_string("Error: The add_config_archive_entry command expects a string key and a string value");
1021  return true;
1022  }
1023 
1024  return _c._commandable.do_add_config_archive_entry(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
1025  }
1026 };
1027 
1032 {
1033 public:
1039  : cmd_(c, "s:n", "Clear the configuration archive list")
1040  {}
1041 
1042 private:
1043  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const /*retvalP*/) override
1044  {
1046  }
1047 };
1048 
1049 // JCF, 9/4/14
1050 
1051 // Not sure if anyone was planning to resurrect this code by changing
1052 // the preprocessor decision; as such, I'll leave it in for now...
1053 
1054 #if 0
1055  class shutdown_ : public xmlrpc_c::registry::shutdown
1056  {
1057  public:
1058  shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
1059 
1060  virtual void doit(const std::string& paramString, void*) const
1061  {
1062  TLOG(TLVL_INFO) << "A shutdown command was sent "
1063  << "with parameter "
1064  << paramString << "\"";
1065  _server->terminate();
1066  }
1067  private:
1068  xmlrpc_c::serverAbyss *_server;
1069  };
1070 #endif
1071 
1072 xmlrpc_commander::xmlrpc_commander(const fhicl::ParameterSet& ps, artdaq::Commandable& commandable)
1073  : CommanderInterface(ps, commandable)
1074  , port_(ps.get<int>("id", 0))
1075  , serverUrl_(ps.get<std::string>("server_url", ""))
1076  , server(nullptr)
1077 {
1078  if (serverUrl_.empty())
1079  {
1080  char hostname[HOST_NAME_MAX];
1081  gethostname(hostname, HOST_NAME_MAX);
1082  serverUrl_ = std::string(hostname);
1083  }
1084  if (serverUrl_.find("http") == std::string::npos)
1085  {
1086  serverUrl_ = "http://" + serverUrl_;
1087  }
1088  if (serverUrl_.find(std::to_string(port_)) == std::string::npos && serverUrl_.find(':', 7) == std::string::npos)
1089  {
1090  serverUrl_ = serverUrl_ + ":" + std::to_string(port_);
1091  }
1092  if (serverUrl_.find("RPC2") == std::string::npos)
1093  {
1094  serverUrl_ = serverUrl_ + "/RPC2";
1095  }
1096  TLOG(TLVL_INFO) << "XMLRPC COMMANDER CONSTRUCTOR: Port: " << port_ << ", Server Url: " << serverUrl_;
1097 }
1098 
1100 {
1101  //std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1102  xmlrpc_c::registry registry;
1103  struct xmlrpc_method_info3 methodInfo;
1104  memset(&methodInfo, 0, sizeof(methodInfo));
1105 
1106  /*#define register_method(m) \
1107  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1108  registry.addMethod ("daq." #m, ptr_ ## m) */
1109 #define register_method(m) register_method2(m, 0x400000)
1110 
1111  xmlrpc_env env; // xmlrpc_env_init(&env);
1112  xmlrpc_registry*** c_registryPPP;
1113  c_registryPPP = reinterpret_cast<xmlrpc_registry***>(reinterpret_cast<char*>(&registry) + sizeof(girmem::autoObject)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
1114 
1115 #define register_method2(m, ss) \
1116  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1117  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1118  methodInfo.methodName = "daq." #m; \
1119  methodInfo.methodFunction = &c_executeMethod; \
1120  methodInfo.serverInfo = ptr_##m; \
1121  methodInfo.stackSize = ss; \
1122  methodInfo.signatureString = &m##signature[0]; \
1123  methodInfo.help = &m##help[0]; \
1124  xmlrpc_env_init(&env); \
1125  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1126  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1127  xmlrpc_env_clean(&env)
1128 
1129  register_method2(init, 0x200000);
1130  register_method(soft_init);
1131  register_method(reinit);
1132  register_method(start);
1133  register_method(status);
1134  register_method(report);
1135  register_method(stop);
1136  register_method(pause);
1137  register_method(resume);
1138  register_method(register_monitor);
1139  register_method(unregister_monitor);
1140  register_method(legal_commands);
1141  register_method(trace_set);
1142  register_method(trace_get);
1143  register_method(meta_command);
1144  register_method(rollover_subrun);
1145  register_method(add_config_archive_entry);
1146  register_method(clear_config_archive);
1147 
1148  register_method(shutdown);
1149 
1150  // alias "daq.reset" to the internal shutdown transition
1151  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1152  registry.addMethod("daq.reset", ptr_reset);
1153 
1154 #undef register_method
1155 
1156  // JCF, 6/3/15
1157 
1158  // In the following code, I configure a socket to have the
1159  // SO_REUSEADDR option so that once an artdaq process closes, the
1160  // port it was communicating on becomes immediately available
1161  // (desirable if, say, the DAQ program is terminated and then
1162  // immediately restarted)
1163 
1164  // Much of the following code is cribbed from
1165  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1166 
1167  // Below, "0" is the default protocol (in this case, given the IPv4
1168  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1169  // method)
1170 
1171  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1172 
1173  if (socket_file_descriptor < 0)
1174  {
1175  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1176  }
1177 
1178  int enable = 1;
1179  int retval = setsockopt(socket_file_descriptor,
1180  SOL_SOCKET, SO_REUSEADDR,
1181  &enable, sizeof(int));
1182 
1183  if (retval < 0)
1184  {
1185  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1186  }
1187 
1188  struct sockaddr_in sockAddr;
1189 
1190  sockAddr.sin_family = AF_INET;
1191  sockAddr.sin_port = htons(port_);
1192  sockAddr.sin_addr.s_addr = 0;
1193 
1194  retval = bind(socket_file_descriptor,
1195  reinterpret_cast<struct sockaddr*>(&sockAddr), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1196  sizeof(sockAddr));
1197 
1198  if (retval != 0)
1199  {
1200  close(socket_file_descriptor);
1201  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1202  }
1203 
1204  server = std::make_unique<xmlrpc_c::serverAbyss>(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor));
1205 
1206 #if 0
1207  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1208  registry.setShutdown(&shutdown_obj);
1209 #endif
1210 
1211  TLOG(TLVL_DEBUG) << "running server";
1212 
1213  // JCF, 6/3/15
1214 
1215  // Use a catch block to clean up (i.e., close the socket). An
1216  // opportunity for RAII, although all control paths are limited to
1217  // this section of the file...
1218 
1219  try
1220  {
1221  running_ = true;
1222  server->run();
1223  running_ = false;
1224  }
1225  catch (...)
1226  {
1227  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1228  running_ = false;
1229  close(socket_file_descriptor);
1230  throw;
1231  }
1232 
1233  close(socket_file_descriptor);
1234  TLOG(TLVL_DEBUG) << "server terminated";
1235 }
1236 catch (...)
1237 {
1238  throw;
1239 }
1240 
1241 std::string xmlrpc_commander::send_command_(const std::string& command)
1242 {
1243  if (serverUrl_.empty())
1244  {
1245  std::stringstream errmsg;
1246  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1247  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1248  }
1249  xmlrpc_c::clientSimple myClient;
1250  xmlrpc_c::value result;
1251 
1252  try
1253  {
1254  myClient.call(serverUrl_, "daq." + command, "", &result);
1255  }
1256  catch (...)
1257  {
1258  std::stringstream errmsg;
1259  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1260  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1261  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1262  }
1263 
1264  return xmlrpc_c::value_string(result);
1265 }
1266 
1267 std::string xmlrpc_commander::send_command_(const std::string& command, const std::string& arg)
1268 {
1269  if (serverUrl_.empty())
1270  {
1271  std::stringstream errmsg;
1272  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1273  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1274  }
1275  xmlrpc_c::clientSimple myClient;
1276  xmlrpc_c::value result;
1277 
1278  try
1279  {
1280  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1281  }
1282  catch (...)
1283  {
1284  std::stringstream errmsg;
1285  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1286  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1287  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1288  }
1289 
1290  return xmlrpc_c::value_string(result);
1291 }
1292 
1293 std::string xmlrpc_commander::send_command_(const std::string& command, const fhicl::ParameterSet& pset, uint64_t timestamp, uint64_t timeout)
1294 {
1295  if (serverUrl_.empty())
1296  {
1297  std::stringstream errmsg;
1298  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1299  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1300  }
1301  xmlrpc_c::clientSimple myClient;
1302  xmlrpc_c::value result;
1303 
1304  try
1305  {
1306  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1307  }
1308  catch (...)
1309  {
1310  std::stringstream errmsg;
1311  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1312  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1313  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1314  }
1315 
1316  return xmlrpc_c::value_string(result);
1317 }
1318 
1319 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint64_t b)
1320 {
1321  if (serverUrl_.empty())
1322  {
1323  std::stringstream errmsg;
1324  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1325  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1326  }
1327  xmlrpc_c::clientSimple myClient;
1328  xmlrpc_c::value result;
1329 
1330  try
1331  {
1332  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1333  }
1334  catch (...)
1335  {
1336  std::stringstream errmsg;
1337  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1338  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1339  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1340  }
1341 
1342  return xmlrpc_c::value_string(result);
1343 }
1344 
1345 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint32_t b)
1346 {
1347  if (serverUrl_.empty())
1348  {
1349  std::stringstream errmsg;
1350  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1351  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1352  }
1353  xmlrpc_c::clientSimple myClient;
1354  xmlrpc_c::value result;
1355 
1356  try
1357  {
1358  myClient.call(serverUrl_, "daq." + command, "Ii", &result, a, b);
1359  }
1360  catch (...)
1361  {
1362  std::stringstream errmsg;
1363  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1364  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1365  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1366  }
1367 
1368  return xmlrpc_c::value_string(result);
1369 }
1370 
1371 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, art::RunID r, uint64_t a, uint64_t b)
1372 {
1373  if (serverUrl_.empty())
1374  {
1375  std::stringstream errmsg;
1376  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1377  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1378  }
1379  xmlrpc_c::clientSimple myClient;
1380  xmlrpc_c::value result;
1381 
1382  try
1383  {
1384  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1385  }
1386  catch (...)
1387  {
1388  std::stringstream errmsg;
1389  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1390  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1391  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1392  }
1393 
1394  return xmlrpc_c::value_string(result);
1395 }
1396 
1397 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t arg1)
1398 {
1399  if (serverUrl_.empty())
1400  {
1401  std::stringstream errmsg;
1402  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1403  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1404  }
1405  xmlrpc_c::clientSimple myClient;
1406  xmlrpc_c::value result;
1407 
1408  try
1409  {
1410  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1411  }
1412  catch (...)
1413  {
1414  std::stringstream errmsg;
1415  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1416  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1417  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1418  }
1419 
1420  return xmlrpc_c::value_string(result);
1421 }
1422 
1423 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2)
1424 {
1425  if (serverUrl_.empty())
1426  {
1427  std::stringstream errmsg;
1428  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1429  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1430  }
1431  xmlrpc_c::clientSimple myClient;
1432  xmlrpc_c::value result;
1433 
1434  try
1435  {
1436  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1437  }
1438  catch (...)
1439  {
1440  std::stringstream errmsg;
1441  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1442  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1443  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1444  }
1445 
1446  return xmlrpc_c::value_string(result);
1447 }
1448 
1449 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2, const std::string& arg3)
1450 {
1451  if (serverUrl_.empty())
1452  {
1453  std::stringstream errmsg;
1454  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1455  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1456  }
1457  xmlrpc_c::clientSimple myClient;
1458  xmlrpc_c::value result;
1459 
1460  try
1461  {
1462  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1463  }
1464  catch (...)
1465  {
1466  std::stringstream errmsg;
1467  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1468  << "; possible causes are bad arguments or nonexistent process at requested port";
1469  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1470  }
1471 
1472  return xmlrpc_c::value_string(result);
1473 }
1474 
1475 std::string xmlrpc_commander::send_register_monitor(std::string const& monitor_fhicl)
1476 {
1477  return send_command_("register_monitor", monitor_fhicl);
1478 }
1479 std::string xmlrpc_commander::send_unregister_monitor(std::string const& monitor_label)
1480 {
1481  return send_command_("unregister_monitor", monitor_label);
1482 }
1483 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1484 {
1485  return send_command_("init", ps, timeout, timestamp);
1486 }
1487 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1488 {
1489  return send_command_("soft_init", ps, timeout, timestamp);
1490 }
1491 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1492 {
1493  return send_command_("reinit", ps, timeout, timestamp);
1494 }
1495 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1496 {
1497  return send_command_("start", run, timeout, timestamp);
1498 }
1499 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1500 {
1501  return send_command_("pause", timeout, timestamp);
1502 }
1503 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1504 {
1505  return send_command_("resume", timeout, timestamp);
1506 }
1507 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1508 {
1509  return send_command_("stop", timeout, timestamp);
1510 }
1511 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1512 {
1513  return send_command_("shutdown", timeout);
1514 }
1516 {
1517  return send_command_("status");
1518 }
1519 std::string xmlrpc_commander::send_report(std::string const& what)
1520 {
1521  return send_command_("report", what);
1522 }
1524 {
1525  return send_command_("legal_commands");
1526 }
1527 std::string xmlrpc_commander::send_trace_get(std::string const& name)
1528 {
1529  return send_command_("trace_get", name);
1530 }
1531 std::string xmlrpc_commander::send_trace_set(std::string const& name, std::string const& type, std::string const& mask)
1532 {
1533  return send_command_("trace_set", name, type, mask);
1534 }
1535 std::string xmlrpc_commander::send_meta_command(std::string const& command, std::string const& arg)
1536 {
1537  return send_command_("meta_command", command, arg);
1538 }
1539 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1540 {
1541  return send_command_("rollover_subrun", when, sr);
1542 }
1543 } // namespace artdaq
1544 
1545 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