tdaq-develop-2025-02-12
CorePropertySupervisorBase.cc
1 #include "otsdaq/CoreSupervisors/CorePropertySupervisorBase.h"
2 #include "otsdaq/MessageFacility/ITRACEController.h"
3 #include "otsdaq/MessageFacility/TRACEController.h"
4 
5 using namespace ots;
6 
8  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES =
10 
11 // clang-format off
12 //==============================================================================
13 CorePropertySupervisorBase::CorePropertySupervisorBase(xdaq::Application* application)
14  : theConfigurationManager_(0) // new ConfigurationManager)
15  , supervisorClass_(application->getApplicationDescriptor()->getClassName())
16  , supervisorClassNoNamespace_(
17  supervisorClass_.substr(supervisorClass_.find_last_of(":") + 1, supervisorClass_.length() - supervisorClass_.find_last_of(":")))
18  , supervisorContextUID_("UNINITIALIZED_supervisorContextUID") // MUST BE INITIALIZED INSIDE THE CONTRUCTOR TO THROW EXCEPTIONS on bad conditions
19  , supervisorApplicationUID_("UNINITIALIZED_supervisorApplicationUID") // MUST BE INITIALIZED INSIDE THE CONTRUCTOR TO THROW EXCEPTIONS on bad conditions
20  , supervisorConfigurationPath_("UNINITIALIZED_supervisorConfigurationPath") // MUST BE INITIALIZED INSIDE THE CONTRUCTOR TO THROW EXCEPTIONS on bad conditions
21  , propertiesAreSetup_(false)
22  , theTRACEController_(nullptr)
23 {
24  INIT_MF("." /*directory used is USER_DATA/LOG/.*/);
25 
26 
27 
28  __SUP_COUTV__(application->getApplicationContext()->getContextDescriptor()->getURL());
29  __SUP_COUTV__(application->getApplicationDescriptor()->getLocalId());
30  __SUP_COUTV__(supervisorClass_);
31  __SUP_COUTV__(supervisorClassNoNamespace_);
32 
33  // get all supervisor info, and wiz mode, macroMaker mode, or not
34  allSupervisorInfo_.init(application->getApplicationContext());
35 
36  if(allSupervisorInfo_.isMacroMakerMode())
37  {
38  theConfigurationManager_ = new ConfigurationManager(false /*initForWriteAccess*/, true /*initializeFromFhicl*/);
39  __SUP_COUT__ << "Macro Maker mode detected. So skipping configuration location work for "
40  "supervisor of class '"
41  << supervisorClass_ << "'" << __E__;
42 
43  supervisorContextUID_ = "MacroMakerFEContext";
44  supervisorApplicationUID_ = "MacroMakerFESupervisor";
45  supervisorConfigurationPath_ = CorePropertySupervisorBase::supervisorContextUID_ + "/LinkToApplicationTable/" +
46  CorePropertySupervisorBase::supervisorApplicationUID_ + "/LinkToSupervisorTable";
47 
48  __SUP_COUTV__(CorePropertySupervisorBase::supervisorContextUID_);
49  __SUP_COUTV__(CorePropertySupervisorBase::supervisorApplicationUID_);
50  __SUP_COUTV__(CorePropertySupervisorBase::supervisorConfigurationPath_);
51 
52  //move to after configure for MacroMaker mode
53  // CorePropertySupervisorBase::indicateOtsAlive(0);
54 
55  return;
56  }
57  else if(allSupervisorInfo_.isWizardMode())
58  {
59  __SUP_COUT__ << "Wiz mode detected. So skipping configuration location work for "
60  "supervisor of class '"
61  << supervisorClass_ << "'" << __E__;
62  supervisorContextUID_ = "NO CONTEXT ID IN WIZ MODE";
63  supervisorApplicationUID_ = std::to_string(application->getApplicationDescriptor()->getLocalId());
64  supervisorConfigurationPath_ = "NO APP PATH IN WIZ MODE";
65 
66  __SUP_COUTV__(CorePropertySupervisorBase::supervisorContextUID_);
67  __SUP_COUTV__(CorePropertySupervisorBase::supervisorApplicationUID_);
68  __SUP_COUTV__(CorePropertySupervisorBase::supervisorConfigurationPath_);
69 
70  return;
71  }
72 
73  __SUP_COUT__ << "Getting configuration specific info for supervisor '" << (allSupervisorInfo_.getSupervisorInfo(application).getName()) << "' of class "
74  << supervisorClass_ << "." << __E__;
75 
76  // get configuration specific info for the application supervisor
77 
78  try
79  {
80  __SUP_COUTV__(application->getApplicationContext()->getContextDescriptor()->getURL());
81  theConfigurationManager_ = new ConfigurationManager();
82  CorePropertySupervisorBase::supervisorContextUID_ =
83  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getContextUID(application->getApplicationContext()->getContextDescriptor()->getURL());
84  if(CorePropertySupervisorBase::supervisorContextUID_ == "")
85  {
86  __SUP_SS__ << "Illegal empty Supervisor Context UID identified. Please try again or contact admins." << __E__;
87  __SUP_SS_THROW__;
88  }
89  }
90  catch(...)
91  {
92  __SUP_COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through "
93  "the Configuration Manager."
94  << ". The getApplicationContext()->getContextDescriptor()->getURL() = "
95  << application->getApplicationContext()->getContextDescriptor()->getURL() << __E__;
96  throw;
97  }
98 
99  try
100  {
101  __SUP_COUTV__(application->getApplicationDescriptor()->getLocalId());
102  CorePropertySupervisorBase::supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
103  ->getApplicationUID(application->getApplicationContext()->getContextDescriptor()->getURL(),
104  application->getApplicationDescriptor()->getLocalId());
105  if(CorePropertySupervisorBase::supervisorApplicationUID_ == "")
106  {
107  __SUP_SS__ << "Illegal empty Supervisor Application UID identified. Please try again or contact admins." << __E__;
108  __SUP_SS_THROW__;
109  }
110  }
111  catch(...)
112  {
113  __SUP_COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through "
114  "the Configuration Manager."
115  << " The supervisorContextUID_ = " << supervisorContextUID_ << ". The supervisorApplicationUID = " << supervisorApplicationUID_
116  << __E__;
117  throw;
118  }
119 
120  CorePropertySupervisorBase::supervisorConfigurationPath_ = "/" + CorePropertySupervisorBase::supervisorContextUID_ + "/LinkToApplicationTable/" +
121  CorePropertySupervisorBase::supervisorApplicationUID_ + "/LinkToSupervisorTable";
122 
123  __SUP_COUTV__(CorePropertySupervisorBase::supervisorContextUID_);
124  __SUP_COUTV__(CorePropertySupervisorBase::supervisorApplicationUID_);
125  __SUP_COUTV__(CorePropertySupervisorBase::supervisorConfigurationPath_);
126 
127  //try to verify binding port for context was established
128  //All this code failed to do the trick
129  // {
130  // application->ptr_;
131 
132  // PeerTransportHTTP(this)
133  // const xdaq::NetGroup* netGroupPtr = application->getApplicationContext()->getNetGroup();
134  // auto netVector = netGroupPtr->getNetworks();
135  // __SUP_COUTV__(netVector.size());
136  // }
137 
138  CorePropertySupervisorBase::indicateOtsAlive(this);
139 
140  theConfigurationManager_->setOwnerContext(CorePropertySupervisorBase::supervisorContextUID_);
141  theConfigurationManager_->setOwnerApp(CorePropertySupervisorBase::supervisorApplicationUID_);
142 
143 } // end constructor
144 // clang-format on
145 
146 //==============================================================================
147 CorePropertySupervisorBase::~CorePropertySupervisorBase(void)
148 {
149  __SUP_COUT__ << "Destructor." << __E__;
150 
151  CorePropertySupervisorBase::indicateOtsDead(this);
152 
153  if(theConfigurationManager_)
154  delete theConfigurationManager_;
155 
157  {
158  __SUP_COUT__ << "Destroying TRACE Controller..." << __E__;
159  delete theTRACEController_;
160  theTRACEController_ = nullptr;
161  }
162  __SUP_COUT__ << "Destructed." << __E__;
163 } // end destructor
164 
165 //==============================================================================
166 void CorePropertySupervisorBase::indicateOtsAlive(
167  const CorePropertySupervisorBase* properties)
168 {
169  char portStr[100] = "0";
170  std::string hostname = "wiz";
171 
172  /* Note: the environment variable __ENV__("HOSTNAME")
173  // fails in multinode ots systems started through ssh
174  // because it will change meaning from host to host
175  */
176 
177  if(properties)
178  {
179  unsigned int port = properties->getContextTreeNode()
180  .getNode(properties->supervisorContextUID_)
181  .getNode("Port")
182  .getValue<unsigned int>();
183 
184  // help the user out if the config has old defaults for port/address
185  // Same as XDAQContextTable_table.cc:extractContexts:L164
186  if(port == 0) // convert 0 to ${OTS_MAIN_PORT}
187  port = atoi(__ENV__("OTS_MAIN_PORT"));
188 
189  sprintf(portStr, "%u", port);
190 
191  hostname = properties->getContextTreeNode()
192  .getNode(properties->supervisorContextUID_)
193  .getNode("Address")
194  .getValue<std::string>();
195  if(hostname == "DEFAULT") // convert DEFAULT to http://${HOSTNAME}
196  hostname = "http://" + std::string(__ENV__("HOSTNAME"));
197 
198  size_t i = hostname.find("//");
199  if(i != std::string::npos)
200  hostname = hostname.substr(i + 2);
201 
202  __COUTV__(hostname);
203  }
204 
205  // indicate ots is alive (for StartOTS.sh to verify launch was successful)
206  std::string filename = std::string(__ENV__("OTSDAQ_LOG_DIR")) + "/otsdaq_is_alive-" +
207  hostname + "-" + portStr + ".dat";
208  FILE* fp = fopen(filename.c_str(), "w");
209  if(!fp)
210  {
211  __SS__ << "Failed to open the ots-is-alive file: " << filename << __E__;
212  __SS_THROW__;
213  }
214  fprintf(fp, "%s %s %ld\n", hostname.c_str(), portStr, time(0));
215  fclose(fp);
216 
217  __COUT__ << "Marked alive: " << filename << __E__;
218 } // end indicateOtsAlive()
219 
220 //==============================================================================
221 void CorePropertySupervisorBase::indicateOtsDead(
222  const CorePropertySupervisorBase* properties)
223 {
224  char portStr[100] = "0";
225  std::string hostname = "wiz";
226 
227  /* Note: the environment variable __ENV__("HOSTNAME")
228  // fails in multinode ots systems started through ssh
229  // because it will change meaning from host to host
230  */
231 
232  if(properties)
233  {
234  unsigned int port = properties->getContextTreeNode()
235  .getNode(properties->supervisorContextUID_)
236  .getNode("Port")
237  .getValue<unsigned int>();
238 
239  // help the user out if the config has old defaults for port/address
240  // Same as XDAQContextTable_table.cc:extractContexts:L164
241  if(port == 0) // convert 0 to ${OTS_MAIN_PORT}
242  port = atoi(__ENV__("OTS_MAIN_PORT"));
243 
244  sprintf(portStr, "%u", port);
245 
246  hostname = properties->getContextTreeNode()
247  .getNode(properties->supervisorContextUID_)
248  .getNode("Address")
249  .getValue<std::string>();
250  if(hostname == "DEFAULT") // convert DEFAULT to http://${HOSTNAME}
251  hostname = "http://" + std::string(__ENV__("HOSTNAME"));
252 
253  size_t i = hostname.find("//");
254  if(i != std::string::npos)
255  hostname = hostname.substr(i + 2);
256 
257  __COUTV__(hostname);
258  }
259 
260  // indicate ots is dead (for StartOTS.sh to verify launch was successful)
261  std::string filename = std::string(__ENV__("OTSDAQ_LOG_DIR")) + "/otsdaq_is_alive-" +
262  hostname + "-" + portStr + ".dat";
263  FILE* fp = fopen(filename.c_str(), "w");
264  if(!fp)
265  {
266  __SS__ << "Failed to open the ots-is-alive file: " << filename << __E__;
267  __SS_THROW__;
268  }
269  fclose(fp);
270 
271  __COUT__ << "Marked dead: " << filename << __E__;
272 } // end indicateOtsDead()
273 
274 //==============================================================================
276 XDAQ_CONST_CALL xdaq::ApplicationDescriptor*
278 {
279  if(allSupervisorInfo_.isMacroMakerMode())
280  return 0;
281 
282  return allSupervisorInfo_.isWizardMode() ? allSupervisorInfo_.getWizardDescriptor()
283  : allSupervisorInfo_.getGatewayDescriptor();
284 } // end getGatewaySupervisorDescriptor()
285 
286 //==============================================================================
291 {
292  // This can be done in the constructor because when you start xdaq it loads the
293  // configuration that can't be changed while running!
294 
295  //__SUP_COUT__ << "Setting up Core Supervisor Base property defaults for supervisor"
296  //<<
297  // "..." << __E__;
298 
299  // set core Supervisor base class defaults
300  CorePropertySupervisorBase::setSupervisorProperty(
301  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
302  "*=1");
303  CorePropertySupervisorBase::setSupervisorProperty(
304  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserGroupsAllowed, "");
305  CorePropertySupervisorBase::setSupervisorProperty(
306  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserGroupsDisallowed, "");
307 
308  CorePropertySupervisorBase::setSupervisorProperty(
309  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes, "");
310  CorePropertySupervisorBase::setSupervisorProperty(
311  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
312  "");
313  CorePropertySupervisorBase::setSupervisorProperty(
314  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes, "");
315  CorePropertySupervisorBase::setSupervisorProperty(
316  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes, "");
317  CorePropertySupervisorBase::setSupervisorProperty(
318  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireSecurityRequestTypes,
319  "");
320 
321  CorePropertySupervisorBase::setSupervisorProperty(
322  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NoXmlWhiteSpaceRequestTypes,
323  "");
324  CorePropertySupervisorBase::setSupervisorProperty(
325  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NonXMLRequestTypes, "");
326 
327  // __SUP_COUT__ << "Done setting up Core Supervisor Base property defaults for
328  // supervisor" <<
329  // "..." << __E__;
330 } // end setSupervisorPropertyDefaults()
331 
332 //==============================================================================
348  const std::string& permissionsString,
349  std::map<std::string, WebUsers::permissionLevel_t>& permissionsMap)
350 {
351  permissionsMap.clear();
352  StringMacros::getMapFromString(permissionsString, permissionsMap);
353  if(permissionsMap.size() == 0) // do not allow empty permissions map
354  permissionsMap.emplace(std::pair<std::string, WebUsers::permissionLevel_t>(
355  WebUsers::DEFAULT_USER_GROUP,
356  atoi(permissionsString.c_str())) // convert to integer
357  );
358 } // end extractPermissionsMapFromString()
359 
360 //==============================================================================
379  std::map<std::string, WebUsers::permissionLevel_t>& permissionLevelsMap,
380  std::map<std::string, WebUsers::permissionLevel_t>& permissionThresholdsMap)
381 {
382  // return true if a permission level group name is found with a permission level
383  // greater than or equal to the permission level at a matching group name entry in
384  // the thresholds map.
385 
386  //__COUTV__(StringMacros::mapToString(permissionLevelsMap));
387  //__COUTV__(StringMacros::mapToString(permissionThresholdsMap));
388 
389  for(const auto& permissionLevelGroupPair : permissionLevelsMap)
390  {
391  //__COUTV__(permissionLevelGroupPair.first);
392  //__COUTV__(permissionLevelGroupPair.second);
393 
394  for(const auto& permissionThresholdGroupPair : permissionThresholdsMap)
395  {
396  //__COUTV__(permissionThresholdGroupPair.first);
397  //__COUTV__(permissionThresholdGroupPair.second);
398  if(permissionLevelGroupPair.first == permissionThresholdGroupPair.first &&
399  permissionThresholdGroupPair.second && // not explicitly disallowed
400  permissionLevelGroupPair.second >= permissionThresholdGroupPair.second)
401  return true; // access granted!
402  }
403  }
404  //__COUT__ << "Denied." << __E__;
405 
406  // if here, no access group match found
407  // so denied
408  return false;
409 } // end doPermissionsGrantAccess()
410 
411 //==============================================================================
412 void CorePropertySupervisorBase::checkSupervisorPropertySetup()
413 {
414  if(propertiesAreSetup_)
415  return;
416 
417  // Immediately mark properties as setup, (prevent infinite loops due to
418  // other launches from within this function, e.g. from getSupervisorProperty)
419  // only redo if Context configuration group changes
420  propertiesAreSetup_ = true;
421 
422  __SUP_COUTT__ << "Setting up supervisor specific property DEFAULTS for supervisor..."
423  << __E__;
424 
426  // version defaults
427 
428  setSupervisorPropertyDefaults(); // calls override version defaults
429 
430  __SUP_COUTT__
431  << "Done setting up supervisor specific property DEFAULTS for supervisor."
432  << __E__;
433 
434  if(allSupervisorInfo_.isWizardMode())
435  __SUP_COUT__ << "Wiz mode detected. Skipping setup of supervisor properties for "
436  "supervisor of class '"
437  << supervisorClass_ << "'" << __E__;
438  else if(allSupervisorInfo_.isMacroMakerMode())
439  __SUP_COUT__
440  << "Maker Maker mode detected. Skipping setup of supervisor properties for "
441  "supervisor of class '"
442  << supervisorClass_ << "'" << __E__;
443  else
445  // settings from
446  // configuration
447 
448  readOnly_ = getSupervisorProperty("ReadOnly", "0") == "1" ? true : false;
449  __SUP_COUTV__(readOnly_);
450 
451  //__SUP_COUT__ << "Setting up supervisor specific FORCED properties for supervisor..."
452  //<< __E__;
453  forceSupervisorPropertyValues(); // calls override forced values
454  // __SUP_COUT__ << "Done setting up supervisor
455  // specific FORCED properties for supervisor" <<
456  // "." << __E__;
457 
459  getSupervisorProperty(
460  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold),
461  propertyStruct_.UserPermissionsThreshold);
462 
463  propertyStruct_.UserGroupsAllowed.clear();
465  getSupervisorProperty(
466  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserGroupsAllowed),
467  propertyStruct_.UserGroupsAllowed);
468 
469  propertyStruct_.UserGroupsDisallowed.clear();
471  getSupervisorProperty(
472  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserGroupsDisallowed),
473  propertyStruct_.UserGroupsDisallowed);
474 
475  auto nameIt = SUPERVISOR_PROPERTIES.allSetNames_.begin();
476  auto setIt = propertyStruct_.allSets_.begin();
477  while(nameIt != SUPERVISOR_PROPERTIES.allSetNames_.end() &&
478  setIt != propertyStruct_.allSets_.end())
479  {
480  (*setIt)->clear();
481  StringMacros::getSetFromString(getSupervisorProperty(*(*nameIt)), *(*setIt));
482 
483  ++nameIt;
484  ++setIt;
485  }
486 
487  __SUP_COUT__ << "Final supervisor property settings:" << __E__;
488  for(auto& property : propertyMap_)
489  __SUP_COUT__ << "\t" << property.first << " = " << property.second << __E__;
490 } // end checkSupervisorPropertySetup()
491 
492 //==============================================================================
496 try
497 {
498  if(supervisorContextUID_ == "" || supervisorApplicationUID_ == "")
499  {
500  __SUP_SS__ << "Empty supervisorContextUID_ or supervisorApplicationUID_."
501  << __E__;
502  __SUP_SS_THROW__;
503  }
504  return theConfigurationManager_->getSupervisorNode(supervisorContextUID_,
505  supervisorApplicationUID_);
506 } // end getSupervisorTreeNode()
507 catch(...)
508 {
509  __SUP_COUT_ERR__
510  << "XDAQ Supervisor could not access it's configuration node through "
511  "theConfigurationManager_ "
512  << "(Did you remember to initialize using CorePropertySupervisorBase::init()?)."
513  << " The supervisorContextUID_ = " << supervisorContextUID_
514  << ". The supervisorApplicationUID = " << supervisorApplicationUID_ << __E__;
515  throw;
516 } // end getSupervisorTreeNode() exception handling
517 
518 //==============================================================================
522 {
523  // __SUP_COUT__ << "Loading user properties for supervisor '" <<
524  // supervisorContextUID_ << "/" << supervisorApplicationUID_ <<
525  // "'..." << __E__;
526 
527  // re-acquire the configuration supervisor node, in case the config has changed
529 
530  try
531  {
532  auto /*map<name,node>*/ children =
533  supervisorNode.getNode("LinkToPropertyTable").getChildren();
534 
535  for(auto& child : children)
536  {
537  if(!child.second.status())
538  continue; // skip OFF properties
539 
540  auto propertyName = child.second.getNode("PropertyName").getValue();
541  setSupervisorProperty(
542  propertyName,
543  child.second.getNode("PropertyValue").getValue<std::string>());
544  }
545  }
546  catch(...)
547  {
548  __SUP_COUT__ << "No user supervisor property settings found in the configuration "
549  "tree, going with the defaults."
550  << __E__;
551  }
552 
553  // __SUP_COUT__ << "Done loading user properties for supervisor '" <<
554  // supervisorContextUID_ << "/" << supervisorApplicationUID_ <<
555  // "'" << __E__;
556 } // end loadUserSupervisorProperties()
557 
558 //==============================================================================
559 void CorePropertySupervisorBase::setSupervisorProperty(const std::string& propertyName,
560  const std::string& propertyValue)
561 {
562  propertyMap_[propertyName] = propertyValue;
563  // __SUP_COUT__ << "Set propertyMap_[" << propertyName <<
564  // "] = " << propertyMap_[propertyName] << __E__;
565 } // end setSupervisorProperty()
566 
567 //==============================================================================
568 void CorePropertySupervisorBase::addSupervisorProperty(const std::string& propertyName,
569  const std::string& propertyValue)
570 {
571  propertyMap_[propertyName] =
572  propertyValue + " | " + getSupervisorProperty(propertyName);
573  // __SUP_COUT__ << "Set propertyMap_[" << propertyName <<
574  // "] = " << propertyMap_[propertyName] << __E__;
575 } // end addSupervisorProperty()
576 
577 //==============================================================================
580 std::string CorePropertySupervisorBase::getSupervisorProperty(
581  const std::string& propertyName)
582 {
583  // check if need to setup properties
584  checkSupervisorPropertySetup();
585 
586  auto it = propertyMap_.find(propertyName);
587  if(it == propertyMap_.end())
588  {
589  __SUP_SS__ << "Could not find property named " << propertyName << __E__;
590  __SS_THROW__; //__SUP_SS_THROW__;
591  }
593 } // end getSupervisorProperty()
594 
595 //==============================================================================
597 std::string CorePropertySupervisorBase::getSupervisorProperty(
598  const std::string& propertyName, const std::string& defaultValue)
599 {
600  // check if need to setup properties
601  checkSupervisorPropertySetup();
602 
603  auto it = propertyMap_.find(propertyName);
604  if(it == propertyMap_.end())
605  {
606  // not found, so returning default value
607  return defaultValue;
608  }
610 } // end getSupervisorProperty()
611 
612 //==============================================================================
615 WebUsers::permissionLevel_t
617  const std::string& requestType)
618 {
619  // check if need to setup properties
620  checkSupervisorPropertySetup();
621 
623  requestType, propertyStruct_.UserPermissionsThreshold);
624 } // end getSupervisorPropertyUserPermissionsThreshold()
625 
626 //==============================================================================
630 {
631  checkSupervisorPropertySetup();
632 
633  __SUP_COUT_TYPE__(TLVL_DEBUG + 20)
634  << __COUT_HDR__ << "userInfo.requestType_ " << userInfo.requestType_ << __E__;
635 
636  __SUP_COUT_TYPE__(TLVL_DEBUG + 20)
637  << __COUT_HDR__ << "propertyStruct_.AutomatedRequestTypes "
638  << StringMacros::setToString(propertyStruct_.AutomatedRequestTypes) << __E__;
639  userInfo.automatedCommand_ = StringMacros::inWildCardSet(
640  userInfo.requestType_,
641  propertyStruct_.AutomatedRequestTypes); // automatic commands should not refresh
642  // cookie code.. only user initiated
643  // commands should!
644 
645  __SUP_COUT_TYPE__(TLVL_DEBUG + 21)
646  << __COUT_HDR__ << "propertyStruct_.NonXMLRequestTypes "
647  << StringMacros::setToString(propertyStruct_.NonXMLRequestTypes) << __E__;
648  userInfo.NonXMLRequestType_ = StringMacros::inWildCardSet(
649  userInfo.requestType_, propertyStruct_.NonXMLRequestTypes); // non-xml request
650  // types just return
651  // the request return
652  // string to client
653 
654  __SUP_COUT_TYPE__(TLVL_DEBUG + 21)
655  << __COUT_HDR__ << "propertyStruct_.NoXmlWhiteSpaceRequestTypes "
656  << StringMacros::setToString(propertyStruct_.NoXmlWhiteSpaceRequestTypes)
657  << __E__;
658  userInfo.NoXmlWhiteSpace_ = StringMacros::inWildCardSet(
659  userInfo.requestType_, propertyStruct_.NoXmlWhiteSpaceRequestTypes);
660 
661  //**** start LOGIN GATEWAY CODE ***//
662  // check cookieCode, sequence, userWithLock, and permissions access all in one shot!
663  {
664  __SUP_COUT_TYPE__(TLVL_DEBUG + 20)
665  << __COUT_HDR__ << "propertyStruct_.CheckUserLockRequestTypes "
666  << StringMacros::setToString(propertyStruct_.CheckUserLockRequestTypes)
667  << __E__;
668  userInfo.checkLock_ = StringMacros::inWildCardSet(
669  userInfo.requestType_, propertyStruct_.CheckUserLockRequestTypes);
670  __SUP_COUT_TYPE__(TLVL_DEBUG + 20)
671  << __COUT_HDR__ << "propertyStruct_.RequireUserLockRequestTypes "
672  << StringMacros::setToString(propertyStruct_.RequireUserLockRequestTypes)
673  << __E__;
674  userInfo.requireLock_ = StringMacros::inWildCardSet(
675  userInfo.requestType_, propertyStruct_.RequireUserLockRequestTypes);
676  if(userInfo.requireLock_ && userInfo.automatedCommand_)
677  {
678  __SUP_COUTT__ << "Overriding requireLock_ because request '"
679  << userInfo.requestType_ << "' marked as automatedCommand_"
680  << __E__;
681  userInfo.requireLock_ = false;
682  }
683 
684  __SUP_COUT_TYPE__(TLVL_DEBUG + 21)
685  << __COUT_HDR__ << "propertyStruct_.AllowNoLoginRequestTypes "
686  << StringMacros::setToString(propertyStruct_.AllowNoLoginRequestTypes)
687  << __E__;
688  userInfo.allowNoUser_ = StringMacros::inWildCardSet(
689  userInfo.requestType_, propertyStruct_.AllowNoLoginRequestTypes);
690  __SUP_COUT_TYPE__(TLVL_DEBUG + 21)
691  << __COUT_HDR__ << "propertyStruct_.RequireSecurityRequestTypes "
692  << StringMacros::setToString(propertyStruct_.RequireSecurityRequestTypes)
693  << __E__;
694  userInfo.requireSecurity_ = StringMacros::inWildCardSet(
695  userInfo.requestType_, propertyStruct_.RequireSecurityRequestTypes);
696 
697  userInfo.permissionsThreshold_ = -1; // default to max
698  try
699  {
700  userInfo.permissionsThreshold_ =
702  userInfo.requestType_);
703  }
704  catch(std::runtime_error& e)
705  {
706  if(!userInfo.automatedCommand_)
707  __SUP_COUT__ << "No explicit permissions threshold for request '"
708  << userInfo.requestType_
709  << "'... Defaulting to max threshold = "
710  << (unsigned int)userInfo.permissionsThreshold_ << __E__;
711  }
712 
713  __SUP_COUTVS__(20, userInfo.requestType_);
714  __SUP_COUTVS__(20, userInfo.checkLock_);
715  __SUP_COUTVS__(20, userInfo.requireLock_);
716  __SUP_COUTVS__(20, userInfo.allowNoUser_);
717  __SUP_COUTVS__(20, userInfo.automatedCommand_);
718  __SUP_COUTVS__(20, userInfo.automatedCommand_);
719  __SUP_COUTVS__(20, (unsigned int)userInfo.permissionsThreshold_);
720 
721  try
722  {
724  StringMacros::getWildCardMatchFromMap(userInfo.requestType_,
725  propertyStruct_.UserGroupsAllowed),
726  userInfo.groupsAllowed_);
727  }
728  catch(std::runtime_error& e)
729  {
730  userInfo.groupsAllowed_.clear();
731  if(!userInfo.automatedCommand_)
732  __SUP_COUT_TYPE__(TLVL_DEBUG + 25)
733  << __COUT_HDR__ << "No explicit groups allowed for request '"
734  << userInfo.requestType_
735  << "'... Defaulting to empty groups allowed. " << __E__;
736  }
737  try
738  {
741  userInfo.requestType_, propertyStruct_.UserGroupsDisallowed),
742  userInfo.groupsDisallowed_);
743  }
744  catch(std::runtime_error& e)
745  {
746  userInfo.groupsDisallowed_.clear();
747 
748  if(!userInfo.automatedCommand_)
749  __SUP_COUT_TYPE__(TLVL_DEBUG + 25)
750  << __COUT_HDR__ << "No explicit groups disallowed for request '"
751  << userInfo.requestType_
752  << "'... Defaulting to empty groups disallowed. " << __E__;
753  }
754  } //**** end LOGIN GATEWAY CODE ***//
755 
756  // completed user info, for the request type, is returned to caller
757 } // end getRequestUserInfo()
758 
759 //==============================================================================
760 xoap::MessageReference CorePropertySupervisorBase::TRACESupervisorRequest(
761  xoap::MessageReference message)
762 {
763  __SUP_COUT__ << "$$$$$$$$$$$$$$$$$" << __E__;
764 
765  // receive request parameters
766  SOAPParameters parameters;
767  parameters.addParameter("Request");
768 
769  __SUP_COUT__ << "Received TRACE message: " << SOAPUtilities::translate(message)
770  << __E__;
771 
772  SOAPUtilities::receive(message, parameters);
773  std::string request = parameters.getValue("Request");
774 
775  __SUP_COUT__ << "request: " << request << __E__;
776 
777  // request types:
778  // GetTraceLevels
779  // SetTraceLevels
780 
781  SOAPParameters retParameters;
782  try
783  {
784  if(request == "GetTraceLevels")
785  {
786  retParameters.addParameter("TRACEList", getTraceLevels());
787  retParameters.addParameter("TRACEHostnameList", traceReturnHostString_);
788  return SOAPUtilities::makeSOAPMessageReference(
789  supervisorClassNoNamespace_ + "Response", retParameters);
790  }
791  else if(request == "SetTraceLevels")
792  {
793  parameters.addParameter("IndividualValues");
794  parameters.addParameter("Host");
795  parameters.addParameter("SetMode");
796  parameters.addParameter("Labels");
797  parameters.addParameter("SetValueMSB");
798  parameters.addParameter("SetValueLSB");
799  SOAPUtilities::receive(message, parameters);
800 
801  int individualValues = parameters.getValueAsInt("IndividualValues");
802  std::string host = parameters.getValue("Host");
803  std::string setMode = parameters.getValue("SetMode");
804  std::string labelsStr = parameters.getValue("Labels");
805  int setValueMSB = parameters.getValueAsInt("SetValueMSB");
806  int setValueLSB = parameters.getValueAsInt("SetValueLSB");
807  __SUP_COUTV__(individualValues);
808  __SUP_COUTV__(host);
809  __SUP_COUTV__(setMode);
810  __SUP_COUTV__(setValueMSB);
811  __SUP_COUTV__(setValueLSB);
812  __SUP_COUTV__(labelsStr);
813 
814  if(individualValues)
815  retParameters.addParameter(
816  "TRACEList", setIndividualTraceLevels(host, setMode, labelsStr));
817  else
818  retParameters.addParameter(
819  "TRACEList",
820  setTraceLevels(host, setMode, labelsStr, setValueMSB, setValueLSB));
821  return SOAPUtilities::makeSOAPMessageReference(
822  supervisorClassNoNamespace_ + "Response", retParameters);
823  }
824  else if(request == "GetTriggerStatus")
825  {
826  retParameters.addParameter("TRACETriggerStatus", getTraceTriggerStatus());
827  return SOAPUtilities::makeSOAPMessageReference(
828  supervisorClassNoNamespace_ + "Response", retParameters);
829  }
830  else if(request == "SetTriggerEnable")
831  {
832  parameters.addParameter("Host");
833  parameters.addParameter("EntriesAfterTrigger");
834  SOAPUtilities::receive(message, parameters);
835 
836  std::string host = parameters.getValue("Host");
837  int entriesAfterTrigger = parameters.getValueAsInt("EntriesAfterTrigger");
838  __SUP_COUTV__(host);
839  __SUP_COUTV__(entriesAfterTrigger);
840  retParameters.addParameter("TRACETriggerStatus",
841  setTraceTriggerEnable(host, entriesAfterTrigger));
842  return SOAPUtilities::makeSOAPMessageReference(
843  supervisorClassNoNamespace_ + "Response", retParameters);
844  }
845  else if(request == "ResetTRACE")
846  {
847  parameters.addParameter("Host");
848  SOAPUtilities::receive(message, parameters);
849 
850  std::string host = parameters.getValue("Host");
851  __SUP_COUTV__(host);
852  retParameters.addParameter("TRACETriggerStatus", resetTRACE(host));
853  return SOAPUtilities::makeSOAPMessageReference(
854  supervisorClassNoNamespace_ + "Response", retParameters);
855  }
856  else if(request == "EnableTRACE")
857  {
858  parameters.addParameter("Host");
859  parameters.addParameter("SetEnable");
860  SOAPUtilities::receive(message, parameters);
861 
862  std::string host = parameters.getValue("Host");
863  bool enable = parameters.getValueAsInt("SetEnable") ? true : false;
864  __SUP_COUTV__(host);
865  __SUP_COUTV__(enable);
866 
867  retParameters.addParameter("TRACETriggerStatus", enableTRACE(host, enable));
868  return SOAPUtilities::makeSOAPMessageReference(
869  supervisorClassNoNamespace_ + "Response", retParameters);
870  }
871  else if(request == "GetSnapshot")
872  {
873  parameters.addParameter("Host");
874  parameters.addParameter("FilterForCSV");
875  parameters.addParameter("FilterOutCSV");
876  SOAPUtilities::receive(message, parameters);
877 
878  std::string host = parameters.getValue("Host");
879  std::string filterFor = parameters.getValue("FilterForCSV");
880  std::string filterOut = parameters.getValue("FilterOutCSV");
881  __SUP_COUTV__(host);
882  __SUP_COUTV__(filterFor);
883  __SUP_COUTV__(filterOut);
884  retParameters.addParameter("TRACESnapshot",
885  getTraceSnapshot(host, filterFor, filterOut));
886  retParameters.addParameter("TRACETriggerStatus", getTraceTriggerStatus());
887  return SOAPUtilities::makeSOAPMessageReference(
888  supervisorClassNoNamespace_ + "Response", retParameters);
889  }
890  else
891  {
892  __SUP_SS__ << "Unrecognized request received! '" << request << "'" << __E__;
893  __SUP_SS_THROW__;
894  }
895  }
896  catch(const std::runtime_error& e)
897  {
898  __SUP_SS__ << "Error occurred handling request: " << e.what() << __E__;
899  __SUP_COUT_ERR__ << ss.str();
900  retParameters.addParameter("Error", ss.str());
901  }
902  catch(...)
903  {
904  __SUP_SS__ << "Error occurred handling request." << __E__;
905  try
906  {
907  throw;
908  } //one more try to printout extra info
909  catch(const std::exception& e)
910  {
911  ss << "Exception message: " << e.what();
912  }
913  catch(...)
914  {
915  }
916  __SUP_COUT_ERR__ << ss.str();
917  retParameters.addParameter("Error", ss.str());
918  }
919 
920  return SOAPUtilities::makeSOAPMessageReference("TRACEFault", retParameters);
921 
922 } // end TRACESupervisorRequest()
923 
924 //==============================================================================
925 const std::string& CorePropertySupervisorBase::getTraceLevels()
926 {
927  __SUP_COUT__ << "getTraceLevels()" << __E__;
928 
929  traceReturnString_ = ""; // reset;
930  traceReturnHostString_ = ""; // reset;
931 
933  {
934  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
936  }
937 
938  // typedef std::unordered_map<std::string, TraceLevelMap> HostTraceLevelMap =
939  ITRACEController::HostTraceLevelMap traceHostMap =
941  for(const auto& traceMap : traceHostMap)
942  {
943  //__COUTV__(traceMap.first);
944 
945  // NOTE: TRACE hostname resolution is not necessarily the same as xdaq context name resolution
946  // so return TRACE hostname resolution so a map can be generated at the controller
947 
948  traceReturnHostString_ = ";" + traceMap.first;
949  traceReturnString_ += ";" + traceMap.first;
950 
951  for(const auto& traceMask : traceMap.second)
952  {
953  //__COUTV__(traceMask.first);
954  //__COUTV__(traceMask.second);
955  // give in 32b chunks since javascript is 32-bit
956  traceReturnString_ +=
957  "," + traceMask.first +
958  ",M:" + std::to_string((unsigned int)(traceMask.second.M >> 32)) + ":" +
959  std::to_string((unsigned int)traceMask.second.M) +
960  ":S:" + std::to_string((unsigned int)(traceMask.second.S >> 32)) + ":" +
961  std::to_string((unsigned int)traceMask.second.S) +
962  ":T:" + std::to_string((unsigned int)(traceMask.second.T >> 32)) + ":" +
963  std::to_string((unsigned int)traceMask.second.T);
964  } // end label loop
965  } // end host loop
966  __SUP_COUT__ << "end getTraceLevels()" << __E__;
967  return traceReturnString_;
968 } // end getTraceLevels()
969 
970 //==============================================================================
971 const std::string& CorePropertySupervisorBase::setTraceLevels(
972  std::string const& host,
973  std::string const& mode,
974  std::string const& labelsStr,
975  uint32_t setValueMSB,
976  uint32_t setValueLSB)
977 {
978  __SUP_COUT__ << "setTraceLevels()" << __E__;
979 
981  {
982  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
984  }
985 
987  bool allMode = mode == "ALL";
988  if(allMode || mode == "FAST")
989  setMask.M = ((uint64_t(setValueMSB)) << 32) | (uint64_t(uint32_t(setValueLSB)));
990  if(allMode || mode == "SLOW")
991  setMask.S = ((uint64_t(setValueMSB)) << 32) | (uint64_t(uint32_t(setValueLSB)));
992  if(allMode || mode == "TRIGGER")
993  setMask.T = ((uint64_t(setValueMSB)) << 32) | (uint64_t(uint32_t(setValueLSB)));
994 
995  std::vector<std::string /*labels*/> labels;
996  StringMacros::getVectorFromString(labelsStr, labels, {','});
997  for(const auto& label : labels)
998  {
999  __SUP_COUTV__(label);
1000  theTRACEController_->setTraceLevelMask(label, setMask, host, mode);
1001  }
1002 
1003  __SUP_COUT__ << "end setTraceLevels()" << __E__;
1004  return getTraceLevels();
1005 } // end setTraceLevels()
1006 
1007 //==============================================================================
1008 const std::string& CorePropertySupervisorBase::setIndividualTraceLevels(
1009  std::string const& host, std::string const& mode, std::string const& labelValuesStr)
1010 {
1011  __SUP_COUT__ << "setIndividualTraceLevels()" << __E__;
1012 
1013  if(!theTRACEController_)
1014  {
1015  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1017  }
1018 
1020  bool allMode = mode == "ALL";
1021  bool fastMode = mode == "FAST";
1022  bool slowMode = mode == "SLOW";
1023  bool triggerMode = mode == "TRIGGER";
1024 
1025  std::vector<std::string /*labels,msb,lsb*/> labelValues;
1026  StringMacros::getVectorFromString(labelValuesStr, labelValues, {','});
1027  for(unsigned int i = 0; i < labelValues.size(); i += 3 /*label,msb,lsb*/)
1028  {
1029  __SUP_COUT__ << "Label = " << labelValues[i] << " msb/lsb " << labelValues[i + 1]
1030  << "/" << labelValues[i + 2] << __E__;
1031 
1032  if(allMode || fastMode)
1033  setMask.M = ((uint64_t(atoi(labelValues[i + 1].c_str()))) << 32) |
1034  (uint64_t(uint32_t(atoi(labelValues[i + 2].c_str()))));
1035  if(allMode || slowMode)
1036  setMask.S = ((uint64_t(atoi(labelValues[i + 1].c_str()))) << 32) |
1037  (uint64_t(uint32_t(atoi(labelValues[i + 2].c_str()))));
1038  if(allMode || triggerMode)
1039  setMask.T = ((uint64_t(atoi(labelValues[i + 1].c_str()))) << 32) |
1040  (uint64_t(uint32_t(atoi(labelValues[i + 2].c_str()))));
1041 
1042  theTRACEController_->setTraceLevelMask(labelValues[i], setMask, host, mode);
1043  }
1044 
1045  __SUP_COUT__ << "end setIndividualTraceLevels()" << __E__;
1046  return getTraceLevels();
1047 } // end setTraceLevels()
1048 
1049 //==============================================================================
1050 const std::string& CorePropertySupervisorBase::getTraceTriggerStatus()
1051 {
1052  __SUP_COUT__ << "getTraceTriggerStatus()" << __E__;
1053 
1054  traceReturnString_ = ""; // reset;
1055 
1056  if(!theTRACEController_)
1057  {
1058  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1060  }
1061 
1062  bool isTriggered = theTRACEController_->getIsTriggered();
1063  traceReturnString_ +=
1064  ";" + theTRACEController_->getHostnameString() + "," + (isTriggered ? "1" : "0");
1065 
1066  __SUP_COUT__ << "end getTraceTriggerStatus() " << traceReturnString_ << __E__;
1067  return traceReturnString_;
1068 } // end getTraceTriggerStatus()
1069 
1070 //==============================================================================
1071 const std::string& CorePropertySupervisorBase::setTraceTriggerEnable(
1072  std::string const& host, size_t entriesAfterTrigger)
1073 {
1074  __SUP_COUT__ << "setTraceTriggerEnable() " << host << __E__;
1075 
1076  if(!theTRACEController_)
1077  {
1078  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1080  }
1081  theTRACEController_->setTriggerEnable(entriesAfterTrigger);
1082  __SUP_COUT__ << "end setTraceTriggerEnable()" << __E__;
1083  return getTraceTriggerStatus();
1084 } // end setTraceTriggerEnable()
1085 
1086 //==============================================================================
1087 const std::string& CorePropertySupervisorBase::resetTRACE(std::string const& host)
1088 {
1089  __SUP_COUT__ << "resetTRACE() " << host << __E__;
1090 
1091  if(!theTRACEController_)
1092  {
1093  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1095  }
1098  __SUP_COUT__ << "end resetTRACE()" << __E__;
1099  return getTraceTriggerStatus();
1100 } // end resetTRACE()
1101 
1102 //==============================================================================
1103 const std::string& CorePropertySupervisorBase::enableTRACE(std::string const& host,
1104  bool enable)
1105 {
1106  __SUP_COUT__ << "enableTRACE() " << host << " " << enable << __E__;
1107 
1108  if(!theTRACEController_)
1109  {
1110  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1112  }
1114  __SUP_COUT__ << "end enableTRACE()" << __E__;
1115  return getTraceTriggerStatus();
1116 } // end enableTRACE()
1117 
1118 //==============================================================================
1119 const std::string& CorePropertySupervisorBase::getTraceSnapshot(
1120  std::string const& host, std::string const& filterFor, std::string const& filterOut)
1121 {
1122  __SUP_COUT__ << "getTraceSnapshot()" << host << __E__;
1123 
1124  traceReturnString_ = ""; // reset;
1125 
1126  if(!theTRACEController_)
1127  {
1128  __SUP_COUT__ << "No TRACE Controller found, constructing!" << __E__;
1130  }
1131 
1132  traceReturnString_ = theTRACEController_->getTraceBufferDump(filterFor, filterOut);
1133  // std::cout << traceReturnString_ << __E__;
1134 
1135  const size_t MAX_SZ = 200000;
1136  if(traceReturnString_.size() > MAX_SZ)
1137  {
1138  __SUP_COUT__ << "Truncating from " << traceReturnString_.size() << " to "
1139  << MAX_SZ << __E__;
1140  traceReturnString_.resize(MAX_SZ);
1141  traceReturnString_ += "\n...TRUNCATED";
1142  }
1143  else if(traceReturnString_.size() == 0)
1144  {
1145  __SUP_COUT__ << "Empty snapshot" << __E__;
1146  traceReturnString_ = "Empty TRACE snapshot.";
1147  }
1148  __SUP_COUT__ << "end getTraceSnapshot() Bytes = " << traceReturnString_.size()
1149  << __E__;
1150  return traceReturnString_;
1151 } // end getTraceSnapshot()
bool isWizardMode(void) const
BOOLs.
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
void getValue(T &value) const
static void extractPermissionsMapFromString(const std::string &permissionsString, std::map< std::string, WebUsers::permissionLevel_t > &permissionsMap)
static bool doPermissionsGrantAccess(std::map< std::string, WebUsers::permissionLevel_t > &permissionLevelsMap, std::map< std::string, WebUsers::permissionLevel_t > &permissionThresholdsMap)
ITRACEController * theTRACEController_
only define for an app that receives a command
virtual void forceSupervisorPropertyValues(void)
override to force supervisor property values (and ignore user settings)
void getRequestUserInfo(WebUsers::RequestUserInfo &requestUserInfo)
WebUsers::permissionLevel_t getSupervisorPropertyUserPermissionsThreshold(const std::string &requestType)
XDAQ_CONST_CALL xdaq::ApplicationDescriptor * getGatewaySupervisorDescriptor(void)
will be wizard supervisor in wiz mode
virtual void setSupervisorPropertyDefaults(void)
override to control supervisor specific defaults
std::string getTraceBufferDump(std::string const &filterFor="", std::string const &filterOut="")
virtual void setTraceLevelMask(std::string const &name, TraceMasks const &lvl, std::string const &hostname="localhost", std::string const &mode="ALL")=0
pure virtual
virtual void resetTraceBuffer(void)=0
pure virtual
virtual bool getIsTriggered(void)=0
pure virtual
virtual const HostTraceLevelMap & getTraceLevels(void)=0
pure virtual
virtual void enableTrace(bool enable=true)=0
pure virtual
virtual void setTriggerEnable(size_t entriesAfterTrigger)=0
pure virtual
void INIT_MF(const char *name)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static void getSetFromString(const std::string &inputString, std::set< std::string > &setToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static T validateValueForDefaultStringDataType(const std::string &value, bool doConvertEnvironmentVariables=true)
static T & getWildCardMatchFromMap(const std::string &needle, std::map< std::string, T > &haystack, std::string *foundKey=0)
defined in included .icc source
static bool inWildCardSet(const std::string &needle, const std::set< std::string > &haystack)
Definition: StringMacros.cc:94
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~