LCOV - code coverage report
Current view: top level - cmdlib/plugins - stdinCommandFacility.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 61.2 % 49 30
Test Date: 2025-12-21 13:07:08 Functions: 38.9 % 18 7

            Line data    Source code
       1              : /**
       2              :  * @file stdinCommandFacility.cpp CommandFacility implementation
       3              :  * that reads commands from std::cin
       4              :  *
       5              :  * This is part of the DUNE DAQ Application Framework, copyright 2020.
       6              :  * Licensing/copyright details are in the COPYING file that you should have
       7              :  * received with this code.
       8              :  */
       9              : #include "cmdlib/CommandFacility.hpp"
      10              : #include "cmdlib/Issues.hpp"
      11              : #include "cmdlib/cmd/Nljs.hpp"
      12              : 
      13              : #include "logging/Logging.hpp" // NOTE: if ISSUES ARE DECLARED BEFORE include logging/Logging.hpp, TLOG_DEBUG<<issue wont work.
      14              : #include <nlohmann/json.hpp>
      15              : #include <cetlib/BasicPluginFactory.h>
      16              : 
      17              : #include <thread>
      18              : #include <chrono>
      19              : #include <map>
      20              : #include <memory>
      21              : #include <string>
      22              : #include <fstream>
      23              : 
      24              : namespace dunedaq {
      25              : 
      26              :     // Throw if a file can not be opened.  Provide "mode" of "reading"
      27              :     // or "writing" and provide erroneous filename as args.
      28            1 :     ERS_DECLARE_ISSUE(cmdlib, BadFile,
      29              :                      "Can not open file for " << mode << ": " << filename,
      30              :                       ((std::string)filename)
      31              :                       ((std::string)mode))
      32              : 
      33              : } // namespace dunedaq
      34              : 
      35              : using namespace dunedaq::cmdlib;
      36              : using namespace std::chrono_literals;
      37              : using json = nlohmann::json;
      38              : 
      39              :     
      40              : 
      41              : class stdinCommandFacility : public CommandFacility
      42              : {
      43              : public:
      44           10 :   explicit stdinCommandFacility(std::string uri) : CommandFacility(uri) { 
      45              :     // Allocate resources as needed
      46           10 :     auto col = uri.find_last_of(':');
      47           10 :     auto sep = uri.find("://");
      48           10 :     std::string fname;
      49           10 :     if (col == std::string::npos || sep == std::string::npos) { // assume filename
      50            0 :       fname = uri;
      51              :     } else {
      52           10 :       fname = uri.substr(sep+3);
      53              :     }
      54              : 
      55           20 :     TLOG() <<"Loading commands from file: " << fname;
      56              :    
      57           10 :     std::ifstream ifs;
      58           10 :     ifs.open(fname, std::fstream::in);
      59           10 :     if (!ifs.is_open()) {
      60            0 :       throw BadFile(ERS_HERE, fname, "reading");
      61              :     } 
      62              : 
      63           10 :     try {
      64           10 :       m_raw_commands = json::parse(ifs);
      65            0 :     } catch (const std::exception& ex) {
      66            0 :       throw CannotParseCommand(ERS_HERE, ex.what());
      67            0 :     }
      68           10 :     std::ostringstream avaostr;
      69           10 :     avaostr << "Available commands:";
      70           40 :     for (auto it = m_raw_commands.begin(); it != m_raw_commands.end(); ++it) {
      71           30 :       std::string idstr(it.value()["id"]);
      72           30 :       m_available_commands[idstr] = it.value();
      73           30 :       avaostr << " | " << idstr;
      74           30 :     }
      75           10 :     m_available_str = avaostr.str();
      76           10 :   }
      77              : 
      78              :   // Implementation of the runner
      79            1 :   void run(std::atomic<bool>& end_marker) {
      80            1 :     TLOG_DEBUG(1) << "Entered commands will be launched on CommandedObject...";
      81            1 :     std::string cmdid;
      82            2 :     while (end_marker) { //until runmarker
      83            0 :       TLOG() << m_available_str;
      84              :       // feed commands from cin
      85            0 :       std::cin >> cmdid;
      86            0 :       if (std::cin.eof()) {
      87              :         break;
      88              :       }
      89            0 :       if ( m_available_commands.find(cmdid) == m_available_commands.end() ) {
      90            0 :         std::ostringstream s;
      91            0 :         s << "Command " << cmdid << " is not available...";
      92            0 :         ers::error (CannotParseCommand(ERS_HERE, s.str()));
      93            0 :       } else {
      94            0 :         TLOG() << "Executing " << cmdid << " command...";
      95            0 :         inherited::execute_command(m_available_commands[cmdid], cmd::CommandReply());
      96              :       }
      97              :     }
      98            1 :     TLOG_DEBUG(1) << "Command handling stopped.";
      99            1 :   }
     100              : 
     101              : protected:
     102              :   typedef CommandFacility inherited;
     103              : 
     104              :   json m_raw_commands;
     105              :   std::map<std::string, json> m_available_commands;
     106              :   std::string m_available_str;
     107              : 
     108              :   // Implementation of completion_handler interface
     109            0 :   void completion_callback(const cmdobj_t& cmd, cmd::CommandReply& meta) {
     110            0 :     cmd::Command  command = cmd.get<cmd::Command>();
     111            0 :     TLOG() << "Application " << meta.appname << " executed command " << command.id << " with result: " << meta.success << " " << meta.result;
     112            0 :   }
     113              : 
     114              : };
     115              : 
     116              : extern "C" {
     117           10 :     std::shared_ptr<dunedaq::cmdlib::CommandFacility> make(std::string uri) {
     118           10 :         return std::shared_ptr<dunedaq::cmdlib::CommandFacility>(new stdinCommandFacility(uri));
     119              :     }
     120              : }
        

Generated by: LCOV version 2.0-1