CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FWCore/Services/src/SiteLocalConfigService.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "FWCore/Services/src/SiteLocalConfigService.h"
00004 #include "FWCore/Utilities/interface/Exception.h"
00005 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00008 #include <xercesc/dom/DOM.hpp>
00009 #include <xercesc/parsers/XercesDOMParser.hpp>
00010 #include <xercesc/util/PlatformUtils.hpp>
00011 #include <xercesc/util/XMLString.hpp>
00012 #include <sstream>
00013 #include <memory>
00014 #include <boost/algorithm/string.hpp>
00015 
00016 using namespace xercesc;
00017 
00018 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00019 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00020 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00021 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00022 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00023 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00024 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00025 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00026 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00027 
00028 namespace {
00029   inline std::string _toString(XMLCh const* toTranscode) {
00030       std::string tmp(XMLString::transcode(toTranscode));
00031       return tmp;
00032   }
00033 
00034   inline unsigned int _toUInt(XMLCh const* toTranscode) {
00035      std::istringstream iss(_toString(toTranscode));
00036      unsigned int returnValue;
00037      iss >> returnValue;
00038      return returnValue;
00039   }
00040 
00041   inline bool _toBool(XMLCh const* toTranscode) {
00042     std::string value = _toString(toTranscode);
00043     if ((value == "true") || (value == "1"))
00044       return true;
00045     return false;
00046   }
00047 
00048   inline double _toDouble(XMLCh const* toTranscode) {
00049      std::istringstream iss(_toString(toTranscode));
00050      double returnValue;
00051      iss >> returnValue;
00052      return returnValue;
00053   }
00054 
00055   inline XMLCh*  _toDOMS(std::string temp) {
00056       XMLCh* buff = XMLString::transcode(temp.c_str());
00057       return  buff;
00058   }
00059 
00060   // concatenate all the XML node attribute/value pairs into a
00061   // paren-separated string (for use by CORAL and frontier_client)
00062   inline std::string _toParenString(DOMNode const& nodeToConvert) {
00063       std::ostringstream oss;
00064 
00065       DOMNodeList *childList = nodeToConvert.getChildNodes();
00066 
00067       unsigned int numNodes = childList->getLength();
00068       for (unsigned int i = 0; i < numNodes; ++i) {
00069         DOMNode *childNode = childList->item(i);
00070         if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
00071             continue;
00072         }
00073         DOMElement *child = static_cast<DOMElement *>(childNode);
00074 
00075         DOMNamedNodeMap *attributes = child->getAttributes();
00076         unsigned int numAttributes = attributes->getLength();
00077         for (unsigned int j = 0; j < numAttributes; ++j) {
00078             DOMNode *attributeNode = attributes->item(j);
00079             if (attributeNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {
00080               continue;
00081             }
00082             DOMAttr *attribute = static_cast<DOMAttr *>(attributeNode);
00083 
00084             oss << "(" << _toString(child->getTagName()) <<
00085                           _toString(attribute->getName()) << "=" <<
00086                           _toString(attribute->getValue()) << ")";
00087         }
00088       }
00089       return oss.str();
00090   }
00091 
00092   template<typename T>
00093   static
00094   void overrideFromPSet(char const* iName, edm::ParameterSet const& iPSet,
00095                         T& iHolder, T const*& iPointer) {
00096      if(iPSet.exists(iName)) {
00097         iHolder = iPSet.getUntrackedParameter<T>(iName);
00098         iPointer = &iHolder;
00099      }
00100   }
00101 }
00102 
00103 namespace edm {
00104   namespace service {
00105 
00106     const std::string SiteLocalConfigService::m_statisticsDefaultPort = "3334";
00107 
00108     SiteLocalConfigService::SiteLocalConfigService(ParameterSet const& pset) :
00109           m_url("/SITECONF/local/JobConfig/site-local-config.xml"),
00110           m_dataCatalog(),
00111           m_fallbackDataCatalog(),
00112           m_frontierConnect(),
00113           m_rfioType("castor"),
00114           m_connected(false),
00115           m_cacheTempDir(),
00116           m_cacheTempDirPtr(nullptr),
00117           m_cacheMinFree(),
00118           m_cacheMinFreePtr(nullptr),
00119           m_cacheHint(),
00120           m_cacheHintPtr(nullptr),
00121           m_readHint(),
00122           m_readHintPtr(nullptr),
00123           m_ttreeCacheSize(0U),
00124           m_ttreeCacheSizePtr(nullptr),
00125           m_timeout(0U),
00126           m_timeoutPtr(nullptr),
00127           m_debugLevel(0U),
00128           m_enablePrefetching(false),
00129           m_enablePrefetchingPtr(nullptr),
00130           m_nativeProtocols(),
00131           m_nativeProtocolsPtr(nullptr),
00132           m_statisticsDestination(),
00133           m_statisticsAddrInfo(nullptr),
00134           m_siteName() {
00135 
00136         char* tmp = getenv("CMS_PATH");
00137 
00138         if (tmp) {
00139           m_url = tmp + m_url;
00140         }
00141 
00142         this->parse(m_url);
00143 
00144         //apply overrides
00145         overrideFromPSet("overrideSourceCacheTempDir", pset, m_cacheTempDir, m_cacheTempDirPtr);
00146         overrideFromPSet("overrideSourceCacheMinFree", pset, m_cacheMinFree, m_cacheMinFreePtr);
00147         overrideFromPSet("overrideSourceCacheHintDir", pset, m_cacheHint, m_cacheHintPtr);
00148         overrideFromPSet("overrideSourceReadHint", pset, m_readHint, m_readHintPtr);
00149         overrideFromPSet("overrideSourceNativeProtocols", pset, m_nativeProtocols, m_nativeProtocolsPtr);
00150         overrideFromPSet("overrideSourceTTreeCacheSize", pset, m_ttreeCacheSize, m_ttreeCacheSizePtr);
00151         overrideFromPSet("overrideSourceTimeout", pset, m_timeout, m_timeoutPtr);
00152         overrideFromPSet("overridePrefetching", pset, m_enablePrefetching, m_enablePrefetchingPtr);
00153         const std::string * tmpStringPtr = NULL;
00154         overrideFromPSet("overrideStatisticsDestination", pset, m_statisticsDestination, tmpStringPtr);
00155         this->computeStatisticsDestination();
00156 
00157        if(pset.exists("debugLevel")) {
00158             m_debugLevel = pset.getUntrackedParameter<unsigned int>("debugLevel");
00159        }
00160 
00161     }
00162 
00163     SiteLocalConfigService::~SiteLocalConfigService() {
00164       if (m_statisticsAddrInfo) {
00165         freeaddrinfo(m_statisticsAddrInfo);
00166         m_statisticsAddrInfo = nullptr;
00167       }
00168     }
00169 
00170     std::string const
00171     SiteLocalConfigService::dataCatalog(void) const {
00172         if (!m_connected) {
00173             //throw cms::Exception("Incomplete configuration")
00174             //    << "Valid site-local-config not found at " << m_url;
00175             // Return PoolFileCatalog.xml for now
00176             return "file:PoolFileCatalog.xml";
00177         }
00178 
00179         if (m_dataCatalog == "") {
00180           throw cms::Exception("Incomplete configuration")
00181             << "Did not find catalog in event-data section in " << m_url;
00182         }
00183 
00184         return m_dataCatalog;
00185     }
00186 
00187     std::string const
00188     SiteLocalConfigService::fallbackDataCatalog(void) const {
00189         if (!m_connected) {
00190             //throw cms::Exception("Incomplete configuration")
00191             //    << "Valid site-local-config not found at " << m_url;
00192             // Return PoolFileCatalog.xml for now
00193             return "file:PoolFileCatalog.xml";
00194         }
00195 
00196         // Note: Unlike the dataCatalog, the fallbackDataCatalog may be empty!
00197         return  m_fallbackDataCatalog;
00198     }
00199 
00200     std::string const
00201     SiteLocalConfigService::frontierConnect(std::string const& servlet) const {
00202         if (!m_connected) {
00203           throw cms::Exception("Incomplete configuration")
00204             << "Valid site-local-config not found at " << m_url;
00205         }
00206 
00207         if (m_frontierConnect == "") {
00208           throw cms::Exception("Incomplete configuration")
00209             << "Did not find frontier-connect in calib-data section in " << m_url;
00210         }
00211 
00212         if (servlet == "") {
00213           return m_frontierConnect;
00214         }
00215 
00216         // Replace the last component of every "serverurl=" piece (up to the
00217         //   next close-paren) with the servlet
00218         std::string::size_type nextparen = 0;
00219         std::string::size_type serverurl, lastslash;
00220         std::string complexstr = "";
00221         while ((serverurl = m_frontierConnect.find("(serverurl=", nextparen)) != std::string::npos) {
00222           complexstr.append(m_frontierConnect, nextparen, serverurl - nextparen);
00223           nextparen = m_frontierConnect.find(')', serverurl);
00224           lastslash = m_frontierConnect.rfind('/', nextparen);
00225           complexstr.append(m_frontierConnect, serverurl, lastslash - serverurl + 1);
00226           complexstr.append(servlet);
00227         }
00228         complexstr.append(m_frontierConnect, nextparen, m_frontierConnect.length()-nextparen);
00229 
00230         return complexstr;
00231     }
00232 
00233     std::string const
00234     SiteLocalConfigService::lookupCalibConnect(std::string const& input) const {
00235         static std::string const proto = "frontier://";
00236 
00237         if (input.substr(0,proto.length()) == proto) {
00238           // Replace the part after the frontier:// and before either an open-
00239           //  parentheses (which indicates user-supplied options) or the last
00240           //  slash (which indicates start of the schema) with the complex
00241           //  parenthesized string returned from frontierConnect() (which
00242           //  contains all the information needed to connect to frontier),
00243           //  if that part is a simple servlet name (non-empty and not
00244           //  containing special characters)
00245           // Example connect strings where servlet is replaced:
00246           //  frontier://cms_conditions_data/CMS_COND_ECAL
00247           //  frontier://FrontierInt/CMS_COND_ECAL
00248           //  frontier://FrontierInt(retrieve-ziplevel=0)/CMS_COND_ECAL
00249           // Example connect strings left untouched:
00250           //  frontier://cmsfrontier.cern.ch:8000/FrontierInt/CMS_COND_ECAL
00251           //  frontier://(serverurl=cmsfrontier.cern.ch:8000/FrontierInt)/CMS_COND_ECAL
00252           std::string::size_type startservlet = proto.length();
00253           // if user supplied extra parenthesized options, stop servlet there
00254           std::string::size_type endservlet = input.find("(", startservlet);
00255           if (endservlet == std::string::npos) {
00256               endservlet = input.rfind('/', input.length());
00257           }
00258           std::string servlet = input.substr(startservlet, endservlet - startservlet);
00259           if ((servlet != "") && (servlet.find_first_of(":/)[]") == std::string::npos)) {
00260               if (servlet == "cms_conditions_data") {
00261                 // use the default servlet from site-local-config.xml
00262                 servlet = "";
00263               }
00264               return proto + frontierConnect(servlet) + input.substr(endservlet);
00265           }
00266         }
00267         return input;
00268     }
00269 
00270     std::string const
00271     SiteLocalConfigService::rfioType(void) const {
00272         return m_rfioType;
00273     }
00274 
00275     std::string const*
00276     SiteLocalConfigService::sourceCacheTempDir() const {
00277        return m_cacheTempDirPtr;
00278     }
00279 
00280     double const*
00281     SiteLocalConfigService::sourceCacheMinFree() const {
00282        return m_cacheMinFreePtr;
00283     }
00284 
00285     std::string const*
00286     SiteLocalConfigService::sourceCacheHint() const {
00287        return m_cacheHintPtr;
00288     }
00289 
00290     std::string const*
00291     SiteLocalConfigService::sourceReadHint() const {
00292        return m_readHintPtr;
00293     }
00294 
00295     unsigned int const*
00296     SiteLocalConfigService::sourceTTreeCacheSize() const {
00297        return m_ttreeCacheSizePtr;
00298     }
00299 
00300     unsigned int const*
00301     SiteLocalConfigService::sourceTimeout() const {
00302        return m_timeoutPtr;
00303     }
00304 
00305     bool
00306     SiteLocalConfigService::enablePrefetching() const {
00307        return m_enablePrefetchingPtr ? *m_enablePrefetchingPtr : false;
00308     }
00309 
00310     unsigned int
00311     SiteLocalConfigService::debugLevel() const {
00312        return m_debugLevel;
00313     }
00314 
00315     std::vector<std::string> const*
00316     SiteLocalConfigService::sourceNativeProtocols() const {
00317        return m_nativeProtocolsPtr;
00318     }
00319 
00320     struct addrinfo const*
00321     SiteLocalConfigService::statisticsDestination() const {
00322        return m_statisticsAddrInfo;
00323     }
00324 
00325     std::string const&
00326     SiteLocalConfigService::siteName() const {
00327        return m_siteName;
00328     }
00329 
00330     void
00331     SiteLocalConfigService::parse(std::string const& url) {
00332       XMLPlatformUtils::Initialize();
00333       std::auto_ptr<XercesDOMParser> parser(new XercesDOMParser);
00334       try {
00335         parser->setValidationScheme(XercesDOMParser::Val_Auto);
00336         parser->setDoNamespaces(false);
00337 
00338         parser->parse(url.c_str());
00339         DOMDocument* doc = parser->getDocument();
00340         if (!doc) {
00341           return;
00342         }
00343 
00344         // The Site Config has the following format
00345         // <site-local-config>
00346         // <site name="FNAL">
00347         //   <event-data>
00348         //     <catalog url="trivialcatalog_file:/x/y/z.xml"/>
00349         //     <rfiotype value="castor"/>
00350         //   </event-data>
00351         //   <calib-data>
00352         //     <catalog url="trivialcatalog_file:/x/y/z.xml"/>
00353         //     <frontier-connect>
00354         //       ... frontier-interpreted server/proxy xml ...
00355             //     </frontier-connect>
00356         //   </calib-data>
00357             //   <source-config>
00358             //     <cache-temp-dir name="/a/b/c"/>
00359             //     <cache-hint value="..."/>
00360             //     <read-hint value="..."/>
00361             //     <ttree-cache-size value="0"/>
00362             //     <native-protocols>
00363             //        <protocol  prefix="dcache"/>
00364             //        <protocol prefix="file"/>
00365             //     </native-protocols>
00366             //   </source-config>
00367         // </site>
00368         // </site-local-config>
00369 
00370         // FIXME: should probably use the parser for validating the XML.
00371 
00372         DOMNodeList *sites = doc->getElementsByTagName(_toDOMS("site"));
00373         unsigned int numSites = sites->getLength();
00374         for (unsigned int i = 0; i < numSites; ++i) {
00375           DOMElement *site = static_cast<DOMElement *>(sites->item(i));
00376 
00377           // Parse the site name
00378           m_siteName = _toString(site->getAttribute(_toDOMS("name")));
00379 
00380           // Parsing of the event data section
00381           {
00382             DOMNodeList *eventDataList = site->getElementsByTagName(_toDOMS("event-data"));
00383             if (eventDataList->getLength() > 0) {
00384               DOMElement *eventData = static_cast<DOMElement *>(eventDataList->item(0));
00385 
00386               DOMNodeList *catalogs = eventData->getElementsByTagName(_toDOMS("catalog"));
00387 
00388               if (catalogs->getLength() > 0) {
00389                 DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(0));
00390                 m_dataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
00391               }
00392 
00393               if (catalogs->getLength() > 1) {
00394                 DOMElement * catalog = static_cast<DOMElement *>(catalogs->item(1));
00395                 m_fallbackDataCatalog = _toString(catalog->getAttribute(_toDOMS("url")));
00396               }
00397 
00398               DOMNodeList* rfiotypes = eventData->getElementsByTagName(_toDOMS("rfiotype"));
00399 
00400               if (rfiotypes->getLength() > 0) {
00401                 DOMElement* rfiotype = static_cast<DOMElement *>(rfiotypes->item(0));
00402                 m_rfioType = _toString(rfiotype->getAttribute(_toDOMS("value")));
00403               }
00404             }
00405           }
00406 
00407           // Parsing of the calib-data section
00408           {
00409             DOMNodeList *calibDataList = site->getElementsByTagName(_toDOMS("calib-data"));
00410 
00411             if (calibDataList->getLength() > 0) {
00412               DOMElement *calibData = static_cast<DOMElement *>(calibDataList->item(0));
00413               DOMNodeList *frontierConnectList = calibData->getElementsByTagName(_toDOMS("frontier-connect"));
00414 
00415               if (frontierConnectList->getLength() > 0) {
00416                 DOMElement *frontierConnect = static_cast<DOMElement *>(frontierConnectList->item(0));
00417                 m_frontierConnect = _toParenString(*frontierConnect);
00418               }
00419             }
00420           }
00421           // Parsing of the source config section
00422           {
00423             DOMNodeList *sourceConfigList = site->getElementsByTagName(_toDOMS("source-config"));
00424 
00425             if (sourceConfigList->getLength() > 0) {
00426               DOMElement *sourceConfig = static_cast<DOMElement *>(sourceConfigList->item(0));
00427               DOMNodeList *cacheTempDirList = sourceConfig->getElementsByTagName(_toDOMS("cache-temp-dir"));
00428 
00429               if (cacheTempDirList->getLength() > 0) {
00430                 DOMElement *cacheTempDir = static_cast<DOMElement *>(cacheTempDirList->item(0));
00431                 m_cacheTempDir = _toString(cacheTempDir->getAttribute(_toDOMS("name")));
00432                 m_cacheTempDirPtr = &m_cacheTempDir;
00433               }
00434 
00435               DOMNodeList *cacheMinFreeList = sourceConfig->getElementsByTagName(_toDOMS("cache-min-free"));
00436 
00437               if (cacheMinFreeList->getLength() > 0) {
00438                 DOMElement *cacheMinFree = static_cast<DOMElement *>(cacheMinFreeList->item(0));
00439                 m_cacheMinFree = _toDouble(cacheMinFree->getAttribute(_toDOMS("value")));
00440                 m_cacheMinFreePtr = &m_cacheMinFree;
00441               }
00442 
00443               DOMNodeList *cacheHintList = sourceConfig->getElementsByTagName(_toDOMS("cache-hint"));
00444 
00445               if (cacheHintList->getLength() > 0) {
00446                 DOMElement *cacheHint = static_cast<DOMElement *>(cacheHintList->item(0));
00447                 m_cacheHint = _toString(cacheHint->getAttribute(_toDOMS("value")));
00448                 m_cacheHintPtr = &m_cacheHint;
00449               }
00450 
00451               DOMNodeList *readHintList = sourceConfig->getElementsByTagName(_toDOMS("read-hint"));
00452 
00453               if (readHintList->getLength() > 0) {
00454                 DOMElement *readHint = static_cast<DOMElement *>(readHintList->item(0));
00455                 m_readHint = _toString(readHint->getAttribute(_toDOMS("value")));
00456                 m_readHintPtr = &m_readHint;
00457               }
00458 
00459               DOMNodeList *ttreeCacheSizeList = sourceConfig->getElementsByTagName(_toDOMS("ttree-cache-size"));
00460 
00461               if (ttreeCacheSizeList->getLength() > 0) {
00462                 DOMElement *ttreeCacheSize = static_cast<DOMElement *>(ttreeCacheSizeList->item(0));
00463                 m_ttreeCacheSize = _toUInt(ttreeCacheSize->getAttribute(_toDOMS("value")));
00464                 m_ttreeCacheSizePtr = &m_ttreeCacheSize;
00465               }
00466 
00467               DOMNodeList *timeoutList = sourceConfig->getElementsByTagName(_toDOMS("timeout-in-seconds"));
00468 
00469               if (timeoutList->getLength() > 0) {
00470                 DOMElement *timeout = static_cast<DOMElement *>(timeoutList->item(0));
00471                 m_timeout = _toUInt(timeout->getAttribute(_toDOMS("value")));
00472                 m_timeoutPtr = &m_timeout;
00473               }
00474 
00475               DOMNodeList *statsDestList = sourceConfig->getElementsByTagName(_toDOMS("statistics-destination"));
00476 
00477               if (statsDestList->getLength() > 0) {
00478                 DOMElement *statsDest = static_cast<DOMElement *>(statsDestList->item(0));
00479                 m_statisticsDestination = _toString(statsDest->getAttribute(_toDOMS("name")));
00480               }
00481 
00482               DOMNodeList *prefetchingList = sourceConfig->getElementsByTagName(_toDOMS("prefetching"));
00483 
00484               if (prefetchingList->getLength() > 0) {
00485                 DOMElement *prefetching = static_cast<DOMElement *>(prefetchingList->item(0));
00486                 m_enablePrefetching = _toBool(prefetching->getAttribute(_toDOMS("value")));
00487                 m_enablePrefetchingPtr = &m_enablePrefetching;
00488               }
00489 
00490               DOMNodeList *nativeProtocolsList = sourceConfig->getElementsByTagName(_toDOMS("native-protocols"));
00491 
00492               if (nativeProtocolsList->getLength() > 0) {
00493                 DOMElement *nativeProtocol = static_cast<DOMElement *>(nativeProtocolsList->item(0));
00494                 DOMNodeList *childList = nativeProtocol->getChildNodes();
00495 
00496                 XMLCh* prefixXMLCh = _toDOMS("prefix");
00497                 unsigned int numNodes = childList->getLength();
00498                 for (unsigned int i = 0; i < numNodes; ++i) {
00499                   DOMNode *childNode = childList->item(i);
00500                   if (childNode->getNodeType() != DOMNode::ELEMENT_NODE) {
00501                     continue;
00502                   }
00503                   DOMElement *child = static_cast<DOMElement *>(childNode);
00504                   m_nativeProtocols.push_back(_toString(child->getAttribute(prefixXMLCh)));
00505                 }
00506                 m_nativeProtocolsPtr = &m_nativeProtocols;
00507               }
00508             }
00509           }
00510         }
00511         m_connected = true;
00512       }
00513       catch (xercesc::DOMException const& e) {
00514       }
00515     }
00516 
00517     void
00518     SiteLocalConfigService::computeStatisticsDestination() {
00519       std::vector<std::string> inputStrings;
00520       boost::split(inputStrings, m_statisticsDestination, boost::is_any_of(":"));
00521       const std::string &host=inputStrings[0];
00522       const std::string &port = (inputStrings.size() > 1) ? inputStrings[1] : m_statisticsDefaultPort;
00523       struct addrinfo *res;
00524       struct addrinfo hints;
00525       memset(&hints, '\0', sizeof(hints));
00526       hints.ai_socktype = SOCK_DGRAM;
00527       hints.ai_flags = AI_ADDRCONFIG;
00528       hints.ai_family = AF_UNSPEC;
00529       int e = getaddrinfo(host.c_str(), port.c_str(), &hints, &res);
00530       if (e != 0) {
00531         // Silent failure - there's no way to report non-fatal failures from here.
00532         return;
00533       }
00534       m_statisticsAddrInfo = res;
00535     }
00536 
00537     void
00538     SiteLocalConfigService::fillDescriptions(ConfigurationDescriptions& descriptions) {
00539       ParameterSetDescription desc;
00540       desc.setComment("Service to translate logical file names to physical file names.");
00541 
00542       desc.addOptionalUntracked<std::string>("overrideSourceCacheTempDir");
00543       desc.addOptionalUntracked<double>("overrideSourceCacheMinFree");
00544       desc.addOptionalUntracked<std::string>("overrideSourceCacheHintDir");
00545       desc.addOptionalUntracked<std::string>("overrideSourceReadHint");
00546       desc.addOptionalUntracked<std::vector<std::string> >("overrideSourceNativeProtocols");
00547       desc.addOptionalUntracked<unsigned int>("overrideSourceTTreeCacheSize");
00548       desc.addOptionalUntracked<unsigned int>("overrideSourceTimeout");
00549       desc.addOptionalUntracked<unsigned int>("debugLevel");
00550       desc.addOptionalUntracked<bool>("overridePrefetching")
00551         ->setComment("Request ROOT to asynchronously prefetch I/O during computation.");
00552       desc.addOptionalUntracked<std::string>("overrideStatisticsDestination")
00553         ->setComment("Provide an alternate network destination for I/O statistics (must be in the form of host:port).");
00554 
00555       descriptions.add("SiteLocalConfigService", desc);
00556     }
00557   }
00558 }