CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SiteLocalConfigService.cc
Go to the documentation of this file.
1 //<<<<<< INCLUDES >>>>>>
2 
8 #include <xercesc/dom/DOM.hpp>
9 #include <xercesc/parsers/XercesDOMParser.hpp>
11 #include <xercesc/util/XMLString.hpp>
12 #include <sstream>
13 #include <memory>
14 #include <boost/algorithm/string.hpp>
15 
16 using namespace xercesc;
17 
18 //<<<<<< PRIVATE DEFINES >>>>>>
19 //<<<<<< PRIVATE CONSTANTS >>>>>>
20 //<<<<<< PRIVATE TYPES >>>>>>
21 //<<<<<< PRIVATE VARIABLE DEFINITIONS >>>>>>
22 //<<<<<< PUBLIC VARIABLE DEFINITIONS >>>>>>
23 //<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>>
24 //<<<<<< PRIVATE FUNCTION DEFINITIONS >>>>>>
25 //<<<<<< PUBLIC FUNCTION DEFINITIONS >>>>>>
26 //<<<<<< MEMBER FUNCTION DEFINITIONS >>>>>>
27 
28 namespace {
29  inline std::string _toString(XMLCh const* toTranscode) {
30  std::string tmp(XMLString::transcode(toTranscode));
31  return tmp;
32  }
33 
34  inline unsigned int _toUInt(XMLCh const* toTranscode) {
35  std::istringstream iss(_toString(toTranscode));
36  unsigned int returnValue;
37  iss >> returnValue;
38  return returnValue;
39  }
40 
41  inline bool _toBool(XMLCh const* toTranscode) {
42  std::string value = _toString(toTranscode);
43  if ((value == "true") || (value == "1"))
44  return true;
45  return false;
46  }
47 
48  inline double _toDouble(XMLCh const* toTranscode) {
49  std::istringstream iss(_toString(toTranscode));
50  double returnValue;
51  iss >> returnValue;
52  return returnValue;
53  }
54 
55  inline XMLCh* _toDOMS(std::string temp) {
56  XMLCh* buff = XMLString::transcode(temp.c_str());
57  return buff;
58  }
59 
60  // concatenate all the XML node attribute/value pairs into a
61  // paren-separated string (for use by CORAL and frontier_client)
62  inline std::string _toParenString(DOMNode const& nodeToConvert) {
63  std::ostringstream oss;
64 
65  DOMNodeList *childList = nodeToConvert.getChildNodes();
66 
67  unsigned int numNodes = childList->getLength();
68  for (unsigned int i = 0; i < numNodes; ++i) {
69  DOMNode *childNode = childList->item(i);
70  if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
71  continue;
72  }
73  DOMElement *child = static_cast<DOMElement *>(childNode);
74 
75  DOMNamedNodeMap *attributes = child->getAttributes();
76  unsigned int numAttributes = attributes->getLength();
77  for (unsigned int j = 0; j < numAttributes; ++j) {
78  DOMNode *attributeNode = attributes->item(j);
79  if (attributeNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {
80  continue;
81  }
82  DOMAttr *attribute = static_cast<DOMAttr *>(attributeNode);
83 
84  oss << "(" << _toString(child->getTagName()) <<
85  _toString(attribute->getName()) << "=" <<
86  _toString(attribute->getValue()) << ")";
87  }
88  }
89  return oss.str();
90  }
91 
92  template<typename T>
93  static
94  void overrideFromPSet(char const* iName, edm::ParameterSet const& iPSet,
95  T& iHolder, T const*& iPointer) {
96  if(iPSet.exists(iName)) {
97  iHolder = iPSet.getUntrackedParameter<T>(iName);
98  iPointer = &iHolder;
99  }
100  }
101 }
102 
103 namespace edm {
104  namespace service {
105 
106  const std::string SiteLocalConfigService::m_statisticsDefaultPort = "3334";
107 
108  SiteLocalConfigService::SiteLocalConfigService(ParameterSet const& pset) :
109  m_url("/SITECONF/local/JobConfig/site-local-config.xml"),
110  m_dataCatalog(),
111  m_fallbackDataCatalog(),
112  m_frontierConnect(),
113  m_rfioType("castor"),
114  m_connected(false),
115  m_cacheTempDir(),
116  m_cacheTempDirPtr(nullptr),
117  m_cacheMinFree(),
118  m_cacheMinFreePtr(nullptr),
119  m_cacheHint(),
120  m_cacheHintPtr(nullptr),
121  m_cloneCacheHint(),
122  m_cloneCacheHintPtr(nullptr),
123  m_readHint(),
124  m_readHintPtr(nullptr),
125  m_ttreeCacheSize(0U),
126  m_ttreeCacheSizePtr(nullptr),
127  m_timeout(0U),
128  m_timeoutPtr(nullptr),
129  m_debugLevel(0U),
130  m_enablePrefetching(false),
131  m_enablePrefetchingPtr(nullptr),
132  m_nativeProtocols(),
133  m_nativeProtocolsPtr(nullptr),
134  m_statisticsDestination(),
135  m_statisticsAddrInfo(nullptr),
136  m_siteName() {
137 
138  char* tmp = getenv("CMS_PATH");
139 
140  if (tmp) {
141  m_url = tmp + m_url;
142  }
143 
144  this->parse(m_url);
145 
146  //apply overrides
147  overrideFromPSet("overrideSourceCacheTempDir", pset, m_cacheTempDir, m_cacheTempDirPtr);
148  overrideFromPSet("overrideSourceCacheMinFree", pset, m_cacheMinFree, m_cacheMinFreePtr);
149  overrideFromPSet("overrideSourceCacheHintDir", pset, m_cacheHint, m_cacheHintPtr);
150  overrideFromPSet("overrideSourceCloneCacheHintDir", pset, m_cloneCacheHint, m_cloneCacheHintPtr);
151  overrideFromPSet("overrideSourceReadHint", pset, m_readHint, m_readHintPtr);
152  overrideFromPSet("overrideSourceNativeProtocols", pset, m_nativeProtocols, m_nativeProtocolsPtr);
153  overrideFromPSet("overrideSourceTTreeCacheSize", pset, m_ttreeCacheSize, m_ttreeCacheSizePtr);
154  overrideFromPSet("overrideSourceTimeout", pset, m_timeout, m_timeoutPtr);
155  overrideFromPSet("overridePrefetching", pset, m_enablePrefetching, m_enablePrefetchingPtr);
156  const std::string * tmpStringPtr = NULL;
157  overrideFromPSet("overrideStatisticsDestination", pset, m_statisticsDestination, tmpStringPtr);
159 
160  if(pset.exists("debugLevel")) {
161  m_debugLevel = pset.getUntrackedParameter<unsigned int>("debugLevel");
162  }
163 
164  }
165 
167  if (m_statisticsAddrInfo) {
168  freeaddrinfo(m_statisticsAddrInfo);
169  m_statisticsAddrInfo = nullptr;
170  }
171  }
172 
173  std::string const
175  if (!m_connected) {
176  //throw cms::Exception("Incomplete configuration")
177  // << "Valid site-local-config not found at " << m_url;
178  // Return PoolFileCatalog.xml for now
179  return "file:PoolFileCatalog.xml";
180  }
181 
182  if (m_dataCatalog == "") {
183  throw cms::Exception("Incomplete configuration")
184  << "Did not find catalog in event-data section in " << m_url;
185  }
186 
187  return m_dataCatalog;
188  }
189 
190  std::string const
192  if (!m_connected) {
193  //throw cms::Exception("Incomplete configuration")
194  // << "Valid site-local-config not found at " << m_url;
195  // Return PoolFileCatalog.xml for now
196  return "file:PoolFileCatalog.xml";
197  }
198 
199  // Note: Unlike the dataCatalog, the fallbackDataCatalog may be empty!
200  return m_fallbackDataCatalog;
201  }
202 
203  std::string const
205  if (!m_connected) {
206  throw cms::Exception("Incomplete configuration")
207  << "Valid site-local-config not found at " << m_url;
208  }
209 
210  if (m_frontierConnect == "") {
211  throw cms::Exception("Incomplete configuration")
212  << "Did not find frontier-connect in calib-data section in " << m_url;
213  }
214 
215  if (servlet == "") {
216  return m_frontierConnect;
217  }
218 
219  // Replace the last component of every "serverurl=" piece (up to the
220  // next close-paren) with the servlet
221  std::string::size_type nextparen = 0;
222  std::string::size_type serverurl, lastslash;
223  std::string complexstr = "";
224  while ((serverurl = m_frontierConnect.find("(serverurl=", nextparen)) != std::string::npos) {
225  complexstr.append(m_frontierConnect, nextparen, serverurl - nextparen);
226  nextparen = m_frontierConnect.find(')', serverurl);
227  lastslash = m_frontierConnect.rfind('/', nextparen);
228  complexstr.append(m_frontierConnect, serverurl, lastslash - serverurl + 1);
229  complexstr.append(servlet);
230  }
231  complexstr.append(m_frontierConnect, nextparen, m_frontierConnect.length()-nextparen);
232 
233  return complexstr;
234  }
235 
236  std::string const
238  static std::string const proto = "frontier://";
239 
240  if (input.substr(0,proto.length()) == proto) {
241  // Replace the part after the frontier:// and before either an open-
242  // parentheses (which indicates user-supplied options) or the last
243  // slash (which indicates start of the schema) with the complex
244  // parenthesized string returned from frontierConnect() (which
245  // contains all the information needed to connect to frontier),
246  // if that part is a simple servlet name (non-empty and not
247  // containing special characters)
248  // Example connect strings where servlet is replaced:
249  // frontier://cms_conditions_data/CMS_COND_ECAL
250  // frontier://FrontierInt/CMS_COND_ECAL
251  // frontier://FrontierInt(retrieve-ziplevel=0)/CMS_COND_ECAL
252  // Example connect strings left untouched:
253  // frontier://cmsfrontier.cern.ch:8000/FrontierInt/CMS_COND_ECAL
254  // frontier://(serverurl=cmsfrontier.cern.ch:8000/FrontierInt)/CMS_COND_ECAL
255  std::string::size_type startservlet = proto.length();
256  // if user supplied extra parenthesized options, stop servlet there
257  std::string::size_type endservlet = input.find("(", startservlet);
258  if (endservlet == std::string::npos) {
259  endservlet = input.rfind('/', input.length());
260  }
261  std::string servlet = input.substr(startservlet, endservlet - startservlet);
262  if ((servlet != "") && (servlet.find_first_of(":/)[]") == std::string::npos)) {
263  if (servlet == "cms_conditions_data") {
264  // use the default servlet from site-local-config.xml
265  servlet = "";
266  }
267  return proto + frontierConnect(servlet) + input.substr(endservlet);
268  }
269  }
270  return input;
271  }
272 
273  std::string const
275  return m_rfioType;
276  }
277 
278  std::string const*
280  return m_cacheTempDirPtr;
281  }
282 
283  double const*
285  return m_cacheMinFreePtr;
286  }
287 
288  std::string const*
290  return m_cacheHintPtr;
291  }
292 
293  std::string const*
295  return m_cloneCacheHintPtr;
296  }
297 
298  std::string const*
300  return m_readHintPtr;
301  }
302 
303  unsigned int const*
305  return m_ttreeCacheSizePtr;
306  }
307 
308  unsigned int const*
310  return m_timeoutPtr;
311  }
312 
313  bool
316  }
317 
318  unsigned int
320  return m_debugLevel;
321  }
322 
323  std::vector<std::string> const*
325  return m_nativeProtocolsPtr;
326  }
327 
328  struct addrinfo const*
330  return m_statisticsAddrInfo;
331  }
332 
333  std::string const&
335  return m_siteName;
336  }
337 
338  void
341  std::auto_ptr<XercesDOMParser> parser(new XercesDOMParser);
342  try {
343  parser->setValidationScheme(XercesDOMParser::Val_Auto);
344  parser->setDoNamespaces(false);
345 
346  parser->parse(url.c_str());
347  DOMDocument* doc = parser->getDocument();
348  if (!doc) {
349  return;
350  }
351 
352  // The Site Config has the following format
353  // <site-local-config>
354  // <site name="FNAL">
355  // <event-data>
356  // <catalog url="trivialcatalog_file:/x/y/z.xml"/>
357  // <rfiotype value="castor"/>
358  // </event-data>
359  // <calib-data>
360  // <catalog url="trivialcatalog_file:/x/y/z.xml"/>
361  // <frontier-connect>
362  // ... frontier-interpreted server/proxy xml ...
363  // </frontier-connect>
364  // </calib-data>
365  // <source-config>
366  // <cache-temp-dir name="/a/b/c"/>
367  // <cache-hint value="..."/>
368  // <read-hint value="..."/>
369  // <ttree-cache-size value="0"/>
370  // <native-protocols>
371  // <protocol prefix="dcache"/>
372  // <protocol prefix="file"/>
373  // </native-protocols>
374  // </source-config>
375  // </site>
376  // </site-local-config>
377 
378  // FIXME: should probably use the parser for validating the XML.
379 
380  DOMNodeList *sites = doc->getElementsByTagName(_toDOMS("site"));
381  unsigned int numSites = sites->getLength();
382  for (unsigned int i = 0; i < numSites; ++i) {
383  DOMElement *site = static_cast<DOMElement *>(sites->item(i));
384 
385  // Parse the site name
386  m_siteName = _toString(site->getAttribute(_toDOMS("name")));
387 
388  // Parsing of the event data section
389  {
390  DOMNodeList *eventDataList = site->getElementsByTagName(_toDOMS("event-data"));
391  if (eventDataList->getLength() > 0) {
392  DOMElement *eventData = static_cast<DOMElement *>(eventDataList->item(0));
393 
394  DOMNodeList *catalogs = eventData->getElementsByTagName(_toDOMS("catalog"));
395 
396  if (catalogs->getLength() > 0) {
397  DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(0));
398  m_dataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
399  }
400 
401  if (catalogs->getLength() > 1) {
402  DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(1));
403  m_fallbackDataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
404  }
405 
406  DOMNodeList* rfiotypes = eventData->getElementsByTagName(_toDOMS("rfiotype"));
407 
408  if (rfiotypes->getLength() > 0) {
409  DOMElement* rfiotype = static_cast<DOMElement *>(rfiotypes->item(0));
410  m_rfioType = _toString(rfiotype->getAttribute(_toDOMS("value")));
411  }
412  }
413  }
414 
415  // Parsing of the calib-data section
416  {
417  DOMNodeList *calibDataList = site->getElementsByTagName(_toDOMS("calib-data"));
418 
419  if (calibDataList->getLength() > 0) {
420  DOMElement *calibData = static_cast<DOMElement *>(calibDataList->item(0));
421  DOMNodeList *frontierConnectList = calibData->getElementsByTagName(_toDOMS("frontier-connect"));
422 
423  if (frontierConnectList->getLength() > 0) {
424  DOMElement *frontierConnect = static_cast<DOMElement *>(frontierConnectList->item(0));
425  m_frontierConnect = _toParenString(*frontierConnect);
426  }
427  }
428  }
429  // Parsing of the source config section
430  {
431  DOMNodeList *sourceConfigList = site->getElementsByTagName(_toDOMS("source-config"));
432 
433  if (sourceConfigList->getLength() > 0) {
434  DOMElement *sourceConfig = static_cast<DOMElement *>(sourceConfigList->item(0));
435  DOMNodeList *cacheTempDirList = sourceConfig->getElementsByTagName(_toDOMS("cache-temp-dir"));
436 
437  if (cacheTempDirList->getLength() > 0) {
438  DOMElement *cacheTempDir = static_cast<DOMElement *>(cacheTempDirList->item(0));
439  m_cacheTempDir = _toString(cacheTempDir->getAttribute(_toDOMS("name")));
441  }
442 
443  DOMNodeList *cacheMinFreeList = sourceConfig->getElementsByTagName(_toDOMS("cache-min-free"));
444 
445  if (cacheMinFreeList->getLength() > 0) {
446  DOMElement *cacheMinFree = static_cast<DOMElement *>(cacheMinFreeList->item(0));
447  m_cacheMinFree = _toDouble(cacheMinFree->getAttribute(_toDOMS("value")));
449  }
450 
451  DOMNodeList *cacheHintList = sourceConfig->getElementsByTagName(_toDOMS("cache-hint"));
452 
453  if (cacheHintList->getLength() > 0) {
454  DOMElement *cacheHint = static_cast<DOMElement *>(cacheHintList->item(0));
455  m_cacheHint = _toString(cacheHint->getAttribute(_toDOMS("value")));
457  }
458 
459  DOMNodeList *cloneCacheHintList = sourceConfig->getElementsByTagName(_toDOMS("clone-cache-hint"));
460 
461  if (cloneCacheHintList->getLength() > 0) {
462  DOMElement *cloneCacheHint = static_cast<DOMElement *>(cloneCacheHintList->item(0));
463  m_cloneCacheHint = _toString(cloneCacheHint->getAttribute(_toDOMS("value")));
465  }
466 
467  DOMNodeList *readHintList = sourceConfig->getElementsByTagName(_toDOMS("read-hint"));
468 
469  if (readHintList->getLength() > 0) {
470  DOMElement *readHint = static_cast<DOMElement *>(readHintList->item(0));
471  m_readHint = _toString(readHint->getAttribute(_toDOMS("value")));
473  }
474 
475  DOMNodeList *ttreeCacheSizeList = sourceConfig->getElementsByTagName(_toDOMS("ttree-cache-size"));
476 
477  if (ttreeCacheSizeList->getLength() > 0) {
478  DOMElement *ttreeCacheSize = static_cast<DOMElement *>(ttreeCacheSizeList->item(0));
479  m_ttreeCacheSize = _toUInt(ttreeCacheSize->getAttribute(_toDOMS("value")));
481  }
482 
483  DOMNodeList *timeoutList = sourceConfig->getElementsByTagName(_toDOMS("timeout-in-seconds"));
484 
485  if (timeoutList->getLength() > 0) {
486  DOMElement *timeout = static_cast<DOMElement *>(timeoutList->item(0));
487  m_timeout = _toUInt(timeout->getAttribute(_toDOMS("value")));
489  }
490 
491  DOMNodeList *statsDestList = sourceConfig->getElementsByTagName(_toDOMS("statistics-destination"));
492 
493  if (statsDestList->getLength() > 0) {
494  DOMElement *statsDest = static_cast<DOMElement *>(statsDestList->item(0));
495  m_statisticsDestination = _toString(statsDest->getAttribute(_toDOMS("name")));
496  }
497 
498  DOMNodeList *prefetchingList = sourceConfig->getElementsByTagName(_toDOMS("prefetching"));
499 
500  if (prefetchingList->getLength() > 0) {
501  DOMElement *prefetching = static_cast<DOMElement *>(prefetchingList->item(0));
502  m_enablePrefetching = _toBool(prefetching->getAttribute(_toDOMS("value")));
504  }
505 
506  DOMNodeList *nativeProtocolsList = sourceConfig->getElementsByTagName(_toDOMS("native-protocols"));
507 
508  if (nativeProtocolsList->getLength() > 0) {
509  DOMElement *nativeProtocol = static_cast<DOMElement *>(nativeProtocolsList->item(0));
510  DOMNodeList *childList = nativeProtocol->getChildNodes();
511 
512  XMLCh* prefixXMLCh = _toDOMS("prefix");
513  unsigned int numNodes = childList->getLength();
514  for (unsigned int i = 0; i < numNodes; ++i) {
515  DOMNode *childNode = childList->item(i);
516  if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
517  continue;
518  }
519  DOMElement *child = static_cast<DOMElement *>(childNode);
520  m_nativeProtocols.push_back(_toString(child->getAttribute(prefixXMLCh)));
521  }
523  }
524  }
525  }
526  }
527  m_connected = true;
528  }
529  catch (xercesc::DOMException const& e) {
530  }
531  }
532 
533  void
535  std::vector<std::string> inputStrings;
536  boost::split(inputStrings, m_statisticsDestination, boost::is_any_of(":"));
537  const std::string &host=inputStrings[0];
538  const std::string &port = (inputStrings.size() > 1) ? inputStrings[1] : m_statisticsDefaultPort;
539  struct addrinfo *res;
540  struct addrinfo hints;
541  memset(&hints, '\0', sizeof(hints));
542  hints.ai_socktype = SOCK_DGRAM;
543  hints.ai_flags = AI_ADDRCONFIG;
544  hints.ai_family = AF_UNSPEC;
545  int e = getaddrinfo(host.c_str(), port.c_str(), &hints, &res);
546  if (e != 0) {
547  // Silent failure - there's no way to report non-fatal failures from here.
548  return;
549  }
550  m_statisticsAddrInfo = res;
551  }
552 
553  void
556  desc.setComment("Service to translate logical file names to physical file names.");
557 
558  desc.addOptionalUntracked<std::string>("overrideSourceCacheTempDir");
559  desc.addOptionalUntracked<double>("overrideSourceCacheMinFree");
560  desc.addOptionalUntracked<std::string>("overrideSourceCacheHintDir");
561  desc.addOptionalUntracked<std::string>("overrideSourceCloneCacheHintDir")
562  ->setComment("Provide an alternate cache hint for fast cloning.");
563  desc.addOptionalUntracked<std::string>("overrideSourceReadHint");
564  desc.addOptionalUntracked<std::vector<std::string> >("overrideSourceNativeProtocols");
565  desc.addOptionalUntracked<unsigned int>("overrideSourceTTreeCacheSize");
566  desc.addOptionalUntracked<unsigned int>("overrideSourceTimeout");
567  desc.addOptionalUntracked<unsigned int>("debugLevel");
568  desc.addOptionalUntracked<bool>("overridePrefetching")
569  ->setComment("Request ROOT to asynchronously prefetch I/O during computation.");
570  desc.addOptionalUntracked<std::string>("overrideStatisticsDestination")
571  ->setComment("Provide an alternate network destination for I/O statistics (must be in the form of host:port).");
572 
573  descriptions.add("SiteLocalConfigService", desc);
574  }
575  }
576 }
std::string const fallbackDataCatalog(void) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
static void fillDescriptions(ConfigurationDescriptions &descriptions)
std::string const rfioType(void) const
static const std::string m_statisticsDefaultPort
std::string _toString(const XMLCh *toTranscode)
std::string const dataCatalog(void) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
#define NULL
Definition: scimark2.h:8
struct addrinfo const * statisticsDestination() const
void xercesInitialize()
Definition: Xerces.cc:17
#define nullptr
uint16_t size_type
int port
Definition: query.py:115
std::vector< std::string > const * m_nativeProtocolsPtr
static std::string const input
Definition: EdmProvDump.cc:44
std::string const lookupCalibConnect(std::string const &input) const
void setComment(std::string const &value)
std::string const * sourceCacheHint() const
list attributes
Definition: asciidump.py:415
std::string const * sourceReadHint() const
int j
Definition: DBlmapReader.cc:9
std::string const * sourceCloneCacheHint() const override
tuple doc
Definition: asciidump.py:381
std::vector< std::string > m_nativeProtocols
string host
Definition: query.py:114
string const
Definition: compareJSON.py:14
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::string const * sourceCacheTempDir() const
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
XMLCh * _toDOMS(std::string temp)
unsigned int const * sourceTimeout() const
ParameterDescriptionBase * addOptionalUntracked(U const &iLabel, T const &value)
volatile std::atomic< bool > shutdown_flag false
std::string const frontierConnect(std::string const &servlet) const
std::vector< std::string > const * sourceNativeProtocols() const
long double T
unsigned int const * sourceTTreeCacheSize() const
double split
Definition: MVATrainer.cc:139