32 #include <boost/format.hpp>
33 #include <boost/filesystem/fstream.hpp>
35 #include <rsc/config/TypedValue.h>
36 #include <rsc/config/ConfigFileSource.h>
37 #include <rsc/config/Environment.h>
38 #include <rsc/logging/Logger.h>
42 using namespace boost;
43 using namespace boost::filesystem;
45 using namespace rsc::config;
46 using namespace rsc::logging;
47 using namespace rsc::runtime;
51 ParticipantConfig::Transport::Transport(
const string& name,
55 throw invalid_argument(
56 "The name of a transport configuration cannot be empty.");
71 return this->converters;
88 return this->
getOptions().getAs<
bool> (
"enabled",
true);
93 options[
"enabled"] = lexical_cast<
string>(value);
98 const string& value) {
100 && (key[0] ==
"converter")
101 && (key[1] ==
"cpp")) {
102 if (key.size() != 3) {
103 throw invalid_argument(
106 "Option key `%1%' has invalid number of components; converter-related keys for transports has to have three components")
109 this->converters.insert(make_pair(key[2], value));
110 }
else if ((key.size() >= 2) && (key[0] ==
"converter")) {
113 if (key.size() != 1) {
114 throw invalid_argument(
117 "Key `%1%' has invalid number of components; transport option keys have to have one component.")
125 return name == other.
name;
129 return name < other.
name;
137 stream <<
"name = " << this->name
138 <<
", converters = " << this->converters
139 <<
", options = " << this->
options;
167 const string& value) {
168 if (key.size() != 1) {
169 throw invalid_argument(str(format(
"Key `%1%' has invalid number of components; transport option keys have to have one component.")
173 this->
options.set<
string>(key.front(), value);
177 stream <<
"name = " << this->name
178 <<
", options = " << this->
options;
182 logger(Logger::getLogger(
"rsb.ParticipantConfig")),
213 map<string, Transport>::const_iterator it = this->
transports.find(name);
215 throw rsc::runtime::NoSuchObject(name);
221 map<string, Transport>::iterator it = this->
transports.find(name);
223 throw rsc::runtime::NoSuchObject(name);
229 bool includeDisabled)
const {
230 set<Transport> result;
231 for (map<string, Transport>::const_iterator it = this->
transports.begin(); it
233 if (it->second.isEnabled() || includeDisabled) {
234 result.insert(it->second);
236 RSCDEBUG(
logger,
"Skipping disabled transport " << it->second);
252 for (set<Transport>::const_iterator it = transports.begin(); it
253 != transports.end(); ++it) {
254 this->transports.insert(make_pair(it->getName(), *it));
284 LoggerPtr
logger = Logger::getLogger(
"rsb.ParticipantConfig");
285 RSCDEBUG(logger,
"Trying to load config from file " << path);
289 boost::filesystem::ifstream stream(path);
291 RSCDEBUG(logger,
"Stream is open; proceeding");
292 ConfigFileSource(stream).provideOptions(result);
294 RSCDEBUG(logger,
"Could not open file");
303 EnvironmentVariableSource(
"RSB_").provideOptions(result);
311 result =
fromFile(systemConfigDirectory() /
"rsb.conf", result);
312 }
catch (
const runtime_error& e) {
313 RSCWARN(Logger::getLogger(
"rsb.ParticipantConfig"),
314 "Could not find a system-wide configuration file ("
319 result =
fromFile(userConfigDirectory() /
"rsb.conf", result);
320 }
catch (
const runtime_error& e) {
321 RSCWARN(Logger::getLogger(
"rsb.ParticipantConfig"),
322 "Could not find a user-specific configuration file ("
326 result =
fromFile(
"rsb.conf", result);
332 const string& value) {
334 if (key[0] ==
"qualityofservice") {
335 if (key.size() != 2) {
336 throw invalid_argument(
339 "Option key `%1%' has invalid number of components; options related to quality of service have to have two components.")
342 if (key[1] ==
"reliability") {
343 if (value ==
"UNRELIABLE") {
345 }
else if (value ==
"RELIABLE") {
348 throw invalid_argument(str(format(
349 "The value `%1%' is invalid for the key `%2%'.")
351 }
else if (key[1] ==
"ordering") {
352 if (value ==
"UNORDERED") {
354 }
else if (value ==
"ORDERED") {
357 throw invalid_argument(str(format(
358 "The value `%1%' is invalid for the key `%2%'.")
361 throw invalid_argument(
362 str(format(
"`%2%' is not a valid sub-key of `%1%'.")
366 }
else if (key[0] ==
"errorhandling") {
367 if (key[1] ==
"onhandlererror") {
368 if (value ==
"LOG") {
370 }
else if (value ==
"PRINT") {
372 }
else if (value ==
"EXIT") {
375 throw invalid_argument(str(format(
376 "The value `%1%' is invalid for the key `%2%'.")
380 throw invalid_argument(
381 str(format(
"`%2%' is not a valid sub-key of `%1%'.")
385 }
else if (key[0] ==
"eventprocessing") {
387 if (key[1] ==
"receivingstrategy") {
389 }
else if (key[1] ==
"sendingstrategy") {
392 throw invalid_argument(
393 str(format(
"`%2%' is not a valid sub-key of `%1%'.")
396 if (key.size() == 2) {
399 vector<string> subKey;
400 copy(key.begin() + 2, key.end(), back_inserter(subKey));
404 }
else if (key[0] ==
"transport") {
405 if (key.size() < 3) {
406 throw invalid_argument(
409 "Option key `%1%' has invalid number of components; transport-related keys have to have at least three components.")
412 map<string, Transport>::iterator it = this->
transports.find(key[1]);
418 vector<string> subKey;
419 copy(key.begin() + 2, key.end(), back_inserter(subKey));
423 if (key.size() == 1) {
424 this->
options[key[0]] = parseTypedValue(value);
430 stream <<
"qosSpec = " << this->
qosSpec
435 <<
", options = " << this->
options <<
"]";