RmsDestination.cpp
Go to the documentation of this file.
1 #include <rms/base/RmsDestination.h>
2 #include <rms/base/RmsRuntimeException.h>
3 
4 namespace gov {
5 
6 namespace fnal {
7 
8 namespace cd {
9 
10 namespace rms {
11 
12 namespace base {
13 
14 /**
15  * The following string constants define common broadcast targets.
16  */
18 const std::string RmsDestination::ALL_BNEVB_TARGET("allBufferNodeEVBs");
20 
21 /**
22  * The following string constants define expected application names.
23  */
28 const std::string RmsDestination::CONFIG_MANAGER_APPNAME("ConfigurationManager");
32 const std::string RmsDestination::DCM_APPNAME("DCMApplication");
33 const std::string RmsDestination::DAQDCS_APPNAME("DAQDCSMonitor");
35 const std::string RmsDestination::BNEVB_APPNAME("BufferNodeEVB");
37 const std::string RmsDestination::DAQAPP_MANAGER_APPNAME("DAQApplicationManager");
38 const std::string RmsDestination::DDT_MANAGER_APPNAME("DAQApplicationManager");
39 
40 /**
41  * The following string constants are used to set and retrieve
42  * common destination properties.
43  */
50 
51 /**
52  * The following string constants are common targets
53  * that are used with the target property.
54  */
56 
57 /**
58  * The following string constants are common channels
59  * that are used with the channel property.
60  */
70 
71 /**
72  * The following string constants are common message types
73  * that are used with the message type property.
74  */
79 
80 /**
81  * Used as an identifier for the null partition.
82  */
83 const int RmsDestination::NULL_PARTITION(-1);
84 
85 /**
86  * Creates an RmsDestination instance for the specified target and channel.
87  *
88  * @param target The target name
89  * @param channel The channel name
90  */
92  setDefaults();
95 }
96 
97 /**
98  * Creates an RmsDestination instance for the specified target, channel,
99  * and message type.
100  *
101  * @param target The target name
102  * @param channel The channel name
103  * @param messageType The message type
104  */
106  std::string messageType) {
107  setDefaults();
111 }
112 
113 /**
114  * Creates an RmsDestination instance for the specified target,
115  * channel, message type, and partition.
116  *
117  * @param target The target name
118  * @param channel The channel name
119  * @param messageType The message type
120  * @param partitionNumber The partition number
121  */
123  std::string messageType, int partitionNumber) {
124  setDefaults();
128  setPartitionProperty(partitionNumber);
129 }
130 
131 /**
132  * Returns the requested property value or null if the specified
133  * property name is not found.
134  *
135  * @param name The property name to look up
136  *
137  * @return The value that corresponds to the property name passed in,
138  * or an empty string if the property is not in the table.
139  */
141  property_sequence propertyList = this->property();
142  std::string value = "";
143 
144  for (int idx = 0; idx < (int) propertyList.size(); idx++) {
145  xsd::property propertyPair = propertyList[idx];
146  std::string propertyName = propertyPair.getName();
147  if (name == propertyName) {
148  value = propertyPair.getValue();
149  break;
150  }
151  }
152 
153  return value;
154 }
155 
156 /**
157  * Returns the requested property value or the specified default value
158  * null if the property name is not found.
159  *
160  * @param name The property name to look up
161  * @param defaultValue The value that will be returned if the property
162  * doesn't exist in the table.
163  *
164  * @return The value that corresponds to the property name passed in,
165  * if that property exists. This will return defaultValue otherwise.
166  */
168  std::string defaultValue) const {
169  std::string value = getProperty(name);
170 
171  return (value != "" ? value : defaultValue);
172 }
173 
174 /**
175  * Sets the named property to the specified value.
176  *
177  * @param name The property name that we're setting
178  * @param value The value that the property is being set to.
179  *
180  * @throws RmsRuntimeException If either the name or the value is
181  * an empty string.
182  */
184  bool found = false;
185 
186  // 02-Nov-2007, KAB - added conditions that inputs must be non-empty
187  if (name == "") {
188  std::string msg("Destination property names can not be empty.");
190  }
191  if (value == "") {
192  std::string msg("Destination property values can not be empty.");
194  }
195 
196  for (int idx = 0; idx < (int) this->getPropertyCount(); idx++) {
197  xsd::property& propertyPair = this->getPropertyReference(idx);
198  std::string propertyName = propertyPair.getName();
199  if (name == propertyName) {
200  propertyPair.setValue(value);
201  found = true;
202  break;
203  }
204  }
205 
206  if (found != true) {
207  xsd::property propertyPair;
208  propertyPair.setName(name);
209  propertyPair.setValue(value);
210  this->addProperty(propertyPair);
211  }
212 }
213 
214 /**
215  * Sets the partition property for this destination.
216  *
217  * @param partitionNumber The partition number
218  */
219 void RmsDestination::setPartitionProperty(int partitionNumber) {
220  char tempString[20];
221  snprintf(tempString, 20, "%d", partitionNumber);
223 }
224 
225 /**
226  * Test to see if another destination object has the
227  * same properties as this one.
228  *
229  * @param testObject The object we are testing to see
230  * if it matches this one.
231  *
232  * @return True if both destinations objects have the
233  * same properties and values, false otherwise.
234  */
235 bool RmsDestination::equals(const RmsDestination& testObject) const {
236  property_sequence thisPropertyList = this->property();
237  property_sequence thatPropertyList = testObject.property();
238 
239  // require the property list sizes to be the same
240  if (thatPropertyList.size() != thisPropertyList.size()) {
241  return false;
242  }
243 
244  // check that each property in this object matches one in the test object
245  for (int idx = 0; idx < (int) thisPropertyList.size(); idx++) {
246  xsd::property propertyPair = thisPropertyList[idx];
247  std::string thisName = propertyPair.getName();
248  std::string thisValue = this->getProperty(thisName);
249  std::string thatValue = testObject.getProperty(thisName);
250  if (thatValue == "" || thatValue != thisValue) {
251  return false;
252  }
253  }
254 
255  return true;
256 }
257 
258 /**
259  * Tests if the specified object matches this destination.
260  * In this case, "matching" means that the values for the
261  * properties that both destinations have in common are equal.
262  * Properties that are specified in only one destination are
263  * not considered in determining whether the destinations match.
264  * (So, if destination A has a "messageType" property and destination
265  * B does not, the this method acts as though destination B
266  * had a wildcard for the messageType property.)
267  *
268  * @param testObject The object that we are comparing this one with.
269  *
270  * @return True if the objects match, false otherwise.
271  */
272 bool RmsDestination::matches(const RmsDestination& testObject) const {
273  property_sequence thisPropertyList = this->property();
274  property_sequence thatPropertyList = testObject.property();
275 
276  // check that each property in this object matches one in the test object
277  for (int idx = 0; idx < (int) thisPropertyList.size(); idx++) {
278  xsd::property propertyPair = thisPropertyList[idx];
279  std::string thisName = propertyPair.getName();
280  std::string thisValue = this->getProperty(thisName);
281  std::string thatValue = testObject.getProperty(thisName);
282  if (thatValue != "" && thatValue != thisValue) {
283  return false;
284  }
285  }
286 
287  return true;
288 }
289 
290 /**
291  * Generate a string representation of this destination.
292  *
293  * @return A string representation of this destination.
294  */
296  std::string stringRep = "";
297 
298  property_sequence propertyList = this->property();
299  for (int idx = 0; idx < (int) propertyList.size(); idx++) {
300  xsd::property propertyPair = propertyList[idx];
301  if (idx > 0) {
302  stringRep.append(";");
303  }
304  stringRep.append(propertyPair.getName());
305  stringRep.append("=");
306  stringRep.append(propertyPair.getValue());
307  }
308 
309  return stringRep;
310 }
311 
312 /**
313  * Validates this destination. This consists of testing if
314  * required properties are set and verifying that mutually exclusive
315  * properties are not set.
316  *
317  * @throws RmsRuntimeException If the destination is invalid.
318  */
320  std::string exceptionText;
321  std::string targetPropertyValue = getProperty(TARGET_PROPERTY_NAME);
322  std::string sourcePropertyValue = getProperty(SOURCE_PROPERTY_NAME);
323  std::string channelPropertyValue = getProperty(CHANNEL_PROPERTY_NAME);
324  std::string partitionPropertyValue = getProperty(PARTITION_PROPERTY_NAME);
325 
326  // check for required properties
327  // --> as of 11-Oct-2007, these are
328  // A) target or source
329  // B) channel
330  // C) partition
331  if (targetPropertyValue == "" && sourcePropertyValue == "") {
332  if (exceptionText.size() > 0) {exceptionText.append("; ");}
333  exceptionText.append("either the " + TARGET_PROPERTY_NAME +
334  " property or the " + SOURCE_PROPERTY_NAME +
335  " property must be set");
336  }
337 
338  if (channelPropertyValue == "") {
339  if (exceptionText.size() > 0) {exceptionText.append("; ");}
340  exceptionText.append("the " + CHANNEL_PROPERTY_NAME +
341  " property must be set");
342  }
343 
344  if (partitionPropertyValue == "") {
345  if (exceptionText.size() > 0) {exceptionText.append("; ");}
346  exceptionText.append("the " + PARTITION_PROPERTY_NAME +
347  " property must be set");
348  }
349 
350  // check for mutually exclusive properties
351  // --> as of 26-Mar-2007, these are
352  // A) target and source
353  if (targetPropertyValue != "" && sourcePropertyValue != "") {
354  if (exceptionText.size() > 0) {exceptionText.append("; ");}
355  exceptionText.append("the " + TARGET_PROPERTY_NAME +
356  " property and the " + SOURCE_PROPERTY_NAME +
357  " property must not both be set");
358  }
359 
360  // throw an exception if one or more problems were found
361  if (exceptionText.size() != 0) {
362  exceptionText.insert(0, "Invalid RmsDestination " +
363  this->toString() + ": ");
364  exceptionText.append(".");
365  GENERATE_RMS_RUNTIME_EXCEPTION(exceptionText);
366  }
367 }
368 
369 /**
370  * Initializes the defaultEnvironment static attribute.
371  */
372 std::unique_ptr<std::string> RmsDestination::_defaultEnvironment;
373 
374 /**
375  * Sets the initial value for the static init done flag.
376  */
378 
379 /**
380  * Sets default values at construction time.
381  */
385 
386  std::string *envString =
387  new std::string(util::ReentrantGetEnv("RMS_CUSTOM_ENVIRONMENT"));
388 
389  if (*envString != "") {
390  boost::algorithm::trim(*envString);
391  if (envString->length() != 0) {
392  _defaultEnvironment.reset(envString);
393  }
394  }
395  else {
396  delete envString;
397  }
398  }
399 
400  if (_defaultEnvironment.get() != NULL) {
402  }
403 
406 }
407 
408 } // end of namespace base
409 
410 } // end of namespace rms
411 
412 } // end of namespace cd
413 
414 } // end of namespace fnal
415 
416 } // end of namespace gov
static const std::string DCM_APPNAME
const XML_Char * name
Definition: expat.h:151
const XML_Char * target
Definition: expat.h:268
static const std::string DAQAPP_MANAGER_APPNAME
static const std::string CONFIGURATION_CHANNEL
static const std::string RESOURCE_MANAGER_APPNAME
static const std::string SIMULATION_MANAGER_APPNAME
static const std::string PARTITION_PROPERTY_NAME
static const std::string SOURCE_PROPERTY_NAME
string trim(string in)
Definition: rootgINukeVal.C:65
static const std::string MONITOR_CHANNEL
static const std::string ALL_BNEVB_TARGET
const XML_Char int const XML_Char int const XML_Char * base
Definition: expat.h:331
static const std::string BNEVB_APPNAME
static const std::string HEARTBEAT_CHANNEL
static const std::string DAQ_MONITOR_APPNAME
static const std::string REPLY_MESSAGE_TYPE
static const std::string DAQDCS_CHANNEL
static const std::string SPILL_SERVER_APPNAME
bool matches(const RmsDestination &testObject) const
const XML_Char int const XML_Char * value
Definition: expat.h:331
static const std::string CONTROL_CHANNEL
static const std::string GLOBAL_TRIGGER_APPNAME
static const std::string CHANNEL_PROPERTY_NAME
static const std::string ALL_DCM_TARGET
static const std::string NOTIFICATION_MESSAGE_TYPE
static const std::string TDU_MANAGER_APPNAME
static const std::string DDT_MANAGER_APPNAME
Definition: fnal.py:1
static const std::string SERVICE_MANAGER_TARGET
#define GENERATE_RMS_RUNTIME_EXCEPTION(msg)
static const std::string STATUS_REPORT_CHANNEL
void setPartitionProperty(int partitionNumber)
static const std::string RUN_CONTROL_APPNAME
static const std::string ENVIRONMENT_PROPERTY_NAME
static const std::string REQUEST_MESSAGE_TYPE
static const std::string MESSAGE_ANALYZER_APPNAME
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void setProperty(std::string name, std::string value)
static const std::string CONFIG_MANAGER_APPNAME
static const std::string TARGET_PROPERTY_NAME
bool equals(const RmsDestination &testObject) const
static const std::string LOOPBACK_MESSAGE_TYPE
std::string getProperty(std::string name) const
static const std::string DATA_LOGGER_APPNAME
static const std::string ALERT_CHANNEL
static std::unique_ptr< std::string > _defaultEnvironment
static const std::string TRIGGER_CHANNEL
std::string ReentrantGetEnv(const std::string name)
c cd(1)
static const std::string DAQDCS_APPNAME
static const std::string MESSAGE_TYPE_PROPERTY_NAME
static const std::string ALL_ELEMENT_TARGET