44 std::lock_guard<std::mutex> m(mutex_);
46 runningStateMutables_.insert(std::make_pair(buildId,pRunningStateMutable));
50 const std::string & sName,
53 const std::vector<Any> & values,
54 const std::string & sUsage,
57 std::size_t minOccurs,
58 std::size_t maxOccurs,
59 const std::string & sRegexPattern)
76 const std::string & sName,
79 const std::vector<Any> & values,
80 const std::string & sUsage,
81 std::size_t minOccurs,
82 std::size_t maxOccurs,
83 const std::string & sRegexPattern)
97 void EMANE::ConfigurationService::registerAny(
BuildId buildId,
98 const std::string & sName,
101 std::lock_guard<std::mutex> m(mutex_);
103 if(std::find_if_not(sName.begin(),sName.end(),[](
int ch){
return isalnum(ch) || ch ==
'.';}) != sName.end())
105 throw makeException<RegistrarException>(
"Invalid charater in the configuration name: %s",
110 if(!configurationInfo.getRegexPattern().empty())
113 const char * pError{};
116 pPCRE = pcre_compile(configurationInfo.getRegexPattern().c_str(),
124 throw makeException<RegistrarException>(
"Bad regex pattern defined for %s: %s (offset:%i) %s",
126 configurationInfo.getRegexPattern().c_str(),
137 auto iter = buildIdConfigurationStore_.find(buildId);
139 if(iter != buildIdConfigurationStore_.end())
141 if(!iter->second.insert(std::make_pair(sName,configurationInfo)).second)
143 throw makeException<RegistrarException>(
"Duplicate configuration name registration detected: %s",
149 ConfigurationStore store;
151 store.insert(std::make_pair(sName,configurationInfo));
153 buildIdConfigurationStore_.insert(std::make_pair(buildId,std::move(store)));
162 std::lock_guard<std::mutex> m(mutex_);
166 auto iter = buildIdConfigurationStore_.find(buildId);
168 if(iter != buildIdConfigurationStore_.end())
170 auto & store = iter->second;
172 std::transform(store.begin(),
174 std::back_inserter(infos),
175 std::bind(&ConfigurationStore::value_type::second,std::placeholders::_1));
181 std::vector<std::pair<std::string,std::vector<EMANE::Any>>>
183 const std::vector<std::string> & names)
const 185 std::lock_guard<std::mutex> m(mutex_);
187 std::vector<std::pair<std::string,std::vector<Any>>> values;
189 auto iter = buildIdConfigurationStore_.find(buildId);
191 if(iter != buildIdConfigurationStore_.end())
193 auto & store = iter->second;
197 for_each(store.begin(),
203 bind(&ConfigurationStore::value_type::second,
204 std::placeholders::_1)));
208 for_each(names.begin(),
210 [&store,&values](
const std::string & s)
212 auto iter = store.find(s);
214 if(iter != store.end())
216 values.push_back(std::make_pair(s,iter->second.getValues()));
220 throw makeException<RegistrarException>(
"Unknown configuration parameter: %s",
235 std::lock_guard<std::mutex> m(mutex_);
239 auto iter = buildIdConfigurationStore_.find(buildId);
241 if(iter != buildIdConfigurationStore_.end())
243 auto & store = iter->second;
245 for(
const auto & paramIter : parameters)
247 auto infoIter = store.find(paramIter.first);
249 if(infoIter != store.end())
251 if(paramIter.second.size() >= infoIter->second.getMinOccurs() &&
252 paramIter.second.size() <= infoIter->second.getMaxOccurs())
255 const char * pError{};
259 const std::string & sRegexPattern = infoIter->second.getRegexPattern();
261 if(!sRegexPattern.empty())
263 pPCRE = pcre_compile(sRegexPattern.c_str(),
270 std::vector<Any> anys;
272 for(
const auto & value : paramIter.second)
276 auto anyType = infoIter->second.getType();
284 if(any < infoIter->second.getMinValue() ||
285 any > infoIter->second.getMaxValue())
287 throw makeException<ConfigurationException>(
"Out of range %s set to %s [%s,%s]",
288 paramIter.first.c_str(),
289 any.toString().c_str(),
290 infoIter->second.getMinValue().toString().c_str(),
291 infoIter->second.getMaxValue().toString().c_str());
306 throw makeException<ConfigurationException>(
"Regular expression mismatch %s set to %s (%s)",
307 paramIter.first.c_str(),
309 sRegexPattern.c_str());
317 throw makeException<ConfigurationException>(
"%s Parameter %s set to %s",
319 paramIter.first.c_str(),
324 updates.push_back(std::make_pair(paramIter.first,anys));
333 throw makeException<ConfigurationException>(
"Value occurrence out of range %s has %zu values [%zu,%zu]",
334 paramIter.first.c_str(),
335 paramIter.second.size(),
336 infoIter->second.getMinOccurs(),
337 infoIter->second.getMaxOccurs());
343 throw makeException<ConfigurationException>(
"Parameter not registered %s",
344 paramIter.first.c_str());
349 for(
const auto & iter : store)
351 const auto & sParamName(iter.first);
352 const auto & item(iter.second);
354 if(item.isRequired() || item.hasDefault())
356 if(std::find_if(updates.begin(),
358 std::bind(std::equal_to<std::string>(),
359 std::bind(&ConfigurationUpdate::value_type::first,
360 std::placeholders::_1),
361 sParamName)) == updates.end())
363 if(item.isRequired())
365 throw makeException<ConfigurationException>(
"Required item not present: %s",
371 updates.push_back(std::make_pair(sParamName,item.getValues()));
379 auto validatorIter = validatorStore_.find(buildId);
381 if(validatorIter != validatorStore_.end())
383 for(
auto validator : validatorIter->second)
385 auto ret = validator(updates);
389 throw makeException<ConfigurationException>(
"Validator failure: %s",ret.first.c_str());
397 std::for_each(updates.begin(),
399 [&store](
const ConfigurationUpdate::value_type & v)
401 store.find(v.first)->second.setValues(v.second);
407 if(!parameters.empty())
409 std::string sUnexpected{};
411 for(
const auto & parameter : parameters)
413 sUnexpected.append(parameter.first +
" ");
416 throw makeException<ConfigurationException>(
"Parameter(s) not registered: %s",
417 sUnexpected.c_str());
426 std::lock_guard<std::mutex> m(mutex_);
428 auto iter = buildIdConfigurationStore_.find(buildId);
430 if(iter != buildIdConfigurationStore_.end())
432 auto & store = iter->second;
434 for(
const auto &
update : updates)
436 auto infoIter = store.find(
update.first);
438 if(infoIter != store.end())
441 if(!infoIter->second.isModifiable())
443 throw makeException<ConfigurationException>(
"Parameter not running state modifiable %s",
448 if(
update.second.size() >= infoIter->second.getMinOccurs() &&
449 update.second.size() <= infoIter->second.getMaxOccurs())
452 const char * pError{};
456 const std::string & sRegexPattern = infoIter->second.getRegexPattern();
458 if(!sRegexPattern.empty())
460 pPCRE = pcre_compile(sRegexPattern.c_str(),
467 std::vector<Any> anys;
469 for(
const auto & value :
update.second)
471 auto anyType = infoIter->second.getType();
473 if(anyType!= value.getType())
475 throw makeException<ConfigurationException>(
"Parameter value type incorrect %s",
483 if(value < infoIter->second.getMinValue() ||
484 value > infoIter->second.getMaxValue())
486 throw makeException<ConfigurationException>(
"Out of range %s set to %s [%s,%s]",
488 value.toString().c_str(),
489 infoIter->second.getMinValue().toString().c_str(),
490 infoIter->second.getMaxValue().toString().c_str());
496 std::string sValue{value.toString()};
507 throw makeException<ConfigurationException>(
"Regular expression mismatch %s set to %s (%s)",
510 sRegexPattern.c_str());
523 throw makeException<ConfigurationException>(
"Value occurrence out of range %s has %zu values [%zu,%zu]",
526 infoIter->second.getMinOccurs(),
527 infoIter->second.getMaxOccurs());
533 throw makeException<ConfigurationException>(
"Parameter not registered %s",
539 auto validatorIter = validatorStore_.find(buildId);
541 if(validatorIter != validatorStore_.end())
543 auto canidateUpdates = updates;
545 for(
const auto & iter : store)
547 const auto & sParamName(iter.first);
548 const auto & item(iter.second);
550 const auto & values = item.getValues();
554 if(std::find_if(canidateUpdates.begin(),
555 canidateUpdates.end(),
556 std::bind(std::equal_to<std::string>(),
557 std::bind(&ConfigurationUpdate::value_type::first,
558 std::placeholders::_1),
559 sParamName)) == canidateUpdates.end())
562 canidateUpdates.push_back(std::make_pair(sParamName,item.getValues()));
567 for(
auto validator : validatorIter->second)
569 auto ret = validator(canidateUpdates);
573 throw makeException<ConfigurationException>(
"Validator failure: %s",ret.first.c_str());
578 auto mutablesIter = runningStateMutables_.find(buildId);
580 if(mutablesIter != runningStateMutables_.end())
584 std::for_each(updates.begin(),
586 [&store](
const ConfigurationUpdate::value_type & v)
588 store.find(v.first)->second.setValues(v.second);
591 mutablesIter->second->processConfiguration(updates);
595 throw makeException<ConfigurationException>(
"No component registered with build id %hu",buildId);
603 std::lock_guard<std::mutex> m(mutex_);
605 auto iter = validatorStore_.find(buildId);
607 if(iter != validatorStore_.end())
609 iter->second.push_back(validator);
613 validatorStore_.insert(std::make_pair(buildId,std::vector<ConfigurationValidator>{validator}));
void registerNonNumericAny(BuildId buildId, const std::string &sName, Any::Type type, const ConfigurationProperties &properties, const std::vector< Any > &values, const std::string &sUsage, std::size_t minOccurs, std::size_t maxOccurs, const std::string &sRegexPattern)
void registerNumericAny(BuildId buildId, const std::string &sName, Any::Type type, const ConfigurationProperties &properties, const std::vector< Any > &values, const std::string &sUsage, const Any &minValue, const Any &maxValue, std::size_t minOccurs, std::size_t maxOccurs, const std::string &sRegexPattern)
const std::string & getName() const
std::vector< std::pair< std::string, std::vector< Any > > > queryConfiguration(BuildId buildId, const std::vector< std::string > &names={}) const
const std::vector< Any > & getValues() const
const char * what() const
The RunningStateMutable interface is used to allow dynamic running-state configuration changes...
std::vector< ConfigurationInfo > ConfigurationManifest
void registerRunningStateMutable(BuildId buildId, RunningStateMutable *pRunningStateMutable)
void update(BuildId buildId, const ConfigurationUpdate &update)
void registerValidator(BuildId buildId, ConfigurationValidator validator)
ConfigurationUpdate buildUpdates(BuildId buildId, const ConfigurationUpdateRequest ¶meters)
ConfigurationManifest getConfigurationManifest(BuildId buildId) const
std::vector< ConfigurationNameStringValues > ConfigurationUpdateRequest
std::vector< ConfigurationNameAnyValues > ConfigurationUpdate
std::function< std::pair< std::string, bool >(const ConfigurationUpdate &update) noexcept > ConfigurationValidator
static Any create(std::string sValue, Type type)
Holds configuration item meta information.
AnyException is thrown when an exception occurs during creation or conversion of an Any...
The Any class can contain an instance of one of any type in its support type set. ...