artdaq  v3_09_01
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 try
1101 {
1102  //std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1103  xmlrpc_c::registry registry;
1104  struct xmlrpc_method_info3 methodInfo;
1105  memset(&methodInfo, 0, sizeof(methodInfo));
1106 
1107  /*#define register_method(m) \
1108  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1109  registry.addMethod ("daq." #m, ptr_ ## m) */
1110 #define register_method(m) register_method2(m, 0x400000)
1111 
1112  xmlrpc_env env; // xmlrpc_env_init(&env);
1113  xmlrpc_registry*** c_registryPPP;
1114  c_registryPPP = reinterpret_cast<xmlrpc_registry***>(reinterpret_cast<char*>(&registry) + sizeof(girmem::autoObject)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
1115 
1116 #define register_method2(m, ss) \
1117  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1118  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1119  methodInfo.methodName = "daq." #m; \
1120  methodInfo.methodFunction = &c_executeMethod; \
1121  methodInfo.serverInfo = ptr_##m; \
1122  methodInfo.stackSize = ss; \
1123  methodInfo.signatureString = &m##signature[0]; \
1124  methodInfo.help = &m##help[0]; \
1125  xmlrpc_env_init(&env); \
1126  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1127  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1128  xmlrpc_env_clean(&env)
1129 
1130  register_method2(init, 0x200000);
1131  register_method(soft_init);
1132  register_method(reinit);
1133  register_method(start);
1134  register_method(status);
1135  register_method(report);
1136  register_method(stop);
1137  register_method(pause);
1138  register_method(resume);
1139  register_method(register_monitor);
1140  register_method(unregister_monitor);
1141  register_method(legal_commands);
1142  register_method(trace_set);
1143  register_method(trace_get);
1144  register_method(meta_command);
1145  register_method(rollover_subrun);
1146  register_method(add_config_archive_entry);
1147  register_method(clear_config_archive);
1148 
1149  register_method(shutdown);
1150 
1151  // alias "daq.reset" to the internal shutdown transition
1152  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1153  registry.addMethod("daq.reset", ptr_reset);
1154 
1155 #undef register_method
1156 
1157  // JCF, 6/3/15
1158 
1159  // In the following code, I configure a socket to have the
1160  // SO_REUSEADDR option so that once an artdaq process closes, the
1161  // port it was communicating on becomes immediately available
1162  // (desirable if, say, the DAQ program is terminated and then
1163  // immediately restarted)
1164 
1165  // Much of the following code is cribbed from
1166  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1167 
1168  // Below, "0" is the default protocol (in this case, given the IPv4
1169  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1170  // method)
1171 
1172  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1173 
1174  if (socket_file_descriptor < 0)
1175  {
1176  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1177  }
1178 
1179  int enable = 1;
1180  int retval = setsockopt(socket_file_descriptor,
1181  SOL_SOCKET, SO_REUSEADDR,
1182  &enable, sizeof(int));
1183 
1184  if (retval < 0)
1185  {
1186  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1187  }
1188 
1189  struct sockaddr_in sockAddr;
1190 
1191  sockAddr.sin_family = AF_INET;
1192  sockAddr.sin_port = htons(port_);
1193  sockAddr.sin_addr.s_addr = 0;
1194 
1195  retval = bind(socket_file_descriptor,
1196  reinterpret_cast<struct sockaddr*>(&sockAddr), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1197  sizeof(sockAddr));
1198 
1199  if (retval != 0)
1200  {
1201  close(socket_file_descriptor);
1202  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1203  }
1204 
1205  server = std::make_unique<xmlrpc_c::serverAbyss>(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor));
1206 
1207 #if 0
1208  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1209  registry.setShutdown(&shutdown_obj);
1210 #endif
1211 
1212  TLOG(TLVL_DEBUG) << "running server";
1213 
1214  // JCF, 6/3/15
1215 
1216  // Use a catch block to clean up (i.e., close the socket). An
1217  // opportunity for RAII, although all control paths are limited to
1218  // this section of the file...
1219 
1220  try
1221  {
1222  running_ = true;
1223  server->run();
1224  running_ = false;
1225  }
1226  catch (...)
1227  {
1228  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1229  running_ = false;
1230  close(socket_file_descriptor);
1231  throw;
1232  }
1233 
1234  close(socket_file_descriptor);
1235  TLOG(TLVL_DEBUG) << "server terminated";
1236 }
1237 catch (...)
1238 {
1239  throw;
1240 }
1241 
1242 std::string xmlrpc_commander::send_command_(const std::string& command)
1243 {
1244  if (serverUrl_.empty())
1245  {
1246  std::stringstream errmsg;
1247  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1248  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1249  }
1250  xmlrpc_c::clientSimple myClient;
1251  xmlrpc_c::value result;
1252 
1253  try
1254  {
1255  myClient.call(serverUrl_, "daq." + command, "", &result);
1256  }
1257  catch (...)
1258  {
1259  std::stringstream errmsg;
1260  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1261  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1262  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1263  }
1264 
1265  return xmlrpc_c::value_string(result);
1266 }
1267 
1268 std::string xmlrpc_commander::send_command_(const std::string& command, const std::string& arg)
1269 {
1270  if (serverUrl_.empty())
1271  {
1272  std::stringstream errmsg;
1273  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1274  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1275  }
1276  xmlrpc_c::clientSimple myClient;
1277  xmlrpc_c::value result;
1278 
1279  try
1280  {
1281  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1282  }
1283  catch (...)
1284  {
1285  std::stringstream errmsg;
1286  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1287  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1288  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1289  }
1290 
1291  return xmlrpc_c::value_string(result);
1292 }
1293 
1294 std::string xmlrpc_commander::send_command_(const std::string& command, const fhicl::ParameterSet& pset, uint64_t timestamp, uint64_t timeout)
1295 {
1296  if (serverUrl_.empty())
1297  {
1298  std::stringstream errmsg;
1299  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1300  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1301  }
1302  xmlrpc_c::clientSimple myClient;
1303  xmlrpc_c::value result;
1304 
1305  try
1306  {
1307  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1308  }
1309  catch (...)
1310  {
1311  std::stringstream errmsg;
1312  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1313  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1314  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1315  }
1316 
1317  return xmlrpc_c::value_string(result);
1318 }
1319 
1320 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint64_t b)
1321 {
1322  if (serverUrl_.empty())
1323  {
1324  std::stringstream errmsg;
1325  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1326  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1327  }
1328  xmlrpc_c::clientSimple myClient;
1329  xmlrpc_c::value result;
1330 
1331  try
1332  {
1333  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1334  }
1335  catch (...)
1336  {
1337  std::stringstream errmsg;
1338  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1339  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1340  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1341  }
1342 
1343  return xmlrpc_c::value_string(result);
1344 }
1345 
1346 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint32_t b)
1347 {
1348  if (serverUrl_.empty())
1349  {
1350  std::stringstream errmsg;
1351  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1352  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1353  }
1354  xmlrpc_c::clientSimple myClient;
1355  xmlrpc_c::value result;
1356 
1357  try
1358  {
1359  myClient.call(serverUrl_, "daq." + command, "Ii", &result, a, b);
1360  }
1361  catch (...)
1362  {
1363  std::stringstream errmsg;
1364  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1365  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1366  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1367  }
1368 
1369  return xmlrpc_c::value_string(result);
1370 }
1371 
1372 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, art::RunID r, uint64_t a, uint64_t b)
1373 {
1374  if (serverUrl_.empty())
1375  {
1376  std::stringstream errmsg;
1377  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1378  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1379  }
1380  xmlrpc_c::clientSimple myClient;
1381  xmlrpc_c::value result;
1382 
1383  try
1384  {
1385  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1386  }
1387  catch (...)
1388  {
1389  std::stringstream errmsg;
1390  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1391  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1392  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1393  }
1394 
1395  return xmlrpc_c::value_string(result);
1396 }
1397 
1398 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t arg1)
1399 {
1400  if (serverUrl_.empty())
1401  {
1402  std::stringstream errmsg;
1403  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1404  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1405  }
1406  xmlrpc_c::clientSimple myClient;
1407  xmlrpc_c::value result;
1408 
1409  try
1410  {
1411  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1412  }
1413  catch (...)
1414  {
1415  std::stringstream errmsg;
1416  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1417  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1418  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1419  }
1420 
1421  return xmlrpc_c::value_string(result);
1422 }
1423 
1424 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2)
1425 {
1426  if (serverUrl_.empty())
1427  {
1428  std::stringstream errmsg;
1429  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1430  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1431  }
1432  xmlrpc_c::clientSimple myClient;
1433  xmlrpc_c::value result;
1434 
1435  try
1436  {
1437  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1438  }
1439  catch (...)
1440  {
1441  std::stringstream errmsg;
1442  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1443  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1444  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1445  }
1446 
1447  return xmlrpc_c::value_string(result);
1448 }
1449 
1450 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2, const std::string& arg3)
1451 {
1452  if (serverUrl_.empty())
1453  {
1454  std::stringstream errmsg;
1455  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1456  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1457  }
1458  xmlrpc_c::clientSimple myClient;
1459  xmlrpc_c::value result;
1460 
1461  try
1462  {
1463  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1464  }
1465  catch (...)
1466  {
1467  std::stringstream errmsg;
1468  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1469  << "; possible causes are bad arguments or nonexistent process at requested port";
1470  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1471  }
1472 
1473  return xmlrpc_c::value_string(result);
1474 }
1475 
1476 std::string xmlrpc_commander::send_register_monitor(std::string const& monitor_fhicl)
1477 {
1478  return send_command_("register_monitor", monitor_fhicl);
1479 }
1480 std::string xmlrpc_commander::send_unregister_monitor(std::string const& monitor_label)
1481 {
1482  return send_command_("unregister_monitor", monitor_label);
1483 }
1484 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1485 {
1486  return send_command_("init", ps, timeout, timestamp);
1487 }
1488 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1489 {
1490  return send_command_("soft_init", ps, timeout, timestamp);
1491 }
1492 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1493 {
1494  return send_command_("reinit", ps, timeout, timestamp);
1495 }
1496 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1497 {
1498  return send_command_("start", run, timeout, timestamp);
1499 }
1500 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1501 {
1502  return send_command_("pause", timeout, timestamp);
1503 }
1504 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1505 {
1506  return send_command_("resume", timeout, timestamp);
1507 }
1508 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1509 {
1510  return send_command_("stop", timeout, timestamp);
1511 }
1512 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1513 {
1514  return send_command_("shutdown", timeout);
1515 }
1517 {
1518  return send_command_("status");
1519 }
1520 std::string xmlrpc_commander::send_report(std::string const& what)
1521 {
1522  return send_command_("report", what);
1523 }
1525 {
1526  return send_command_("legal_commands");
1527 }
1528 std::string xmlrpc_commander::send_trace_get(std::string const& name)
1529 {
1530  return send_command_("trace_get", name);
1531 }
1532 std::string xmlrpc_commander::send_trace_set(std::string const& name, std::string const& type, std::string const& mask)
1533 {
1534  return send_command_("trace_set", name, type, mask);
1535 }
1536 std::string xmlrpc_commander::send_meta_command(std::string const& command, std::string const& arg)
1537 {
1538  return send_command_("meta_command", command, arg);
1539 }
1540 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1541 {
1542  return send_command_("rollover_subrun", when, sr);
1543 }
1544 } // namespace artdaq
1545 
1546 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:534
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:540
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:468
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:431
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:521
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:527
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