16#include <boost/program_options.hpp>
17#include <fmt/chrono.h>
18#include <fmt/format.h>
19#include <fmt/ostream.h>
21#include <rad/helper.hpp>
28 : m_logger(std::move(logger)), m_mgr(m_logger) {
29 m_mgr.
Register(&m_config.
name, {
"cfg/procname",
"Component instance ID"});
30 m_mgr.
Register(&m_config.
dataroot, {
"cfg/dataroot",
"ICS standard DATAROOT directory"});
31 m_mgr.
Register(&m_config.
workspace, {
"cfg/daq/workspace",
"DPM merge workspace"});
32 m_mgr.
Register(&m_config.
rr_uri, {
"cfg/req_endpoint",
"Request/reply URI"});
33 m_mgr.
Register(&m_config.
ps_uri, {
"cfg/pub_endpoint",
"Publish/subscribe URI"});
34 m_mgr.
Register(&m_config.
no_ipc, {
"cfg/no_ipc",
"Disables IPC interfaces"});
36 {
"cfg/oldb_uri_prefix",
"CII OLDB prefix 'cii.oldb:/elt/..'"});
37 m_mgr.
Register(&m_config.
db_timeout, {
"cfg/oldb_conn_timeout",
"CII OLDB connection timeout"});
39 m_mgr.
Register(&m_config.
log_config, {
"cfg/log_properties",
"Log configuration file"});
43 m_mgr.
Register(&m_config.
merge_bin, {
"cfg/bin_merge",
"DPM Merge application binary."});
44 m_mgr.
Register(&m_config.
rsync_bin, {
"cfg/bin_rsync",
"rsync application binary."});
46 m_mgr.
Register(&m_config.
limit_daq, {
"cfg/limits/daq",
"Concurrency limit: Number of DAQs"});
48 {
"cfg/limits/merge",
"Concurrency limit: Number of merges"});
50 {
"cfg/limits/net_send",
"Concurrency limit: Number of network send tranfers."});
53 {
"cfg/limits/net_receive",
"Concurrency limit: Number of network receive transfers."});
55 if (
auto root = rad::Helper::GetEnvVar(
"DATAROOT"); !root.empty()) {
56 m_mgr.
Update(&m_config.
dataroot, root, {config::Origin::EnvironmentVariable,
"$DATAROOT"});
61 namespace po = boost::program_options;
64 po::options_description options_desc(
"Options");
68 options_desc.add_options()
69 (
"help,h",
"Print help messages")
71 po::value<std::string>(),
74 po::value<std::string>(),
75 "Log level: ERROR, WARNING, STATE, EVENT, ACTION, INFO, DEBUG, TRACE")
77 po::value<std::string>(),
78 "Configuration filename")
80 po::value<std::string>(),
81 "In-memory DB host (ipaddr:port)")
83 po::value<std::string>(),
86 po::value<std::string>(),
87 "Publish/subscribe URI")
89 po::value<std::string>(),
90 "workspace path (relative paths are relateive to dataroot)")
92 "Disable request/reply, publish/subscribe and OLDB interfaces for standalone mode")
94 "Poll scheduler once and then exit rather than running until asked to quit (this "
95 "option also implies --no-ipc)")
98 po::variables_map options_map;
99 po::store(po::parse_command_line(argc, argv, options_desc), options_map);
100 if (options_map.count(
"help")) {
101 std::cerr << options_desc << std::endl;
104 po::notify(options_map);
106 if (options_map.count(
"config")) {
107 auto value = options_map[
"config"].as<std::string>();
111 if (options_map.count(
"log-level")) {
114 auto ll_str = options_map[
"log-level"].as<std::string>();
115 auto ll = boost::lexical_cast<LogLevel>(ll_str);
119 if (options_map.count(
"proc-name")) {
120 auto value = options_map[
"proc-name"].as<std::string>();
121 if (m_mgr.
Update(&m_config.
name, value, si)) {
124 "cii.oldb:/elt/" + m_config.
name,
129 if (options_map.count(
"db-host")) {
130 LOG4CPLUS_WARN(m_logger,
131 "Command line parameter --db-host|-d is deprecated and only provided "
132 "for compatibility");
134 if (options_map.count(
"rr-uri")) {
135 auto value = options_map[
"rr-uri"].as<std::string>();
138 if (options_map.count(
"ps-uri")) {
139 auto value = options_map[
"ps-uri"].as<std::string>();
142 if (options_map.count(
"workspace")) {
143 auto value = options_map[
"workspace"].as<std::string>();
146 if (options_map.count(
"no-ipc")) {
149 if (options_map.count(
"poll-once")) {
158 std::throw_with_nested(std::runtime_error(
"Failed to parse command line arguments"));
163void ConfigManager::LoadConfig()
try {
164 std::string resolved = rad::Helper::FindFile(m_config.config_file);
165 LOG4CPLUS_INFO(m_logger,
"Loading configuration from " << resolved);
166 if (resolved.empty()) {
167 auto msg = fmt::format(
"Could not resolve config file {}", m_config.config_file);
168 LOG4CPLUS_ERROR(m_logger, msg);
169 throw std::invalid_argument(msg);
173 auto ifs = std::ifstream(resolved);
174 ifs.exceptions(std::ios_base::badbit);
176 elt::configng::CiiConfigDocument config;
177 config.UpdateFromStream(ifs);
178 auto const& root = config.GetInstanceRootNode();
181 UpdateFromConfig<std::string>(&m_config.dataroot, root, si);
182 UpdateFromConfig<std::string>(&m_config.workspace, root, si);
183 UpdateFromConfig<std::string>(&m_config.log_config, root, si);
184 UpdateFromConfig<std::string>(&m_config.rr_uri, root, si);
185 UpdateFromConfig<std::string>(&m_config.ps_uri, root, si);
186 UpdateFromConfig<std::string>(&m_config.merge_bin, root, si);
187 UpdateFromConfig<std::string>(&m_config.rsync_bin, root, si);
189 UpdateFromConfig<std::string>(&m_config.db_prefix, root, si);
190 UpdateFromConfig<int>(&m_config.db_timeout, root, si);
192 UpdateFromConfig<int>(&m_config.limit_daq, root, si);
193 UpdateFromConfig<int>(&m_config.limit_merge, root, si);
194 UpdateFromConfig<int>(&m_config.limit_net_receive, root, si);
195 UpdateFromConfig<int>(&m_config.limit_net_send, root, si);
198 std::throw_with_nested(std::runtime_error(
199 fmt::format(
"Failed to load configuration from {}", m_config.config_file)));
bool Update(AttrType *ptr, T const &value, OriginInfo const &origin)
Update configuration value taking into account the origin of the change.
void Register(AttrType *ptr, Metadata const &meta)
Registers a configuration parameter/attribute.
ConfigManager(log4cplus::Logger logger)
bool ParseArguments(int argc, char *argv[])
Parse configuration from command line arguments.
Declaration of log4cplus helpers.
@ Configuration
Configuration file.
@ Default
Built-in default value.
@ CommandLine
Command line argument.
std::optional< T > GetParamAs(std::string const &query, elt::configng::CiiConfigInstanceNode const &node)
Performs lookup of parameters in the form root/node/leaf relative to the provided node.
Mutable metadata about a configuration attribute that describes where a value comes from.
std::string name
Process instance name.
log4cplus::LogLevel log_level
std::string rsync_bin
rsync application name.
std::filesystem::path dataroot
Dataroot, normally this should be configured from environment variable $DATAROOT.
std::string merge_bin
Merge application name.
std::filesystem::path workspace
Workspace.
std::chrono::seconds db_timeout
bool no_ipc
If true (set by command line option only) it disables MAL service registration.
std::string rr_uri
Request/reply URI.
std::string ps_uri
Pub/sub URI.
std::string log_config
Log file, defaults to nothing.
bool poll_once
Run scheduler once.
std::filesystem::path config_file
Configuration file.
uint16_t limit_net_receive