artdaq  v3_12_02
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 
18 #include "TRACE/tracemf.h"
19 #include "artdaq/DAQdata/Globals.hh"
20 #define TRACE_NAME (app_name + "_xmlrpc_commander").c_str()
21 
22 #include "artdaq/ExternalComms/CommanderInterface.hh"
23 
24 #include "artdaq-core/Utilities/ExceptionHandler.hh"
25 
26 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <cerrno>
29 #include <cstdint>
30 #include <cstring>
31 #include <exception>
32 #include <iostream>
33 #include <limits>
34 #include <memory>
35 #include <mutex>
36 #include <stdexcept>
37 
38 namespace artdaq {
39 
44 {
45 public:
57  xmlrpc_commander(const fhicl::ParameterSet& ps, artdaq::Commandable& commandable);
58 
62  void run_server() override;
63 
69  std::string send_register_monitor(std::string const& monitor_fhicl) override;
70 
76  std::string send_unregister_monitor(std::string const& monitor_label) override;
77 
88  std::string send_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp) override;
89 
100  std::string send_soft_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp) override;
101 
112  std::string send_reinit(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp) override;
113 
124  std::string send_start(art::RunID runNumber, uint64_t timeout, uint64_t timestamp) override;
125 
135  std::string send_pause(uint64_t timeout, uint64_t timestamp) override;
136 
146  std::string send_resume(uint64_t timeout, uint64_t timestamp) override;
147 
157  std::string send_stop(uint64_t timeout, uint64_t timestamp) override;
158 
167  std::string send_shutdown(uint64_t timeout) override;
168 
175  std::string send_status() override;
176 
184  std::string send_report(std::string const& what) override;
185 
192  std::string send_legal_commands() override;
193 
202  std::string send_trace_get(std::string const& name) override;
203 
217  std::string send_trace_set(std::string const& name, std::string const& type, std::string const& mask) override;
218 
227  std::string send_meta_command(std::string const& command, std::string const& argument) override;
228 
238  std::string send_rollover_subrun(uint64_t when, uint32_t sr) override;
239 
240 private:
241  xmlrpc_commander(const xmlrpc_commander&) = delete;
242 
244  xmlrpc_commander& operator=(xmlrpc_commander const&) = delete;
245  xmlrpc_commander& operator=(xmlrpc_commander&&) = delete;
246 
247  int port_;
248  std::string serverUrl_;
249 
250  std::string send_command_(const std::string& command);
251  std::string send_command_(const std::string& command, const std::string& arg);
252  std::string send_command_(const std::string& command, const fhicl::ParameterSet& pset, uint64_t timestamp, uint64_t timeout);
253  std::string send_command_(const std::string& command, uint64_t a, uint64_t b);
254  std::string send_command_(const std::string& command, uint64_t a, uint32_t b);
255  std::string send_command_(const std::string& command, art::RunID r, uint64_t a, uint64_t b);
256  std::string send_command_(const std::string&, uint64_t);
257  std::string send_command_(const std::string&, const std::string&, const std::string&);
258  std::string send_command_(const std::string&, const std::string&, const std::string&, const std::string&);
259 
260 public:
261  std::timed_mutex mutex_;
262  std::unique_ptr<xmlrpc_c::serverAbyss> server;
263 };
264 
265 } // namespace artdaq
266 
267 namespace {
271 class env_wrap
272 {
273 public:
274  env_wrap() { xmlrpc_env_init(&this->env_c); };
275  ~env_wrap() { xmlrpc_env_clean(&this->env_c); };
276  xmlrpc_env env_c;
277 private:
278  env_wrap(env_wrap const&) = delete;
279  env_wrap(env_wrap&&) = delete;
280  env_wrap& operator=(env_wrap const&) = delete;
281  env_wrap& operator=(env_wrap&&) = delete;
282 };
283 } // namespace
284 static xmlrpc_c::paramList
285 pListFromXmlrpcArray(xmlrpc_value* const arrayP)
286 {
287  env_wrap env;
288  XMLRPC_ASSERT_ARRAY_OK(arrayP);
289  unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP);
290  assert(!env.env_c.fault_occurred);
291  xmlrpc_c::paramList paramList(arraySize);
292  for (unsigned int i = 0; i < arraySize; ++i)
293  {
294  xmlrpc_value* arrayItemP;
295  xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP);
296  assert(!env.env_c.fault_occurred);
297  paramList.add(xmlrpc_c::value(arrayItemP));
298  xmlrpc_DECREF(arrayItemP);
299  }
300  return paramList;
301 }
302 static xmlrpc_value*
303 c_executeMethod(xmlrpc_env* const envP,
304  xmlrpc_value* const paramArrayP,
305  void* const methodPtr,
306  void* const callInfoPtr)
307 {
308  auto* const methodP(static_cast<xmlrpc_c::method*>(methodPtr));
309  xmlrpc_c::paramList const paramList(pListFromXmlrpcArray(paramArrayP));
310  auto* const callInfoP(static_cast<xmlrpc_c::callInfo*>(callInfoPtr));
311  xmlrpc_value* retval;
312  retval = nullptr; // silence used-before-set warning
313  try
314  {
315  xmlrpc_c::value result;
316  try
317  {
318  auto* const method2P(dynamic_cast<xmlrpc_c::method2*>(methodP));
319  if (method2P != nullptr)
320  {
321  method2P->execute(paramList, callInfoP, &result);
322  }
323  else
324  {
325  methodP->execute(paramList, &result);
326  }
327  }
328  catch (xmlrpc_c::fault const& fault)
329  {
330  xmlrpc_env_set_fault(envP, fault.getCode(),
331  fault.getDescription().c_str());
332  }
333  if (envP->fault_occurred == 0)
334  {
335  if (result.isInstantiated())
336  {
337  retval = result.cValue();
338  }
339  else
340  {
341  girerr::throwf(
342  "Xmlrpc-c user's xmlrpc_c::method object's "
343  "'execute method' failed to set the RPC result "
344  "value.");
345  }
346  }
347  }
348  catch (std::exception const& e)
349  {
350  xmlrpc_faultf(envP,
351  "Unexpected error executing code for "
352  "particular method, detected by Xmlrpc-c "
353  "method registry code. Method did not "
354  "fail; rather, it did not complete at all. %s",
355  e.what());
356  }
357  catch (...)
358  {
359  xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
360  "Unexpected error executing code for "
361  "particular method, detected by Xmlrpc-c "
362  "method registry code. Method did not "
363  "fail; rather, it did not complete at all.");
364  }
365  return retval;
366 }
367 
368 namespace artdaq {
375 std::string exception_msg(const std::runtime_error& er,
376  const std::string& helpText = "execute request")
377 {
378  std::string msg("Exception when trying to ");
379  msg.append(helpText);
380  msg.append(": ");
381  msg.append(er.what()); // std::string(er.what ()).substr (2);
382  if (msg[msg.size() - 1] == '\n')
383  {
384  msg.erase(msg.size() - 1);
385  }
386  return msg;
387 }
388 
395 std::string exception_msg(const art::Exception& er,
396  const std::string& helpText)
397 {
398  std::string msg("Exception when trying to ");
399  msg.append(helpText);
400  msg.append(": ");
401  msg.append(er.what());
402  if (msg[msg.size() - 1] == '\n')
403  {
404  msg.erase(msg.size() - 1);
405  }
406  return msg;
407 }
408 
415 std::string exception_msg(const cet::exception& er,
416  const std::string& helpText)
417 {
418  std::string msg("Exception when trying to ");
419  msg.append(helpText);
420  msg.append(": ");
421  msg.append(er.what());
422  if (msg[msg.size() - 1] == '\n')
423  {
424  msg.erase(msg.size() - 1);
425  }
426  return msg;
427 }
428 
435 std::string exception_msg(const boost::exception& er,
436  const std::string& helpText)
437 {
438  std::string msg("Exception when trying to ");
439  msg.append(helpText);
440  msg.append(": ");
441  msg.append(boost::diagnostic_information(er));
442  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
443  return msg;
444 }
451 std::string exception_msg(const std::exception& er,
452  const std::string& helpText)
453 {
454  std::string msg("Exception when trying to ");
455  msg.append(helpText);
456  msg.append(": ");
457  msg.append(er.what());
458  if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
459  return msg;
460 }
461 
468 std::string exception_msg(const std::string& erText,
469  const std::string& helpText)
470 {
471  std::string msg("Exception when trying to ");
472  msg.append(helpText);
473  msg.append(": ");
474  msg.append(erText);
475  if (msg[msg.size() - 1] == '\n')
476  {
477  msg.erase(msg.size() - 1);
478  }
479  return msg;
480 }
481 
499 class cmd_ : public xmlrpc_c::method
500 {
501 public:
502  // Can't seem to initialize "_signature" and "_help" in the initialization list...
509  cmd_(xmlrpc_commander& c, const std::string& signature, const std::string& description)
510  : _c(c)
511  {
512  _signature = signature;
513  _help = description;
514  }
515 
521  void execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* retvalP) final;
522 
523 protected:
525 
531  virtual bool execute_(const xmlrpc_c::paramList&, xmlrpc_c::value* retvalP) = 0;
532 
542  template<typename T>
543  T getParam(const xmlrpc_c::paramList& paramList, int index);
544 
568  template<typename T>
569  T getParam(const xmlrpc_c::paramList& paramList, int index, T default_value);
570 };
571 
572 // Users are only allowed to call getParam for predefined types; see
573 // template specializations below this default function
574 
575 template<typename T>
576 T cmd_::getParam(const xmlrpc_c::paramList& /*unused*/, int /*unused*/)
577 {
578  throw cet::exception("cmd_") << "Error in cmd_::getParam(): value type not supported" << std::endl; // NOLINT(cert-err60-cpp)
579 }
580 
589 template<>
590 uint64_t cmd_::getParam<uint64_t>(const xmlrpc_c::paramList& paramList, int index)
591 {
592  TLOG(TLVL_DEBUG + 33) << "Getting parameter " << index << " from list as uint64_t.";
593  try
594  {
595  TLOG(TLVL_DEBUG + 33) << "Param value: " << paramList.getI8(index);
596  return static_cast<uint64_t>(paramList.getI8(index));
597  }
598  catch (...)
599  {
600  TLOG(TLVL_DEBUG + 33) << "Param value (int): " << paramList.getInt(index);
601  return static_cast<uint64_t>(paramList.getInt(index));
602  }
603 }
604 
613 template<>
614 uint32_t cmd_::getParam<uint32_t>(const xmlrpc_c::paramList& paramList, int index)
615 {
616  TLOG(TLVL_DEBUG + 33) << "Getting parameter " << index << " from list as uint32_t.";
617  TLOG(TLVL_DEBUG + 33) << "Param value: " << paramList.getInt(index);
618  return static_cast<uint32_t>(paramList.getInt(index));
619 }
620 
629 template<>
630 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
631 {
632  TLOG(TLVL_DEBUG + 33) << "Getting parameter " << index << " from list as string.";
633  TLOG(TLVL_DEBUG + 33) << "Param value: " << paramList.getString(index);
634  return static_cast<std::string>(paramList.getString(index));
635 }
636 
645 template<>
646 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
647 {
648  TLOG(TLVL_DEBUG + 33) << "Getting parameter " << index << " from list as Run Number.";
649  art::RunNumber_t run_number;
650  try
651  {
652  TLOG(TLVL_DEBUG + 33) << "Param value: " << paramList.getInt(index);
653  run_number = art::RunNumber_t(paramList.getInt(index));
654  }
655  catch (...)
656  {
657  TLOG(TLVL_DEBUG + 33) << "Parameter is not an int. Trying string...";
658 
659  auto runNumber = paramList.getString(index);
660  TLOG(TLVL_DEBUG + 33) << "Got run number string " << runNumber;
661  run_number = art::RunNumber_t(std::stoi(runNumber));
662  }
663 
664  art::RunID run_id(run_number);
665  return run_id;
666 }
667 
676 template<>
677 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
678 {
679  TLOG(TLVL_DEBUG + 33) << "Getting parameter " << index << " from list as ParameterSet.";
680  TLOG(TLVL_DEBUG + 33) << "Param value: " << paramList.getString(index);
681  std::string configString = std::string(paramList.getString(index));
682  TLOG(TLVL_DEBUG + 32) << "Loading Parameter Set from string: " << configString << std::endl;
683  fhicl::ParameterSet pset;
684 
685  try
686  {
687  pset = fhicl::ParameterSet::make(configString);
688  }
689  catch (const fhicl::exception& e)
690  {
691  if (getenv("FHICL_FILE_PATH") == nullptr)
692  {
693  TLOG(TLVL_ERROR) << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"";
694  std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"" << std::endl;
695  setenv("FHICL_FILE_PATH", ".", 0);
696  }
697  cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
698  pset = fhicl::ParameterSet::make(configString, lookup_policy);
699  }
700 
701  TLOG(TLVL_INFO) << "Parameter Set Loaded." << std::endl;
702  return pset;
703 }
704 
705 template<typename T>
706 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
707  T default_value)
708 {
709  T val = default_value;
710 
711  if (static_cast<unsigned>(index) < paramList.size())
712  {
713  val = getParam<T>(paramList, index);
714  }
715  return val;
716 }
717 
718 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
719 {
720  TLOG(TLVL_DEBUG + 33) << "Received Request to " << _help << ", attempting to get lock";
721  std::unique_lock<std::timed_mutex> lk(_c.mutex_, std::defer_lock);
722  lk.try_lock_for(std::chrono::milliseconds(250));
723 
724  if (lk.owns_lock())
725  {
726  try
727  {
728  // JCF, 9/4/14
729 
730  // Assuming the execute_ function returns true, then if the
731  // retvalP argument was untouched, assign it the string
732  // "Success"
733 
734  // See
735  // http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#isinstantiated
736  // for more on the concept of instantiation in xmlrpc_c::value objects
737 
738  if (execute_(paramList, retvalP))
739  {
740  if (!retvalP->isInstantiated())
741  {
742  *retvalP = xmlrpc_c::value_string("Success");
743  }
744  }
745  else
746  {
747  std::string problemReport = _c._commandable.report("transition_status");
748  *retvalP = xmlrpc_c::value_string(problemReport);
749  }
750  }
751  catch (std::runtime_error& er)
752  {
753  std::string msg = exception_msg(er, _help);
754  *retvalP = xmlrpc_c::value_string(msg);
755  TLOG(TLVL_ERROR) << msg;
756  }
757  catch (art::Exception& er)
758  {
759  std::string msg = exception_msg(er, _help);
760  *retvalP = xmlrpc_c::value_string(msg);
761  TLOG(TLVL_ERROR) << msg;
762  }
763  catch (cet::exception& er)
764  {
765  std::string msg = exception_msg(er, _help);
766  *retvalP = xmlrpc_c::value_string(msg);
767  TLOG(TLVL_ERROR) << msg;
768  }
769  catch (boost::exception& er)
770  {
771  std::string msg = exception_msg(er, _help);
772  *retvalP = xmlrpc_c::value_string(msg);
773  TLOG(TLVL_ERROR) << msg;
774  }
775  catch (std::exception& er)
776  {
777  std::string msg = exception_msg(er, _help);
778  *retvalP = xmlrpc_c::value_string(msg);
779  TLOG(TLVL_ERROR) << msg;
780  }
781  catch (...)
782  {
783  std::string msg = exception_msg("Unknown exception (not from std, boost, cet, or art)", _help);
784  *retvalP = xmlrpc_c::value_string(msg);
785  TLOG(TLVL_ERROR) << msg;
786  }
787 
788  lk.unlock();
789  }
790  else
791  {
792  TLOG(TLVL_ERROR) << "Unable to get lock while trying to " << _help << ", returning busy";
793  *retvalP = xmlrpc_c::value_string("busy");
794  }
795 }
796 
798 
799 // JCF, 9/5/14
800 
801 // The three "init" transitions all take a FHiCL parameter list, and
802 // optionally a timeout and a timestamp; thus we can kill three birds
803 // with one stone in the GENERATE_INIT_TRANSITION macro
804 
805 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
806  \
807  class NAME##_ : public cmd_ \
808  { \
809  public: \
810  \
813  explicit NAME##_(xmlrpc_commander& c) : cmd_(c, "s:sII", DESCRIPTION) {} \
814  \
815  \
816  static const uint64_t defaultTimeout = 45; \
817  \
818  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
819  \
820  private: \
821  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) \
822  { \
823  fhicl::ParameterSet ps; \
824  try \
825  { \
826  ps = getParam<fhicl::ParameterSet>(paramList, 0); \
827  } \
828  catch (...) \
829  { \
830  *retvalP = xmlrpc_c::value_string("Error: The " #NAME " message requires a single argument that is a string containing the initialization ParameterSet"); \
831  return true; \
832  } \
833  \
834  return _c._commandable.CALL(ps, \
835  getParam<uint64_t>(paramList, 1, defaultTimeout), \
836  getParam<uint64_t>(paramList, 2, defaultTimestamp)); \
837  } \
838  };
839 
840 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
841 
842 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
843 
844 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
845 
846 #undef GENERATE_INIT_TRANSITION
847 
849 
853 class start_ : public cmd_
854 {
855 public:
861  : cmd_(c, "s:iII", "start the run")
862  {}
863 
865  static const uint64_t defaultTimeout = 45;
867  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
868 
869 private:
870  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
871  {
872  try
873  {
874  getParam<art::RunID>(paramList, 0);
875  }
876  catch (...)
877  {
878  *retvalP = xmlrpc_c::value_string("Error: The start message requires the run number as an argument.");
879  return true;
880  }
881 
882  return _c._commandable.start(getParam<art::RunID>(paramList, 0),
883  getParam<uint64_t>(paramList, 1, defaultTimeout),
884  getParam<uint64_t>(paramList, 2, defaultTimestamp));
885  }
886 };
887 
889 
890 // JCF, 9/5/14
891 
892 // "pause", "resume" and "stop" all take an optional timeout and
893 // timestamp parameter, so we can generate them all with the
894 // GENERATE_TIMEOUT_TIMESTAMP_TRANSITION macro
895 
896 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
897  \
898  class NAME##_ : public cmd_ \
899  { \
900  public: \
901  \
903  NAME##_(xmlrpc_commander& c) : cmd_(c, "s:II", DESCRIPTION) {} \
904  \
905  \
906  static const uint64_t defaultTimeout = TIMEOUT; \
907  \
908  static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
909  \
910  private: \
911  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const) \
912  { \
913  return _c._commandable.CALL(getParam<uint64_t>(paramList, 0, defaultTimeout), \
914  getParam<uint64_t>(paramList, 1, defaultTimestamp)); \
915  } \
916  };
917 
918 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
919 
920 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
921 
922 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
923 
924 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
925 
929 class shutdown_ : public cmd_
930 {
931 public:
937  : cmd_(c, "s:i", "shutdown the program")
938  {}
939 
941  static const uint64_t defaultTimeout = 45;
942 
943 private:
944  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
945  {
946  auto ret = _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
947 
948 #if 1
949  if (_c.server)
950  {
951  _c.server->terminate();
952  }
953 #endif
954 
955  return ret;
956  }
957 };
958 
962 class status_ : public cmd_
963 {
964 public:
970  : cmd_(c, "s:n", "report the current state")
971  {}
972 
973 private:
974  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
975  {
976  *retvalP = xmlrpc_c::value_string(_c._commandable.status());
977  return true;
978  }
979 };
980 
984 class report_ : public cmd_
985 {
986 public:
992  : cmd_(c, "s:s", "report statistics")
993  {}
994 
995 private:
996  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
997  {
998  try
999  {
1000  getParam<std::string>(paramList, 0);
1001  }
1002  catch (...)
1003  {
1004  *retvalP = xmlrpc_c::value_string("Error: The report message requires a single argument that selects the type of statistics to be reported.");
1005  return true;
1006  }
1007 
1008  *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
1009  return true;
1010  }
1011 };
1012 
1016 class legal_commands_ : public cmd_
1017 {
1018 public:
1024  : cmd_(c, "s:n", "return the currently legal commands")
1025  {}
1026 
1027 private:
1028  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const retvalP) override
1029  {
1030  std::vector<std::string> cmdList = _c._commandable.legal_commands();
1031  std::string resultString;
1032 
1033  for (auto& cmd : cmdList)
1034  {
1035  resultString.append(cmd + " ");
1036  if (cmd == "shutdown")
1037  {
1038  resultString.append(" reset");
1039  }
1040  }
1041  *retvalP = xmlrpc_c::value_string(resultString);
1042 
1043  return true;
1044  }
1045 };
1046 
1050 class register_monitor_ : public cmd_
1051 {
1052 public:
1058  : cmd_(c, "s:s", "Get notified of a new monitor")
1059  {}
1060 
1061 private:
1062  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1063  {
1064  try
1065  {
1066  getParam<fhicl::ParameterSet>(paramList, 0);
1067  }
1068  catch (...)
1069  {
1070  *retvalP = xmlrpc_c::value_string("Error: The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
1071  return true;
1072  }
1073 
1074  *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
1075  return true;
1076  }
1077 };
1078 
1083 {
1084 public:
1090  : cmd_(c, "s:s", "Remove a monitor")
1091  {}
1092 
1093 private:
1094  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1095  {
1096  try
1097  {
1098  getParam<std::string>(paramList, 0);
1099  }
1100  catch (...)
1101  {
1102  *retvalP = xmlrpc_c::value_string("Error: The unregister_monitor command expects a string representing the label of the monitor to be removed");
1103  return true;
1104  }
1105 
1106  *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
1107  return true;
1108  }
1109 };
1110 
1114 class trace_set_ : public cmd_
1115 {
1116 public:
1122  : cmd_(c, "s:ssI", "Set TRACE mask")
1123  {}
1124 
1125 private:
1126  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1127  {
1128  try
1129  {
1130  getParam<std::string>(paramList, 0);
1131  getParam<std::string>(paramList, 1);
1132  getParam<std::string>(paramList, 2);
1133  }
1134  catch (...)
1135  {
1136  *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");
1137  return true;
1138  }
1139 
1140  return _c._commandable.do_trace_set(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1), getParam<std::string>(paramList, 2));
1141  }
1142 };
1143 
1147 class trace_get_ : public cmd_
1148 {
1149 public:
1155  : cmd_(c, "s:s", "Get TRACE mask")
1156  {}
1157 
1158 private:
1159  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1160  {
1161  try
1162  {
1163  getParam<std::string>(paramList, 0);
1164  }
1165  catch (...)
1166  {
1167  *retvalP = xmlrpc_c::value_string("Error: The trace_get command expects a name (ALL for all)");
1168  return true;
1169  }
1170 
1171  *retvalP = xmlrpc_c::value_string(_c._commandable.do_trace_get(getParam<std::string>(paramList, 0)));
1172  return true;
1173  }
1174 };
1175 
1179 class meta_command_ : public cmd_
1180 {
1181 public:
1187  : cmd_(c, "s:ss", "Run custom command")
1188  {}
1189 
1190 private:
1191  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1192  {
1193  try
1194  {
1195  getParam<std::string>(paramList, 0);
1196  getParam<std::string>(paramList, 1);
1197  }
1198  catch (...)
1199  {
1200  *retvalP = xmlrpc_c::value_string("Error: The meta_command command expects a string command and a string argument");
1201  return true;
1202  }
1203 
1204  return _c._commandable.do_meta_command(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
1205  }
1206 };
1207 
1211 class rollover_subrun_ : public cmd_
1212 {
1213 public:
1219  : cmd_(c, "s:Ii", "create a new subrun")
1220  {}
1221 
1222  static const uint64_t defaultSequenceID = 0xFFFFFFFFFFFFFFFF;
1223  static const uint32_t defaultSubrunNumber = 1;
1224 
1225 private:
1226  bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const /*retvalP*/) override
1227  {
1228  auto ret = _c._commandable.do_rollover_subrun(getParam<uint64_t>(paramList, 0, defaultSequenceID), getParam<uint32_t>(paramList, 1, defaultSubrunNumber));
1229  return ret;
1230  }
1231 };
1232 
1237 {
1238 public:
1244  : cmd_(c, "s:ss", "Add an entry to the configuration archive list")
1245  {}
1246 
1247 private:
1248  bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
1249  {
1250  try
1251  {
1252  getParam<std::string>(paramList, 0);
1253  getParam<std::string>(paramList, 1);
1254  }
1255  catch (...)
1256  {
1257  *retvalP = xmlrpc_c::value_string("Error: The add_config_archive_entry command expects a string key and a string value");
1258  return true;
1259  }
1260 
1261  return _c._commandable.do_add_config_archive_entry(getParam<std::string>(paramList, 0), getParam<std::string>(paramList, 1));
1262  }
1263 };
1264 
1269 {
1270 public:
1276  : cmd_(c, "s:n", "Clear the configuration archive list")
1277  {}
1278 
1279 private:
1280  bool execute_(xmlrpc_c::paramList const& /*unused*/, xmlrpc_c::value* const /*retvalP*/) override
1281  {
1283  }
1284 };
1285 
1286 // JCF, 9/4/14
1287 
1288 // Not sure if anyone was planning to resurrect this code by changing
1289 // the preprocessor decision; as such, I'll leave it in for now...
1290 
1291 #if 0
1292  class shutdown_ : public xmlrpc_c::registry::shutdown
1293  {
1294  public:
1295  shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
1296 
1297  virtual void doit(const std::string& paramString, void*) const
1298  {
1299  TLOG(TLVL_INFO) << "A shutdown command was sent "
1300  << "with parameter "
1301  << paramString << "\"";
1302  _server->terminate();
1303  }
1304  private:
1305  xmlrpc_c::serverAbyss *_server;
1306  };
1307 #endif
1308 
1309 xmlrpc_commander::xmlrpc_commander(const fhicl::ParameterSet& ps, artdaq::Commandable& commandable)
1310  : CommanderInterface(ps, commandable)
1311  , port_(ps.get<int>("id", 0))
1312  , serverUrl_(ps.get<std::string>("server_url", ""))
1313  , server(nullptr)
1314 {
1315  if (serverUrl_.empty())
1316  {
1317  char hostname[HOST_NAME_MAX];
1318  gethostname(hostname, HOST_NAME_MAX);
1319  serverUrl_ = std::string(hostname);
1320  }
1321  if (serverUrl_.find("http") == std::string::npos)
1322  {
1323  serverUrl_ = "http://" + serverUrl_;
1324  }
1325  if (serverUrl_.find(std::to_string(port_)) == std::string::npos && serverUrl_.find(':', 7) == std::string::npos)
1326  {
1327  serverUrl_ = serverUrl_ + ":" + std::to_string(port_);
1328  }
1329  if (serverUrl_.find("RPC2") == std::string::npos)
1330  {
1331  serverUrl_ = serverUrl_ + "/RPC2";
1332  }
1333  TLOG(TLVL_INFO) << "XMLRPC COMMANDER CONSTRUCTOR: Port: " << port_ << ", Server Url: " << serverUrl_;
1334 }
1335 
1337 try
1338 {
1339  // std::cout << "XMLRPC_COMMANDER RUN_SERVER CALLED!" << std::endl;
1340  xmlrpc_c::registry registry;
1341  struct xmlrpc_method_info3 methodInfo;
1342  memset(&methodInfo, 0, sizeof(methodInfo));
1343 
1344  /*#define register_method(m) \
1345  // xmlrpc_c::methodPtr const ptr_ ## m(new m ## _(*this));\
1346  registry.addMethod ("daq." #m, ptr_ ## m) */
1347 #define register_method(m) register_method2(m, 0x400000)
1348 
1349  xmlrpc_env env; // xmlrpc_env_init(&env);
1350  xmlrpc_registry*** c_registryPPP;
1351  c_registryPPP = reinterpret_cast<xmlrpc_registry***>(reinterpret_cast<char*>(&registry) + sizeof(girmem::autoObject)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
1352 
1353 #define register_method2(m, ss) \
1354  xmlrpc_c::method* ptr_##m(dynamic_cast<xmlrpc_c::method*>(new m##_(*this))); \
1355  std::string m##signature = ptr_##m->signature(), m##help = ptr_##m->help(); \
1356  methodInfo.methodName = "daq." #m; \
1357  methodInfo.methodFunction = &c_executeMethod; \
1358  methodInfo.serverInfo = ptr_##m; \
1359  methodInfo.stackSize = ss; \
1360  methodInfo.signatureString = &m##signature[0]; \
1361  methodInfo.help = &m##help[0]; \
1362  xmlrpc_env_init(&env); \
1363  xmlrpc_registry_add_method3(&env, **c_registryPPP, &methodInfo); \
1364  if (env.fault_occurred) throw(girerr::error(env.fault_string)); \
1365  xmlrpc_env_clean(&env)
1366 
1367 #define unregister_method(m) delete ptr_##m;
1368 
1369  register_method2(init, 0x200000);
1370  register_method(soft_init);
1371  register_method(reinit);
1372  register_method(start);
1373  register_method(status);
1374  register_method(report);
1375  register_method(stop);
1376  register_method(pause);
1377  register_method(resume);
1378  register_method(register_monitor);
1379  register_method(unregister_monitor);
1380  register_method(legal_commands);
1381  register_method(trace_set);
1382  register_method(trace_get);
1383  register_method(meta_command);
1384  register_method(rollover_subrun);
1385  register_method(add_config_archive_entry);
1386  register_method(clear_config_archive);
1387 
1388  register_method(shutdown);
1389 
1390  // alias "daq.reset" to the internal shutdown transition
1391  xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
1392  registry.addMethod("daq.reset", ptr_reset);
1393 
1394 #undef register_method
1395 
1396  // JCF, 6/3/15
1397 
1398  // In the following code, I configure a socket to have the
1399  // SO_REUSEADDR option so that once an artdaq process closes, the
1400  // port it was communicating on becomes immediately available
1401  // (desirable if, say, the DAQ program is terminated and then
1402  // immediately restarted)
1403 
1404  // Much of the following code is cribbed from
1405  // http://fossies.org/linux/freeswitch/libs/xmlrpc-c/src/cpp/test/server_abyss.cpp
1406 
1407  // Below, "0" is the default protocol (in this case, given the IPv4
1408  // Protocol Family (PF_INET) and the SOCK_STREAM communication
1409  // method)
1410 
1411  XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
1412 
1413  if (socket_file_descriptor < 0)
1414  {
1415  throw cet::exception("xmlrpc_commander::run") << "Problem with the socket() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1416  }
1417 
1418  int enable = 1;
1419  int retval = setsockopt(socket_file_descriptor,
1420  SOL_SOCKET, SO_REUSEADDR,
1421  &enable, sizeof(int));
1422 
1423  if (retval < 0)
1424  {
1425  throw cet::exception("xmlrpc_commander::run") << "Problem with the call to setsockopt(); C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1426  }
1427 
1428  struct sockaddr_in sockAddr;
1429 
1430  sockAddr.sin_family = AF_INET;
1431  sockAddr.sin_port = htons(port_);
1432  sockAddr.sin_addr.s_addr = 0;
1433 
1434  retval = bind(socket_file_descriptor,
1435  reinterpret_cast<struct sockaddr*>(&sockAddr), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
1436  sizeof(sockAddr));
1437 
1438  if (retval != 0)
1439  {
1440  close(socket_file_descriptor);
1441  throw cet::exception("xmlrpc_commander::run") << "Problem with the bind() call; C-style errno == " << errno << " (" << strerror(errno) << ")"; // NOLINT(cert-err60-cpp)
1442  }
1443 
1444  server = std::make_unique<xmlrpc_c::serverAbyss>(xmlrpc_c::serverAbyss::constrOpt().registryP(&registry).socketFd(socket_file_descriptor));
1445 
1446 #if 0
1447  xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
1448  registry.setShutdown(&shutdown_obj);
1449 #endif
1450 
1451  TLOG(TLVL_DEBUG + 32) << "running server";
1452 
1453  // JCF, 6/3/15
1454 
1455  // Use a catch block to clean up (i.e., close the socket). An
1456  // opportunity for RAII, although all control paths are limited to
1457  // this section of the file...
1458 
1459  try
1460  {
1461  running_ = true;
1462  server->run();
1463  running_ = false;
1464  }
1465  catch (...)
1466  {
1467  TLOG(TLVL_WARNING) << "server threw an exception; closing the socket and rethrowing";
1468  running_ = false;
1469  close(socket_file_descriptor);
1470  throw;
1471  }
1472 
1473  close(socket_file_descriptor);
1474 
1475  unregister_method(init);
1476  unregister_method(soft_init);
1477  unregister_method(reinit);
1478  unregister_method(start);
1479  unregister_method(status);
1480  unregister_method(report);
1481  unregister_method(stop);
1482  unregister_method(pause);
1483  unregister_method(resume);
1484  unregister_method(register_monitor);
1485  unregister_method(unregister_monitor);
1486  unregister_method(legal_commands);
1487  unregister_method(trace_set);
1488  unregister_method(trace_get);
1489  unregister_method(meta_command);
1490  unregister_method(rollover_subrun);
1491  unregister_method(add_config_archive_entry);
1492  unregister_method(clear_config_archive);
1493 
1494  unregister_method(shutdown);
1495 
1496  TLOG(TLVL_DEBUG + 32) << "server terminated";
1497 }
1498 catch (...)
1499 {
1500  throw;
1501 }
1502 
1503 std::string xmlrpc_commander::send_command_(const std::string& command)
1504 {
1505  if (serverUrl_.empty())
1506  {
1507  std::stringstream errmsg;
1508  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1509  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1510  }
1511  xmlrpc_c::clientSimple myClient;
1512  xmlrpc_c::value result;
1513 
1514  try
1515  {
1516  myClient.call(serverUrl_, "daq." + command, "", &result);
1517  }
1518  catch (...)
1519  {
1520  std::stringstream errmsg;
1521  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1522  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1523  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1524  }
1525 
1526  return xmlrpc_c::value_string(result);
1527 }
1528 
1529 std::string xmlrpc_commander::send_command_(const std::string& command, const std::string& arg)
1530 {
1531  if (serverUrl_.empty())
1532  {
1533  std::stringstream errmsg;
1534  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1535  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1536  }
1537  xmlrpc_c::clientSimple myClient;
1538  xmlrpc_c::value result;
1539 
1540  try
1541  {
1542  myClient.call(serverUrl_, "daq." + command, "s", &result, arg.c_str());
1543  }
1544  catch (...)
1545  {
1546  std::stringstream errmsg;
1547  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1548  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1549  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1550  }
1551 
1552  return xmlrpc_c::value_string(result);
1553 }
1554 
1555 std::string xmlrpc_commander::send_command_(const std::string& command, const fhicl::ParameterSet& pset, uint64_t timestamp, uint64_t timeout)
1556 {
1557  if (serverUrl_.empty())
1558  {
1559  std::stringstream errmsg;
1560  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1561  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1562  }
1563  xmlrpc_c::clientSimple myClient;
1564  xmlrpc_c::value result;
1565 
1566  try
1567  {
1568  myClient.call(serverUrl_, "daq." + command, "sII", &result, pset.to_string().c_str(), timestamp, timeout);
1569  }
1570  catch (...)
1571  {
1572  std::stringstream errmsg;
1573  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1574  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1575  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1576  }
1577 
1578  return xmlrpc_c::value_string(result);
1579 }
1580 
1581 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint64_t b)
1582 {
1583  if (serverUrl_.empty())
1584  {
1585  std::stringstream errmsg;
1586  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1587  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1588  }
1589  xmlrpc_c::clientSimple myClient;
1590  xmlrpc_c::value result;
1591 
1592  try
1593  {
1594  myClient.call(serverUrl_, "daq." + command, "II", &result, a, b);
1595  }
1596  catch (...)
1597  {
1598  std::stringstream errmsg;
1599  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1600  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1601  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1602  }
1603 
1604  return xmlrpc_c::value_string(result);
1605 }
1606 
1607 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t a, uint32_t b)
1608 {
1609  if (serverUrl_.empty())
1610  {
1611  std::stringstream errmsg;
1612  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1613  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1614  }
1615  xmlrpc_c::clientSimple myClient;
1616  xmlrpc_c::value result;
1617 
1618  try
1619  {
1620  myClient.call(serverUrl_, "daq." + command, "Ii", &result, a, b);
1621  }
1622  catch (...)
1623  {
1624  std::stringstream errmsg;
1625  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1626  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1627  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1628  }
1629 
1630  return xmlrpc_c::value_string(result);
1631 }
1632 
1633 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, art::RunID r, uint64_t a, uint64_t b)
1634 {
1635  if (serverUrl_.empty())
1636  {
1637  std::stringstream errmsg;
1638  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1639  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1640  }
1641  xmlrpc_c::clientSimple myClient;
1642  xmlrpc_c::value result;
1643 
1644  try
1645  {
1646  myClient.call(serverUrl_, "daq." + command, "iII", &result, r.run(), a, b);
1647  }
1648  catch (...)
1649  {
1650  std::stringstream errmsg;
1651  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1652  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1653  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1654  }
1655 
1656  return xmlrpc_c::value_string(result);
1657 }
1658 
1659 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, uint64_t arg1)
1660 {
1661  if (serverUrl_.empty())
1662  {
1663  std::stringstream errmsg;
1664  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1665  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1666  }
1667  xmlrpc_c::clientSimple myClient;
1668  xmlrpc_c::value result;
1669 
1670  try
1671  {
1672  myClient.call(serverUrl_, "daq." + command, "I", &result, arg1);
1673  }
1674  catch (...)
1675  {
1676  std::stringstream errmsg;
1677  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1678  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1679  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1680  }
1681 
1682  return xmlrpc_c::value_string(result);
1683 }
1684 
1685 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2)
1686 {
1687  if (serverUrl_.empty())
1688  {
1689  std::stringstream errmsg;
1690  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1691  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1692  }
1693  xmlrpc_c::clientSimple myClient;
1694  xmlrpc_c::value result;
1695 
1696  try
1697  {
1698  myClient.call(serverUrl_, "daq." + command, "ss", &result, arg1.c_str(), arg2.c_str());
1699  }
1700  catch (...)
1701  {
1702  std::stringstream errmsg;
1703  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1704  << "; possible causes are malformed FHiCL or nonexistent process at requested port";
1705  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1706  }
1707 
1708  return xmlrpc_c::value_string(result);
1709 }
1710 
1711 std::string artdaq::xmlrpc_commander::send_command_(const std::string& command, const std::string& arg1, const std::string& arg2, const std::string& arg3)
1712 {
1713  if (serverUrl_.empty())
1714  {
1715  std::stringstream errmsg;
1716  errmsg << "Problem attempting " << command << " XML-RPC call: No server URL set!";
1717  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1718  }
1719  xmlrpc_c::clientSimple myClient;
1720  xmlrpc_c::value result;
1721 
1722  try
1723  {
1724  myClient.call(serverUrl_, "daq." + command, "sss", &result, arg1.c_str(), arg2.c_str(), arg3.c_str());
1725  }
1726  catch (...)
1727  {
1728  std::stringstream errmsg;
1729  errmsg << "Problem attempting " << command << " XML-RPC call on host " << serverUrl_
1730  << "; possible causes are bad arguments or nonexistent process at requested port";
1731  ExceptionHandler(ExceptionHandlerRethrow::yes, errmsg.str());
1732  }
1733 
1734  return xmlrpc_c::value_string(result);
1735 }
1736 
1737 std::string xmlrpc_commander::send_register_monitor(std::string const& monitor_fhicl)
1738 {
1739  return send_command_("register_monitor", monitor_fhicl);
1740 }
1741 std::string xmlrpc_commander::send_unregister_monitor(std::string const& monitor_label)
1742 {
1743  return send_command_("unregister_monitor", monitor_label);
1744 }
1745 std::string artdaq::xmlrpc_commander::send_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1746 {
1747  return send_command_("init", ps, timeout, timestamp);
1748 }
1749 std::string artdaq::xmlrpc_commander::send_soft_init(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1750 {
1751  return send_command_("soft_init", ps, timeout, timestamp);
1752 }
1753 std::string xmlrpc_commander::send_reinit(fhicl::ParameterSet const& ps, uint64_t timeout, uint64_t timestamp)
1754 {
1755  return send_command_("reinit", ps, timeout, timestamp);
1756 }
1757 std::string xmlrpc_commander::send_start(art::RunID run, uint64_t timeout, uint64_t timestamp)
1758 {
1759  return send_command_("start", run, timeout, timestamp);
1760 }
1761 std::string xmlrpc_commander::send_pause(uint64_t timeout, uint64_t timestamp)
1762 {
1763  return send_command_("pause", timeout, timestamp);
1764 }
1765 std::string xmlrpc_commander::send_resume(uint64_t timeout, uint64_t timestamp)
1766 {
1767  return send_command_("resume", timeout, timestamp);
1768 }
1769 std::string xmlrpc_commander::send_stop(uint64_t timeout, uint64_t timestamp)
1770 {
1771  return send_command_("stop", timeout, timestamp);
1772 }
1773 std::string xmlrpc_commander::send_shutdown(uint64_t timeout)
1774 {
1775  return send_command_("shutdown", timeout);
1776 }
1778 {
1779  return send_command_("status");
1780 }
1781 std::string xmlrpc_commander::send_report(std::string const& what)
1782 {
1783  return send_command_("report", what);
1784 }
1786 {
1787  return send_command_("legal_commands");
1788 }
1789 std::string xmlrpc_commander::send_trace_get(std::string const& name)
1790 {
1791  return send_command_("trace_get", name);
1792 }
1793 std::string xmlrpc_commander::send_trace_set(std::string const& name, std::string const& type, std::string const& mask)
1794 {
1795  return send_command_("trace_set", name, type, mask);
1796 }
1797 std::string xmlrpc_commander::send_meta_command(std::string const& command, std::string const& arg)
1798 {
1799  return send_command_("meta_command", command, arg);
1800 }
1801 std::string xmlrpc_commander::send_rollover_subrun(uint64_t when, uint32_t sr)
1802 {
1803  return send_command_("rollover_subrun", when, sr);
1804 }
1805 } // namespace artdaq
1806 
1807 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:539
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:126
Commandable is the base class for all artdaq components which implement the artdaq state machine...
Definition: Commandable.hh:22
legal_commands_(xmlrpc_commander &c)
legal_commands_ Constructor
virtual bool do_clear_config_archive()
Clears the configuration archive list.
Definition: Commandable.cc:545
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:155
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:300
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:144
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:473
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:313
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:63
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:436
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:526
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:532
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:182