00001
00002
00003
00004
00005
00006 #pragma GCC diagnostic push
00007 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00008 #include <xmlrpc-c/base.hpp>
00009 #include <xmlrpc-c/registry.hpp>
00010 #include <xmlrpc-c/server_abyss.hpp>
00011 #include <xmlrpc-c/girerr.hpp>
00012 #include <xmlrpc-c/client_simple.hpp>
00013 #pragma GCC diagnostic pop
00014 #include <stdexcept>
00015 #include <iostream>
00016 #include <limits>
00017 #include <memory>
00018 #include <cstdint>
00019 #define TRACE_NAME "xmlrpc_commander"
00020 #include "tracemf.h"
00021
00022 #include "artdaq-core/Utilities/ExceptionHandler.hh"
00023 #include <sys/socket.h>
00024 #include <netinet/in.h>
00025 #include <errno.h>
00026 #include <cstring>
00027 #include <exception>
00028
00029 #include "canvas/Persistency/Provenance/RunID.h"
00030 #include "fhiclcpp/make_ParameterSet.h"
00031
00032 #include "artdaq/ExternalComms/xmlrpc_commander.hh"
00033 #include "artdaq/DAQdata/Globals.hh"
00034
00035
00036 namespace {
00037 class env_wrap {
00038 public:
00039 env_wrap() { xmlrpc_env_init(&this->env_c); };
00040 ~env_wrap(){ xmlrpc_env_clean(&this->env_c);};
00041 xmlrpc_env env_c;
00042 };
00043 }
00044 static xmlrpc_c::paramList
00045 pListFromXmlrpcArray(xmlrpc_value * const arrayP)
00046 {
00047 env_wrap env;
00048 XMLRPC_ASSERT_ARRAY_OK(arrayP);
00049 unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP);
00050 assert(!env.env_c.fault_occurred);
00051 xmlrpc_c::paramList paramList(arraySize);
00052 for (unsigned int i = 0; i < arraySize; ++i) {
00053 xmlrpc_value * arrayItemP;
00054 xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP);
00055 assert(!env.env_c.fault_occurred);
00056 paramList.add(xmlrpc_c::value(arrayItemP));
00057 xmlrpc_DECREF(arrayItemP);
00058 }
00059 return paramList;
00060 }
00061 static xmlrpc_value *
00062 c_executeMethod(xmlrpc_env * const envP,
00063 xmlrpc_value * const paramArrayP,
00064 void * const methodPtr,
00065 void * const callInfoPtr)
00066 {
00067 xmlrpc_c::method * const methodP(static_cast<xmlrpc_c::method *>(methodPtr));
00068 xmlrpc_c::paramList const paramList(pListFromXmlrpcArray(paramArrayP));
00069 xmlrpc_c::callInfo * const callInfoP(static_cast<xmlrpc_c::callInfo *>(callInfoPtr));
00070 xmlrpc_value * retval;
00071 retval = NULL;
00072 try {
00073 xmlrpc_c::value result;
00074 try {
00075 xmlrpc_c::method2 * const method2P(dynamic_cast<xmlrpc_c::method2 *>(methodP));
00076 if (method2P)
00077 method2P->execute(paramList, callInfoP, &result);
00078 else
00079 methodP->execute(paramList, &result);
00080 } catch (xmlrpc_c::fault const& fault) {
00081 xmlrpc_env_set_fault(envP, fault.getCode(),
00082 fault.getDescription().c_str());
00083 }
00084 if (!envP->fault_occurred) {
00085 if (result.isInstantiated())
00086 retval = result.cValue();
00087 else
00088 girerr::throwf("Xmlrpc-c user's xmlrpc_c::method object's "
00089 "'execute method' failed to set the RPC result "
00090 "value.");
00091 }
00092 } catch (std::exception const& e) {
00093 xmlrpc_faultf(envP, "Unexpected error executing code for "
00094 "particular method, detected by Xmlrpc-c "
00095 "method registry code. Method did not "
00096 "fail; rather, it did not complete at all. %s",
00097 e.what());
00098 } catch (...) {
00099 xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
00100 "Unexpected error executing code for "
00101 "particular method, detected by Xmlrpc-c "
00102 "method registry code. Method did not "
00103 "fail; rather, it did not complete at all.");
00104 }
00105 return retval;
00106 }
00107
00108
00109
00110 namespace artdaq
00111 {
00118 std::string exception_msg(const std::runtime_error& er,
00119 const std::string& helpText = "execute request")
00120 {
00121 std::string msg("Exception when trying to ");
00122 msg.append(helpText);
00123 msg.append(": ");
00124 msg.append(er.what());
00125 if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
00126 return msg;
00127 }
00128
00135 std::string exception_msg(const art::Exception& er,
00136 const std::string& helpText)
00137 {
00138 std::string msg("Exception when trying to ");
00139 msg.append(helpText);
00140 msg.append(": ");
00141 msg.append(er.what());
00142 if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
00143 return msg;
00144 }
00145
00152 std::string exception_msg(const cet::exception& er,
00153 const std::string& helpText)
00154 {
00155 std::string msg("Exception when trying to ");
00156 msg.append(helpText);
00157 msg.append(": ");
00158 msg.append(er.what());
00159 if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
00160 return msg;
00161 }
00162
00169 std::string exception_msg(const std::string& erText,
00170 const std::string& helpText)
00171 {
00172 std::string msg("Exception when trying to ");
00173 msg.append(helpText);
00174 msg.append(": ");
00175 msg.append(erText);
00176 if (msg[msg.size() - 1] == '\n') msg.erase(msg.size() - 1);
00177 return msg;
00178 }
00179
00180
00198 class cmd_ : public xmlrpc_c::method
00199 {
00200 public:
00201
00202
00209 cmd_(xmlrpc_commander& c, const std::string& signature, const std::string& description) : _c(c)
00210 {
00211 _signature = signature;
00212 _help = description;
00213 }
00214
00220 void execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP) final;
00221
00222 protected:
00223
00224 xmlrpc_commander & _c;
00225
00231 virtual bool execute_(const xmlrpc_c::paramList&, xmlrpc_c::value* const retvalP) = 0;
00232
00242 template <typename T>
00243 T getParam(const xmlrpc_c::paramList& paramList, int index);
00244
00268 template <typename T>
00269 T getParam(const xmlrpc_c::paramList& paramList, int index, T default_value);
00270 };
00271
00272
00273
00274
00275 template <typename T>
00276 T cmd_::getParam(const xmlrpc_c::paramList&, int)
00277 {
00278 throw cet::exception("cmd_") << "Error in cmd_::getParam(): value type not supported" << std::endl;
00279 }
00280
00289 template <>
00290 uint64_t cmd_::getParam<uint64_t>(const xmlrpc_c::paramList& paramList, int index)
00291 {
00292 return boost::lexical_cast<uint64_t>(paramList.getInt(index));
00293 }
00294
00303 template <>
00304 std::string cmd_::getParam<std::string>(const xmlrpc_c::paramList& paramList, int index)
00305 {
00306 return static_cast<std::string>(paramList.getString(index));
00307 }
00308
00317 template <>
00318 art::RunID cmd_::getParam<art::RunID>(const xmlrpc_c::paramList& paramList, int index)
00319 {
00320 std::string run_number_string = paramList.getString(index);
00321 art::RunNumber_t run_number =
00322 boost::lexical_cast<art::RunNumber_t>(run_number_string);
00323 art::RunID run_id(run_number);
00324
00325 return run_id;
00326 }
00327
00336 template <>
00337 fhicl::ParameterSet cmd_::getParam<fhicl::ParameterSet>(const xmlrpc_c::paramList& paramList, int index)
00338 {
00339 std::string configString = std::string(paramList.getString(index).c_str());
00340 TLOG_DEBUG("xmlrpc_commander") << "Loading Parameter Set from string: " << configString << std::endl;
00341 fhicl::ParameterSet pset;
00342
00343 try
00344 {
00345 fhicl::make_ParameterSet(configString, pset);
00346 }
00347 catch (fhicl::exception e)
00348 {
00349 if (getenv("FHICL_FILE_PATH") == nullptr)
00350 {
00351 std::cerr << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
00352 setenv("FHICL_FILE_PATH", ".", 0);
00353 }
00354 cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
00355 fhicl::make_ParameterSet(configString, lookup_policy, pset);
00356 }
00357
00358 TLOG_INFO("xmlrpc_commander") << "Parameter Set Loaded." << std::endl;
00359 return pset;
00360 }
00361
00362 template <typename T>
00363 T cmd_::getParam(const xmlrpc_c::paramList& paramList, int index,
00364 T default_value)
00365 {
00366 T val = default_value;
00367
00368 try
00369 {
00370 val = getParam<T>(paramList, index);
00371 }
00372 catch (const cet::exception& exception)
00373 {
00374 throw exception;
00375 }
00376 catch (...) {}
00377
00378 return val;
00379 }
00380
00381 void cmd_::execute(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP)
00382 {
00383 std::unique_lock<std::mutex> lk(_c.mutex_, std::try_to_lock);
00384 if (lk.owns_lock())
00385 {
00386 try
00387 {
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 if (execute_(paramList, retvalP))
00399 {
00400 if (!retvalP->isInstantiated())
00401 {
00402 *retvalP = xmlrpc_c::value_string("Success");
00403 }
00404 }
00405 else
00406 {
00407 std::string problemReport = _c._commandable.report("transition_status");
00408 *retvalP = xmlrpc_c::value_string(problemReport);
00409 }
00410 }
00411 catch (std::runtime_error& er)
00412 {
00413 std::string msg = exception_msg(er, _help);
00414 *retvalP = xmlrpc_c::value_string(msg);
00415 TLOG_ERROR("XMLRPC_Commander") << msg << TLOG_ENDL;
00416 }
00417 catch (art::Exception& er)
00418 {
00419 std::string msg = exception_msg(er, _help);
00420 *retvalP = xmlrpc_c::value_string(msg);
00421 TLOG_ERROR("XMLRPC_Commander") << msg << TLOG_ENDL;
00422 }
00423 catch (cet::exception& er)
00424 {
00425 std::string msg = exception_msg(er, _help);
00426 *retvalP = xmlrpc_c::value_string(msg);
00427 TLOG_ERROR("XMLRPC_Commander") << msg << TLOG_ENDL;
00428 }
00429 catch (...)
00430 {
00431 std::string msg = exception_msg("Unknown exception", _help);
00432 *retvalP = xmlrpc_c::value_string(msg);
00433 TLOG_ERROR("XMLRPC_Commander") << msg << TLOG_ENDL;
00434 }
00435 }
00436 else
00437 {
00438 *retvalP = xmlrpc_c::value_string("busy");
00439 }
00440 }
00441
00442
00444
00445
00446
00447
00448
00449
00450
00451 #define GENERATE_INIT_TRANSITION(NAME, CALL, DESCRIPTION) \
00452 \
00453 class NAME ## _: public cmd_ { \
00454 \
00455 public: \
00456 \
00459 explicit NAME ## _(xmlrpc_commander& c): \
00460 cmd_(c, "s:sii", DESCRIPTION) {} \
00461 \
00462 \
00463 static const uint64_t defaultTimeout = 45; \
00464 \
00465 static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
00466 \
00467 private: \
00468 bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const retvalP ) { \
00469 fhicl::ParameterSet ps; \
00470 try { \
00471 ps = getParam<fhicl::ParameterSet>(paramList, 0); \
00472 } catch (...) { \
00473 *retvalP = xmlrpc_c::value_string ("The "#NAME" message requires a single argument that is a string containing the initialization ParameterSet"); \
00474 return true; \
00475 } \
00476 \
00477 return _c._commandable.CALL(ps, \
00478 getParam<uint64_t>(paramList, 1, defaultTimeout), \
00479 getParam<uint64_t>(paramList, 2, defaultTimestamp) \
00480 ); \
00481 } \
00482 };
00483
00484 GENERATE_INIT_TRANSITION(init, initialize, "initialize the program")
00485
00486 GENERATE_INIT_TRANSITION(soft_init, soft_initialize, "initialize software components in the program")
00487
00488 GENERATE_INIT_TRANSITION(reinit, reinitialize, "re-initialize the program")
00489
00490 #undef GENERATE_INIT_TRANSITION
00491
00493
00497 class start_ : public cmd_
00498 {
00499 public:
00504 explicit start_(xmlrpc_commander& c) :
00505 cmd_(c, "s:iii", "start the run")
00506 {}
00507
00509 static const uint64_t defaultTimeout = 45;
00511 static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max();
00512
00513 private:
00514
00515 bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP) override
00516 {
00517 try
00518 {
00519 getParam<art::RunID>(paramList, 0);
00520 }
00521 catch (...)
00522 {
00523 *retvalP = xmlrpc_c::value_string("The start message requires the run number as an argument.");
00524 return true;
00525 }
00526
00527 return _c._commandable.start(getParam<art::RunID>(paramList, 0),
00528 getParam<uint64_t>(paramList, 1, defaultTimeout),
00529 getParam<uint64_t>(paramList, 2, defaultTimestamp)
00530 );
00531 }
00532 };
00533
00534
00536
00537
00538
00539
00540
00541
00542
00543 #define GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(NAME, CALL, DESCRIPTION, TIMEOUT) \
00544 \
00545 class NAME ## _: public cmd_ { \
00546 \
00547 public: \
00548 \
00550 NAME ## _(xmlrpc_commander& c): \
00551 cmd_(c, "s:ii", DESCRIPTION) {} \
00552 \
00553 \
00554 static const uint64_t defaultTimeout = TIMEOUT ; \
00555 \
00556 static const uint64_t defaultTimestamp = std::numeric_limits<const uint64_t>::max(); \
00557 \
00558 private: \
00559 \
00560 bool execute_ (const xmlrpc_c::paramList& paramList , xmlrpc_c::value* const ) { \
00561 \
00562 return _c._commandable.CALL( getParam<uint64_t>(paramList, 0, defaultTimeout), \
00563 getParam<uint64_t>(paramList, 1, defaultTimestamp) \
00564 ); \
00565 } \
00566 };
00567
00568 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(pause, pause, "pause the program", 45)
00569
00570 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(resume, resume, "resume the program", 45)
00571
00572 GENERATE_TIMEOUT_TIMESTAMP_TRANSITION(stop, stop, "stop the program", 45)
00573
00574 #undef GENERATE_TIMEOUT_TIMESTAMP_TRANSITION
00575
00576
00580 class shutdown_ : public cmd_
00581 {
00582 public:
00587 shutdown_(xmlrpc_commander& c) :
00588 cmd_(c, "s:i", "shutdown the program")
00589 {}
00590
00592 static const uint64_t defaultTimeout = 45;
00593
00594 private:
00595
00596 bool execute_(const xmlrpc_c::paramList& paramList, xmlrpc_c::value* const)
00597 {
00598 return _c._commandable.shutdown(getParam<uint64_t>(paramList, 0, defaultTimeout));
00599 }
00600 };
00601
00602
00606 class status_ : public cmd_
00607 {
00608 public:
00613 status_(xmlrpc_commander& c) :
00614 cmd_(c, "s:n", "report the current state")
00615 {}
00616
00617 private:
00618
00619 bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
00620 {
00621 *retvalP = xmlrpc_c::value_string(_c._commandable.status());
00622 return true;
00623 }
00624 };
00625
00626
00630 class report_ : public cmd_
00631 {
00632 public:
00637 report_(xmlrpc_commander& c) :
00638 cmd_(c, "s:s", "report statistics")
00639 {}
00640
00641 private:
00642 bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
00643 {
00644 try
00645 {
00646 getParam<std::string>(paramList, 0);
00647 }
00648 catch (...)
00649 {
00650 *retvalP = xmlrpc_c::value_string("The report message requires a single argument that selects the type of statistics to be reported.");
00651 return true;
00652 }
00653
00654 *retvalP = xmlrpc_c::value_string(_c._commandable.report(getParam<std::string>(paramList, 0)));
00655 return true;
00656 }
00657 };
00658
00662 class legal_commands_ : public cmd_
00663 {
00664 public:
00669 legal_commands_(xmlrpc_commander& c) :
00670 cmd_(c, "s:n", "return the currently legal commands")
00671 {}
00672
00673 private:
00674 bool execute_(xmlrpc_c::paramList const&, xmlrpc_c::value* const retvalP)
00675 {
00676 std::vector<std::string> cmdList = _c._commandable.legal_commands();
00677 std::string resultString;
00678
00679 for (auto& cmd : cmdList)
00680 {
00681 resultString.append(cmd + " ");
00682 if (cmd == "shutdown")
00683 {
00684 resultString.append(" reset");
00685 }
00686 }
00687 *retvalP = xmlrpc_c::value_string(resultString);
00688
00689 return true;
00690 }
00691 };
00692
00696 class register_monitor_ : public cmd_
00697 {
00698 public:
00703 register_monitor_(xmlrpc_commander& c) :
00704 cmd_(c, "s:s", "Get notified of a new monitor")
00705 {}
00706
00707 private:
00708 bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
00709 {
00710 try
00711 {
00712 getParam<fhicl::ParameterSet>(paramList, 0);
00713 }
00714 catch (...)
00715 {
00716 *retvalP = xmlrpc_c::value_string("The register_monitor command expects a string representing the FHiCL definition of a Transfer plugin");
00717 return true;
00718 }
00719
00720 *retvalP = xmlrpc_c::value_string(_c._commandable.register_monitor(getParam<fhicl::ParameterSet>(paramList, 0)));
00721 return true;
00722 }
00723 };
00724
00728 class unregister_monitor_ : public cmd_
00729 {
00730 public:
00735 unregister_monitor_(xmlrpc_commander& c) :
00736 cmd_(c, "s:s", "Remove a monitor")
00737 {}
00738
00739 private:
00740 bool execute_(xmlrpc_c::paramList const& paramList, xmlrpc_c::value* const retvalP)
00741 {
00742 try
00743 {
00744 getParam<std::string>(paramList, 0);
00745 }
00746 catch (...)
00747 {
00748 *retvalP = xmlrpc_c::value_string("The unregister_monitor command expects a string representing the label of the monitor to be removed");
00749 return true;
00750 }
00751
00752 *retvalP = xmlrpc_c::value_string(_c._commandable.unregister_monitor(getParam<std::string>(paramList, 0)));
00753 return true;
00754 }
00755 };
00756
00757
00758
00759
00760
00761
00762
00763 #if 0
00764 class shutdown_ : public xmlrpc_c::registry::shutdown
00765 {
00766 public:
00767 shutdown_(xmlrpc_c::serverAbyss *server) : _server(server) {}
00768
00769 virtual void doit(const std::string& paramString, void*) const
00770 {
00771 TLOG_INFO("XMLRPC_Commander") << "A shutdown command was sent "
00772 << "with parameter "
00773 << paramString << "\"" << TLOG_ENDL;
00774 _server->terminate();
00775 }
00776 private:
00777 xmlrpc_c::serverAbyss *_server;
00778 };
00779 #endif
00780
00781
00782
00783 xmlrpc_commander::xmlrpc_commander(fhicl::ParameterSet ps, artdaq::Commandable& commandable)
00784 : CommanderInterface(ps, commandable)
00785 , port_(ps.get<int>("id", 0))
00786 , serverUrl_(ps.get<std::string>("server_url", ""))
00787 {
00788
00789 }
00790
00791 void xmlrpc_commander::run_server() try
00792 {
00793
00794 xmlrpc_c::registry registry;
00795 struct xmlrpc_method_info3 methodInfo;
00796 memset(&methodInfo, 0 , sizeof(methodInfo));
00797
00798
00799
00800
00801 #define register_method(m) register_method2(m,0x200000)
00802
00803 xmlrpc_env env;
00804 xmlrpc_registry ***c_registryPPP;
00805 c_registryPPP = (xmlrpc_registry ***)(((char*)®istry)+sizeof(girmem::autoObject));
00806
00807 #define register_method2(m,ss) \
00808 xmlrpc_c::method * ptr_ ## m(dynamic_cast<xmlrpc_c::method *>(new m ## _(*this))); \
00809 methodInfo.methodName = "daq." #m; \
00810 methodInfo.methodFunction = &c_executeMethod; \
00811 methodInfo.serverInfo = ptr_ ## m; \
00812 methodInfo.stackSize = ss; \
00813 methodInfo.signatureString = ptr_ ## m ->signature().c_str(); \
00814 methodInfo.help = ptr_ ## m ->help().c_str(); \
00815 xmlrpc_env_init(&env); \
00816 xmlrpc_registry_add_method3(&env,**c_registryPPP,&methodInfo); \
00817 if(env.fault_occurred)throw(girerr::error(env.fault_string)); \
00818 xmlrpc_env_clean(&env)
00819
00820 register_method2(init,0x200000);
00821 register_method(soft_init);
00822 register_method(reinit);
00823 register_method(start);
00824 register_method(status);
00825 register_method(report);
00826 register_method(stop);
00827 register_method(pause);
00828 register_method(resume);
00829 register_method(register_monitor);
00830 register_method(unregister_monitor);
00831 register_method(legal_commands);
00832
00833 register_method(shutdown);
00834
00835
00836 xmlrpc_c::methodPtr const ptr_reset(new shutdown_(*this));
00837 registry.addMethod("daq.reset", ptr_reset);
00838
00839 #undef register_method
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 XMLRPC_SOCKET socket_file_descriptor = socket(PF_INET, SOCK_STREAM, 0);
00857
00858 if (socket_file_descriptor < 0)
00859 {
00860 throw cet::exception("xmlrpc_commander::run") <<
00861 "Problem with the socket() call; C-style errno == " <<
00862 errno << " (" << strerror(errno) << ")";
00863 }
00864
00865 int enable = 1;
00866 int retval = setsockopt(socket_file_descriptor,
00867 SOL_SOCKET, SO_REUSEADDR,
00868 &enable, sizeof(int));
00869
00870 if (retval < 0)
00871 {
00872 throw cet::exception("xmlrpc_commander::run") <<
00873 "Problem with the call to setsockopt(); C-style errno == " <<
00874 errno << " (" << strerror(errno) << ")";
00875 }
00876
00877 struct sockaddr_in sockAddr;
00878
00879 sockAddr.sin_family = AF_INET;
00880 sockAddr.sin_port = htons(port_);
00881 sockAddr.sin_addr.s_addr = 0;
00882
00883 retval = bind(socket_file_descriptor,
00884 reinterpret_cast<struct sockaddr*>(&sockAddr),
00885 sizeof(sockAddr));
00886
00887 if (retval != 0)
00888 {
00889 close(socket_file_descriptor);
00890 throw cet::exception("xmlrpc_commander::run") <<
00891 "Problem with the bind() call; C-style errno == " <<
00892 errno << " (" << strerror(errno) << ")";
00893 }
00894
00895 xmlrpc_c::serverAbyss server(xmlrpc_c::serverAbyss::constrOpt().registryP(®istry).socketFd(socket_file_descriptor));
00896
00897 #if 0
00898 xmlrpc_c::serverAbyss::shutdown shutdown_obj(&server);
00899 registry.setShutdown(&shutdown_obj);
00900 #endif
00901
00902 TLOG_DEBUG("XMLRPC_Commander") << "running server" << TLOG_ENDL;
00903
00904
00905
00906
00907
00908
00909
00910 try
00911 {
00912 server.run();
00913 }
00914 catch (...)
00915 {
00916 TLOG_WARNING("XMLRPC_Commander") << "server threw an exception; closing the socket and rethrowing" << TLOG_ENDL;
00917 close(socket_file_descriptor);
00918 throw;
00919 }
00920
00921 close(socket_file_descriptor);
00922 TLOG_DEBUG("XMLRPC_Commander") << "server terminated" << TLOG_ENDL;
00923 }
00924 catch (...)
00925 {
00926 throw;
00927 }
00928
00929
00930 std::string xmlrpc_commander::send_register_monitor(std::string monitor_fhicl)
00931 {
00932 if (serverUrl_ == "")
00933 {
00934 std::stringstream errmsg;
00935 errmsg << "Problem attempting XML-RPC call: No server URL set!";
00936 ExceptionHandler(ExceptionHandlerRethrow::yes,
00937 errmsg.str());
00938
00939 }
00940 xmlrpc_c::clientSimple myClient;
00941 xmlrpc_c::value result;
00942
00943 try
00944 {
00945 myClient.call(serverUrl_, "daq.register_monitor", "s", &result, monitor_fhicl.c_str());
00946 }
00947 catch (...)
00948 {
00949 std::stringstream errmsg;
00950 errmsg << "Problem attempting XML-RPC call on host " << serverUrl_
00951 << "; possible causes are malformed FHiCL or nonexistent process at requested port";
00952 ExceptionHandler(ExceptionHandlerRethrow::yes,
00953 errmsg.str());
00954 }
00955
00956 return xmlrpc_c::value_string(result);
00957 }
00958
00959 std::string xmlrpc_commander::send_unregister_monitor(std::string monitor_label)
00960 {
00961 if (serverUrl_ == "")
00962 {
00963 std::stringstream errmsg;
00964 errmsg << "Problem attempting XML-RPC call: No server URL set!";
00965 ExceptionHandler(ExceptionHandlerRethrow::yes,
00966 errmsg.str());
00967
00968 }
00969
00970 xmlrpc_c::clientSimple myClient;
00971 xmlrpc_c::value result;
00972
00973 try
00974 {
00975 myClient.call(serverUrl_, "daq.unregister_monitor", "s", &result, monitor_label.c_str());
00976 }
00977 catch (...)
00978 {
00979 std::stringstream errmsg;
00980 errmsg << "Problem attempting to unregister monitor via XML-RPC call on host " << serverUrl_
00981 << "; possible causes are that the monitor label \""
00982 << monitor_label
00983 << "\" is unrecognized by contacted process or process at requested port doesn't exist";
00984 ExceptionHandler(ExceptionHandlerRethrow::no,
00985 errmsg.str());
00986 }
00987
00988 return xmlrpc_c::value_string(result);
00989
00990 }
00991 }
00992
00993 DEFINE_ARTDAQ_COMMANDER(artdaq::xmlrpc_commander)