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>
10 #include <xercesc/util/PlatformUtils.hpp>
11 #include <xercesc/util/XMLString.hpp>
12 #include <sstream>
13 #include <memory>
14 
15 using namespace xercesc;
16 
17 //<<<<<< PRIVATE DEFINES >>>>>>
18 //<<<<<< PRIVATE CONSTANTS >>>>>>
19 //<<<<<< PRIVATE TYPES >>>>>>
20 //<<<<<< PRIVATE VARIABLE DEFINITIONS >>>>>>
21 //<<<<<< PUBLIC VARIABLE DEFINITIONS >>>>>>
22 //<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>>
23 //<<<<<< PRIVATE FUNCTION DEFINITIONS >>>>>>
24 //<<<<<< PUBLIC FUNCTION DEFINITIONS >>>>>>
25 //<<<<<< MEMBER FUNCTION DEFINITIONS >>>>>>
26 
27 namespace {
28  inline std::string _toString(XMLCh const* toTranscode) {
29  std::string tmp(XMLString::transcode(toTranscode));
30  return tmp;
31  }
32 
33  inline unsigned int _toUInt(XMLCh const* toTranscode) {
34  std::istringstream iss(_toString(toTranscode));
35  unsigned int returnValue;
36  iss >> returnValue;
37  return returnValue;
38  }
39 
40  inline double _toDouble(XMLCh const* toTranscode) {
41  std::istringstream iss(_toString(toTranscode));
42  double returnValue;
43  iss >> returnValue;
44  return returnValue;
45  }
46 
47  inline XMLCh* _toDOMS(std::string temp) {
48  XMLCh* buff = XMLString::transcode(temp.c_str());
49  return buff;
50  }
51 
52  // concatenate all the XML node attribute/value pairs into a
53  // paren-separated string (for use by CORAL and frontier_client)
54  inline std::string _toParenString(DOMNode const& nodeToConvert) {
55  std::ostringstream oss;
56 
57  DOMNodeList *childList = nodeToConvert.getChildNodes();
58 
59  unsigned int numNodes = childList->getLength();
60  for (unsigned int i = 0; i < numNodes; ++i) {
61  DOMNode *childNode = childList->item(i);
62  if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
63  continue;
64  }
65  DOMElement *child = static_cast<DOMElement *>(childNode);
66 
67  DOMNamedNodeMap *attributes = child->getAttributes();
68  unsigned int numAttributes = attributes->getLength();
69  for (unsigned int j = 0; j < numAttributes; ++j) {
70  DOMNode *attributeNode = attributes->item(j);
71  if (attributeNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {
72  continue;
73  }
74  DOMAttr *attribute = static_cast<DOMAttr *>(attributeNode);
75 
76  oss << "(" << _toString(child->getTagName()) <<
77  _toString(attribute->getName()) << "=" <<
78  _toString(attribute->getValue()) << ")";
79  }
80  }
81  return oss.str();
82  }
83 
84  template<typename T>
85  static
86  void overrideFromPSet(char const* iName, edm::ParameterSet const& iPSet,
87  T& iHolder, T const*& iPointer) {
88  if(iPSet.exists(iName)) {
89  iHolder = iPSet.getUntrackedParameter<T>(iName);
90  iPointer = &iHolder;
91  }
92  }
93 }
94 
95 namespace edm {
96  namespace service {
97  SiteLocalConfigService::SiteLocalConfigService(ParameterSet const& pset) :
98  m_url("/SITECONF/local/JobConfig/site-local-config.xml"),
99  m_dataCatalog(),
100  m_fallbackDataCatalog(),
101  m_frontierConnect(),
102  m_rfioType("castor"),
103  m_connected(false),
104  m_cacheTempDir(),
105  m_cacheTempDirPtr(0),
106  m_cacheMinFree(),
107  m_cacheMinFreePtr(0),
108  m_cacheHint(),
109  m_cacheHintPtr(0),
110  m_readHint(),
111  m_readHintPtr(0),
112  m_ttreeCacheSize(0U),
113  m_ttreeCacheSizePtr(0),
114  m_timeout(0U),
115  m_timeoutPtr(0),
116  m_debugLevel(0U),
117  m_nativeProtocols(),
118  m_nativeProtocolsPtr(0) {
119 
120  char* tmp = getenv("CMS_PATH");
121 
122  if (tmp) {
123  m_url = tmp + m_url;
124  }
125 
126  this->parse(m_url);
127 
128  //apply overrides
129  overrideFromPSet("overrideSourceCacheTempDir", pset, m_cacheTempDir, m_cacheTempDirPtr);
130  overrideFromPSet("overrideSourceCacheMinFree", pset, m_cacheMinFree, m_cacheMinFreePtr);
131  overrideFromPSet("overrideSourceCacheHintDir", pset, m_cacheHint, m_cacheHintPtr);
132  overrideFromPSet("overrideSourceReadHint", pset, m_readHint, m_readHintPtr);
133  overrideFromPSet("overrideSourceNativeProtocols", pset, m_nativeProtocols, m_nativeProtocolsPtr);
134  overrideFromPSet("overrideSourceTTreeCacheSize", pset, m_ttreeCacheSize, m_ttreeCacheSizePtr);
135  overrideFromPSet("overrideSourceTimeout", pset, m_timeout, m_timeoutPtr);
136 
137  if(pset.exists("debugLevel")) {
138  m_debugLevel = pset.getUntrackedParameter<unsigned int>("debugLevel");
139  }
140 
141  }
142 
143  std::string const
145  if (!m_connected) {
146  //throw cms::Exception("Incomplete configuration")
147  // << "Valid site-local-config not found at " << m_url;
148  // Return PoolFileCatalog.xml for now
149  return "file:PoolFileCatalog.xml";
150  }
151 
152  if (m_dataCatalog == "") {
153  throw cms::Exception("Incomplete configuration")
154  << "Did not find catalog in event-data section in " << m_url;
155  }
156 
157  return m_dataCatalog;
158  }
159 
160  std::string const
162  if (!m_connected) {
163  //throw cms::Exception("Incomplete configuration")
164  // << "Valid site-local-config not found at " << m_url;
165  // Return PoolFileCatalog.xml for now
166  return "file:PoolFileCatalog.xml";
167  }
168 
169  // Note: Unlike the dataCatalog, the fallbackDataCatalog may be empty!
170  return m_fallbackDataCatalog;
171  }
172 
173  std::string const
174  SiteLocalConfigService::frontierConnect(std::string const& servlet) const {
175  if (!m_connected) {
176  throw cms::Exception("Incomplete configuration")
177  << "Valid site-local-config not found at " << m_url;
178  }
179 
180  if (m_frontierConnect == "") {
181  throw cms::Exception("Incomplete configuration")
182  << "Did not find frontier-connect in calib-data section in " << m_url;
183  }
184 
185  if (servlet == "") {
186  return m_frontierConnect;
187  }
188 
189  // Replace the last component of every "serverurl=" piece (up to the
190  // next close-paren) with the servlet
191  std::string::size_type nextparen = 0;
192  std::string::size_type serverurl, lastslash;
193  std::string complexstr = "";
194  while ((serverurl = m_frontierConnect.find("(serverurl=", nextparen)) != std::string::npos) {
195  complexstr.append(m_frontierConnect, nextparen, serverurl - nextparen);
196  nextparen = m_frontierConnect.find(')', serverurl);
197  lastslash = m_frontierConnect.rfind('/', nextparen);
198  complexstr.append(m_frontierConnect, serverurl, lastslash - serverurl + 1);
199  complexstr.append(servlet);
200  }
201  complexstr.append(m_frontierConnect, nextparen, m_frontierConnect.length()-nextparen);
202 
203  return complexstr;
204  }
205 
206  std::string const
208  static std::string const proto = "frontier://";
209 
210  if (input.substr(0,proto.length()) == proto) {
211  // Replace the part after the frontier:// and before either an open-
212  // parentheses (which indicates user-supplied options) or the last
213  // slash (which indicates start of the schema) with the complex
214  // parenthesized string returned from frontierConnect() (which
215  // contains all the information needed to connect to frontier),
216  // if that part is a simple servlet name (non-empty and not
217  // containing special characters)
218  // Example connect strings where servlet is replaced:
219  // frontier://cms_conditions_data/CMS_COND_ECAL
220  // frontier://FrontierInt/CMS_COND_ECAL
221  // frontier://FrontierInt(retrieve-ziplevel=0)/CMS_COND_ECAL
222  // Example connect strings left untouched:
223  // frontier://cmsfrontier.cern.ch:8000/FrontierInt/CMS_COND_ECAL
224  // frontier://(serverurl=cmsfrontier.cern.ch:8000/FrontierInt)/CMS_COND_ECAL
225  std::string::size_type startservlet = proto.length();
226  // if user supplied extra parenthesized options, stop servlet there
227  std::string::size_type endservlet = input.find("(", startservlet);
228  if (endservlet == std::string::npos) {
229  endservlet = input.rfind('/', input.length());
230  }
231  std::string servlet = input.substr(startservlet, endservlet - startservlet);
232  if ((servlet != "") && (servlet.find_first_of(":/)[]") == std::string::npos)) {
233  if (servlet == "cms_conditions_data") {
234  // use the default servlet from site-local-config.xml
235  servlet = "";
236  }
237  return proto + frontierConnect(servlet) + input.substr(endservlet);
238  }
239  }
240  return input;
241  }
242 
243  std::string const
245  return m_rfioType;
246  }
247 
248  std::string const*
250  return m_cacheTempDirPtr;
251  }
252 
253  double const*
255  return m_cacheMinFreePtr;
256  }
257 
258  std::string const*
260  return m_cacheHintPtr;
261  }
262 
263  std::string const*
265  return m_readHintPtr;
266  }
267 
268  unsigned int const*
270  return m_ttreeCacheSizePtr;
271  }
272 
273  unsigned int const*
275  return m_timeoutPtr;
276  }
277 
278  unsigned int
280  return m_debugLevel;
281  }
282 
283  std::vector<std::string> const*
285  return m_nativeProtocolsPtr;
286  }
287 
288  void
289  SiteLocalConfigService::parse(std::string const& url) {
290  XMLPlatformUtils::Initialize();
291  std::auto_ptr<XercesDOMParser> parser(new XercesDOMParser);
292  try {
293  parser->setValidationScheme(XercesDOMParser::Val_Auto);
294  parser->setDoNamespaces(false);
295 
296  parser->parse(url.c_str());
297  DOMDocument* doc = parser->getDocument();
298  if (!doc) {
299  return;
300  }
301 
302  // The Site Config has the following format
303  // <site-local-config>
304  // <site name="FNAL">
305  // <event-data>
306  // <catalog url="trivialcatalog_file:/x/y/z.xml"/>
307  // <rfiotype value="castor"/>
308  // </event-data>
309  // <calib-data>
310  // <catalog url="trivialcatalog_file:/x/y/z.xml"/>
311  // <frontier-connect>
312  // ... frontier-interpreted server/proxy xml ...
313  // </frontier-connect>
314  // </calib-data>
315  // <source-config>
316  // <cache-temp-dir name="/a/b/c"/>
317  // <cache-hint value="..."/>
318  // <read-hint value="..."/>
319  // <ttree-cache-size value="0"/>
320  // <native-protocols>
321  // <protocol prefix="dcache"/>
322  // <protocol prefix="file"/>
323  // </native-protocols>
324  // </source-config>
325  // </site>
326  // </site-local-config>
327 
328  // FIXME: should probably use the parser for validating the XML.
329 
330  DOMNodeList *sites = doc->getElementsByTagName(_toDOMS("site"));
331  unsigned int numSites = sites->getLength();
332  for (unsigned int i = 0; i < numSites; ++i) {
333  DOMElement *site = static_cast<DOMElement *>(sites->item(i));
334 
335  // Parsing of the event data section
336  {
337  DOMNodeList *eventDataList = site->getElementsByTagName(_toDOMS("event-data"));
338  if (eventDataList->getLength() > 0) {
339  DOMElement *eventData = static_cast<DOMElement *>(eventDataList->item(0));
340 
341  DOMNodeList *catalogs = eventData->getElementsByTagName(_toDOMS("catalog"));
342 
343  if (catalogs->getLength() > 0) {
344  DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(0));
345  m_dataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
346  }
347 
348  if (catalogs->getLength() > 1) {
349  DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(1));
350  m_fallbackDataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
351  }
352 
353  DOMNodeList* rfiotypes = eventData->getElementsByTagName(_toDOMS("rfiotype"));
354 
355  if (rfiotypes->getLength() > 0) {
356  DOMElement* rfiotype = static_cast<DOMElement *>(rfiotypes->item(0));
357  m_rfioType = _toString(rfiotype->getAttribute(_toDOMS("value")));
358  }
359  }
360  }
361 
362  // Parsing of the calib-data section
363  {
364  DOMNodeList *calibDataList = site->getElementsByTagName(_toDOMS("calib-data"));
365 
366  if (calibDataList->getLength() > 0) {
367  DOMElement *calibData = static_cast<DOMElement *>(calibDataList->item(0));
368  DOMNodeList *frontierConnectList = calibData->getElementsByTagName(_toDOMS("frontier-connect"));
369 
370  if (frontierConnectList->getLength() > 0) {
371  DOMElement *frontierConnect = static_cast<DOMElement *>(frontierConnectList->item(0));
372  m_frontierConnect = _toParenString(*frontierConnect);
373  }
374  }
375  }
376  // Parsing of the source config section
377  {
378  DOMNodeList *sourceConfigList = site->getElementsByTagName(_toDOMS("source-config"));
379 
380  if (sourceConfigList->getLength() > 0) {
381  DOMElement *sourceConfig = static_cast<DOMElement *>(sourceConfigList->item(0));
382  DOMNodeList *cacheTempDirList = sourceConfig->getElementsByTagName(_toDOMS("cache-temp-dir"));
383 
384  if (cacheTempDirList->getLength() > 0) {
385  DOMElement *cacheTempDir = static_cast<DOMElement *>(cacheTempDirList->item(0));
386  m_cacheTempDir = _toString(cacheTempDir->getAttribute(_toDOMS("name")));
388  }
389 
390  DOMNodeList *cacheMinFreeList = sourceConfig->getElementsByTagName(_toDOMS("cache-min-free"));
391 
392  if (cacheMinFreeList->getLength() > 0) {
393  DOMElement *cacheMinFree = static_cast<DOMElement *>(cacheMinFreeList->item(0));
394  m_cacheMinFree = _toDouble(cacheMinFree->getAttribute(_toDOMS("value")));
396  }
397 
398  DOMNodeList *cacheHintList = sourceConfig->getElementsByTagName(_toDOMS("cache-hint"));
399 
400  if (cacheHintList->getLength() > 0) {
401  DOMElement *cacheHint = static_cast<DOMElement *>(cacheHintList->item(0));
402  m_cacheHint = _toString(cacheHint->getAttribute(_toDOMS("value")));
404  }
405 
406  DOMNodeList *readHintList = sourceConfig->getElementsByTagName(_toDOMS("read-hint"));
407 
408  if (readHintList->getLength() > 0) {
409  DOMElement *readHint = static_cast<DOMElement *>(readHintList->item(0));
410  m_readHint = _toString(readHint->getAttribute(_toDOMS("value")));
412  }
413 
414  DOMNodeList *ttreeCacheSizeList = sourceConfig->getElementsByTagName(_toDOMS("ttree-cache-size"));
415 
416  if (ttreeCacheSizeList->getLength() > 0) {
417  DOMElement *ttreeCacheSize = static_cast<DOMElement *>(ttreeCacheSizeList->item(0));
418  m_ttreeCacheSize = _toUInt(ttreeCacheSize->getAttribute(_toDOMS("value")));
420  }
421 
422  DOMNodeList *timeoutList = sourceConfig->getElementsByTagName(_toDOMS("timeout-in-seconds"));
423 
424  if (timeoutList->getLength() > 0) {
425  DOMElement *timeout = static_cast<DOMElement *>(timeoutList->item(0));
426  m_timeout = _toUInt(timeout->getAttribute(_toDOMS("value")));
428  }
429 
430  DOMNodeList *nativeProtocolsList = sourceConfig->getElementsByTagName(_toDOMS("native-protocols"));
431 
432  if (nativeProtocolsList->getLength() > 0) {
433  DOMElement *nativeProtocol = static_cast<DOMElement *>(nativeProtocolsList->item(0));
434  DOMNodeList *childList = nativeProtocol->getChildNodes();
435 
436  XMLCh* prefixXMLCh = _toDOMS("prefix");
437  unsigned int numNodes = childList->getLength();
438  for (unsigned int i = 0; i < numNodes; ++i) {
439  DOMNode *childNode = childList->item(i);
440  if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
441  continue;
442  }
443  DOMElement *child = static_cast<DOMElement *>(childNode);
444  m_nativeProtocols.push_back(_toString(child->getAttribute(prefixXMLCh)));
445  }
447  }
448  }
449  }
450  }
451  m_connected = true;
452  }
453  catch (xercesc::DOMException const& e) {
454  }
455  }
456 
457  void
460  desc.setComment("Service to translate logical file names to physical file names.");
461 
462  desc.addOptionalUntracked<std::string>("overrideSourceCacheTempDir");
463  desc.addOptionalUntracked<double>("overrideSourceCacheMinFree");
464  desc.addOptionalUntracked<std::string>("overrideSourceCacheHintDir");
465  desc.addOptionalUntracked<std::string>("overrideSourceReadHint");
466  desc.addOptionalUntracked<std::vector<std::string> >("overrideSourceNativeProtocols");
467  desc.addOptionalUntracked<unsigned int>("overrideSourceTTreeCacheSize");
468  desc.addOptionalUntracked<unsigned int>("overrideSourceTimeout");
469  desc.addOptionalUntracked<unsigned int>("debugLevel");
470 
471  descriptions.add("SiteLocalConfigService", desc);
472  }
473  }
474 }
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
std::string _toString(const XMLCh *toTranscode)
std::string const dataCatalog(void) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
uint16_t size_type
std::vector< std::string > const * m_nativeProtocolsPtr
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
tuple doc
Definition: asciidump.py:381
std::vector< std::string > m_nativeProtocols
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)
std::string const frontierConnect(std::string const &servlet) const
std::vector< std::string > const * sourceNativeProtocols() const
long double T
unsigned int const * sourceTTreeCacheSize() const