CMS 3D CMS Logo

FileLocator.cc
Go to the documentation of this file.
4 
5 #include <boost/algorithm/string.hpp>
6 #include <boost/algorithm/string/replace.hpp>
7 
8 #include <cstdlib>
9 #include <stdexcept>
10 #include <fstream>
11 #include <iostream>
12 #include <sstream>
13 
14 namespace {
15 
16  std::string replaceWithRegexp(std::smatch const& matches, std::string const& outputFormat) {
17  std::string result = outputFormat;
18  std::stringstream str;
19 
20  // std::cerr << "Output format: "<< outputFormat << std::endl;
21  for (size_t i = 1; i < matches.size(); ++i) {
22  str.str("");
23  str << "$" << i;
24  // std::cerr << "Current match: " << matches[i] << std::endl;
25  std::string const matchedString(matches[i].first, matches[i].second);
26  if (!matchedString.empty())
27  boost::algorithm::replace_all(result, str.str(), matchedString);
28  }
29  // std::cerr << "Final string: " << result << std::endl;
30  return result;
31  }
32 
33  constexpr char const* const kEmptyString = "";
34 
35  const char* safe(const char* iCheck) {
36  if (iCheck == nullptr) {
37  return kEmptyString;
38  }
39  return iCheck;
40  }
41 
42 } // namespace
43 
44 namespace edm {
45  FileLocator::FileLocator(std::string const& catUrl, unsigned iCatalog) : m_destination("any") {
46  init(catUrl, iCatalog);
47 
48  // std::cout << m_protocols.size() << " protocols" << std::endl;
49  // std::cout << m_directRules[m_protocols[0]].size() << " rules" << std::endl;
50  }
51 
53 
54  std::string FileLocator::pfn(std::string const& ilfn) const { return convert(ilfn, m_directRules, true); }
55 
56  std::string FileLocator::lfn(std::string const& ipfn) const { return convert(ipfn, m_inverseRules, false); }
57 
59  std::string out = "";
60 
61  for (size_t pi = 0, pe = m_protocols.size(); pi != pe; ++pi) {
63  if (!out.empty())
64  return out;
65  }
66  return out;
67  }
68 
69  void FileLocator::parseRule(tinyxml2::XMLElement* ruleElement, ProtocolRules& rules) {
70  if (!ruleElement) {
71  throw cms::Exception("TrivialFileCatalog", std::string("TrivialFileCatalog::connect: Malformed trivial catalog"));
72  }
73 
74  auto const protocol = safe(ruleElement->Attribute("protocol"));
75  auto destinationMatchRegexp = ruleElement->Attribute("destination-match");
76  if (destinationMatchRegexp == nullptr or destinationMatchRegexp[0] == 0) {
77  destinationMatchRegexp = ".*";
78  }
79 
80  auto const pathMatchRegexp = safe(ruleElement->Attribute("path-match"));
81  auto const result = safe(ruleElement->Attribute("result"));
82  auto const chain = safe(ruleElement->Attribute("chain"));
83 
84  Rule rule;
85  rule.pathMatch.assign(pathMatchRegexp);
86  rule.destinationMatch.assign(destinationMatchRegexp);
87  rule.result = result;
88  rule.chain = chain;
89  rules[protocol].emplace_back(std::move(rule));
90  }
91 
92  void FileLocator::init(std::string const& catUrl, unsigned iCatalog) {
93  std::string m_url = catUrl;
94 
95  if (m_url.empty()) {
96  Service<SiteLocalConfig> localconfservice;
97  if (!localconfservice.isAvailable())
98  throw cms::Exception("TrivialFileCatalog", "edm::SiteLocalConfigService is not available");
99  if (iCatalog >= localconfservice->dataCatalogs().size())
100  throw cms::Exception("TrivialFileCatalog", "edm::FileLocator: Request nonexistence data catalog");
101  m_url = localconfservice->dataCatalogs()[iCatalog];
102  }
103 
104  if (m_url.find("file:") == std::string::npos) {
105  throw cms::Exception("TrivialFileCatalog",
106  "TrivialFileCatalog::connect: Malformed url for file catalog configuration");
107  }
108 
109  m_url = m_url.erase(0, m_url.find(":") + 1);
110 
111  std::vector<std::string> tokens;
112  boost::algorithm::split(tokens, m_url, boost::is_any_of(std::string("?")));
113  m_filename = tokens[0];
114 
115  if (tokens.size() == 2) {
116  std::string const options = tokens[1];
117  std::vector<std::string> optionTokens;
118  boost::algorithm::split(optionTokens, options, boost::is_any_of(std::string("&")));
119 
120  std::string const equalSign("=");
121  std::string const comma(",");
122 
123  for (size_t oi = 0, oe = optionTokens.size(); oi != oe; ++oi) {
124  std::string const option = optionTokens[oi];
125  std::vector<std::string> argTokens;
126  boost::algorithm::split(argTokens, option, boost::is_any_of(equalSign));
127 
128  if (argTokens.size() != 2) {
129  throw cms::Exception("TrivialFileCatalog",
130  "TrivialFileCatalog::connect: Malformed url for file catalog configuration");
131  }
132 
133  if (argTokens[0] == "protocol") {
134  boost::algorithm::split(m_protocols, argTokens[1], boost::is_any_of(comma));
135  } else if (argTokens[0] == "destination") {
136  m_destination = argTokens[1];
137  }
138  }
139  }
140 
141  if (m_protocols.empty()) {
142  throw cms::Exception("TrivialFileCatalog",
143  "TrivialFileCatalog::connect: protocol was not supplied in the contact string");
144  }
145 
146  std::ifstream configFile;
147  configFile.open(m_filename.c_str());
148 
149  //
150  // std::cout << "Using catalog configuration " << m_filename << std::endl;
151 
152  if (!configFile.good() || !configFile.is_open()) {
153  throw cms::Exception("TrivialFileCatalog",
154  "TrivialFileCatalog::connect: Unable to open trivial file catalog " + m_filename);
155  }
156 
157  configFile.close();
158 
159  tinyxml2::XMLDocument doc;
160  auto loadErr = doc.LoadFile(m_filename.c_str());
161  if (loadErr != tinyxml2::XML_SUCCESS) {
162  throw cms::Exception("TrivialFileCatalog")
163  << "tinyxml file load failed with error : " << doc.ErrorStr() << std::endl;
164  }
165  /* trivialFileCatalog matches the following xml schema
166  FIXME: write a proper DTD
167  <storage-mapping>
168  <lfn-to-pfn protocol="direct" destination-match=".*"
169  path-match="lfn/guid match regular expression"
170  result="/castor/cern.ch/cms/$1"/>
171  <pfn-to-lfn protocol="srm"
172  path-match="lfn/guid match regular expression"
173  result="$1"/>
174  </storage-mapping>
175  */
176  auto rootElement = doc.RootElement();
177  /*first of all do the lfn-to-pfn bit*/
178  for (auto el = rootElement->FirstChildElement("lfn-to-pfn"); el != nullptr;
179  el = el->NextSiblingElement("lfn-to-pfn")) {
181  }
182 
183  /*Then we handle the pfn-to-lfn bit*/
184  for (auto el = rootElement->FirstChildElement("pfn-to-lfn"); el != nullptr;
185  el = el->NextSiblingElement("pfn-to-lfn")) {
187  }
188  }
189 
191  std::string const& protocol,
192  std::string const& destination,
193  bool direct,
194  std::string name) const {
195  // std::cerr << "Calling apply rules with protocol: " << protocol << "\n destination: " << destination << "\n " << " on name " << name << std::endl;
196 
197  ProtocolRules::const_iterator const rulesIterator = protocolRules.find(protocol);
198  if (rulesIterator == protocolRules.end()) {
199  return "";
200  }
201 
202  Rules const& rules = (*(rulesIterator)).second;
203 
204  std::smatch destinationMatches;
205  std::smatch nameMatches;
206 
207  /* Look up for a matching rule*/
208  for (Rules::const_iterator i = rules.begin(); i != rules.end(); ++i) {
209  if (!std::regex_match(destination, destinationMatches, i->destinationMatch)) {
210  continue;
211  }
212 
213  if (!std::regex_match(name, i->pathMatch)) {
214  continue;
215  }
216 
217  // std::cerr << "Rule " << i->pathMatch << "matched! " << std::endl;
218 
219  std::string const chain = i->chain;
220  if ((direct == true) && (!chain.empty())) {
221  name = applyRules(protocolRules, chain, destination, direct, name);
222  if (name.empty()) {
223  return "";
224  }
225  }
226 
227  std::regex_match(name, nameMatches, i->pathMatch);
228  name = replaceWithRegexp(nameMatches, i->result);
229 
230  if ((direct == false) && (!chain.empty())) {
231  name = applyRules(protocolRules, chain, destination, direct, name);
232  }
233  return name;
234  }
235  return "";
236  }
237 } // namespace edm
common_cff.doc
doc
Definition: common_cff.py:54
mps_fire.i
i
Definition: mps_fire.py:355
input
static const std::string input
Definition: EdmProvDump.cc:48
edm
HLT enums.
Definition: AlignableModifier.h:19
findQualityFiles.comma
string comma
Definition: findQualityFiles.py:451
edm::FileLocator::Rule::pathMatch
std::regex pathMatch
Definition: FileLocator.h:28
fwlite::kEmptyString
static const char kEmptyString[1]
Definition: DataGetterHelper.cc:47
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:215
edm::FileLocator::convert
std::string convert(std::string const &input, ProtocolRules const &rules, bool direct) const
Definition: FileLocator.cc:58
cms::dd::split
std::vector< std::string_view > split(std::string_view, const char *)
FileLocator.h
edm::Service::isAvailable
bool isAvailable() const
Definition: Service.h:40
fileinputsource_cfi.option
option
Definition: fileinputsource_cfi.py:87
dqmdumpme.first
first
Definition: dqmdumpme.py:55
options
Definition: options.py:1
edm::FileLocator::Rule
Definition: FileLocator.h:27
edm::FileLocator::pfn
std::string pfn(std::string const &ilfn) const
Definition: FileLocator.cc:54
Service.h
str
#define str(s)
Definition: TestProcessor.cc:48
edm::FileLocator::m_inverseRules
ProtocolRules m_inverseRules
Definition: FileLocator.h:52
edm::FileLocator::~FileLocator
~FileLocator()
Definition: FileLocator.cc:52
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::FileLocator::m_protocols
std::vector< std::string > m_protocols
Definition: FileLocator.h:56
edm::FileLocator::lfn
std::string lfn(std::string const &ipfn) const
Definition: FileLocator.cc:56
edm::FileLocator::m_destination
std::string m_destination
Definition: FileLocator.h:57
edm::FileLocator::m_filename
std::string m_filename
Definition: FileLocator.h:55
edm::FileLocator::init
void init(std::string const &catUrl, unsigned iCatalog)
Definition: FileLocator.cc:92
edm::Service
Definition: Service.h:30
edm::FileLocator::ProtocolRules
std::map< std::string, Rules > ProtocolRules
Definition: FileLocator.h:35
edm::FileLocator::Rules
std::vector< Rule > Rules
Definition: FileLocator.h:34
HLTMuonOfflineAnalyzer_cff.destination
destination
Definition: HLTMuonOfflineAnalyzer_cff.py:50
edm::FileLocator::parseRule
void parseRule(tinyxml2::XMLElement *ruleNode, ProtocolRules &rules)
Definition: FileLocator.cc:69
eostools.move
def move(src, dest)
Definition: eostools.py:511
edm::FileLocator::m_directRules
ProtocolRules m_directRules
Definition: FileLocator.h:50
edm::FileLocator::FileLocator
FileLocator(std::string const &catUrl, unsigned iCatalog=0)
Definition: FileLocator.cc:45
Exception
Definition: hltDiff.cc:246
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
or
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
patCandidatesForDimuonsSequences_cff.matches
matches
Definition: patCandidatesForDimuonsSequences_cff.py:131
MillePedeFileConverter_cfg.out
out
Definition: MillePedeFileConverter_cfg.py:31
mps_fire.result
result
Definition: mps_fire.py:303
pi
const Double_t pi
Definition: trackSplitPlot.h:36
cms::Exception
Definition: Exception.h:70
cmsCodeRulesChecker.rules
rules
Definition: cmsCodeRulesChecker.py:152
edm::FileLocator::applyRules
std::string applyRules(ProtocolRules const &protocolRules, std::string const &protocol, std::string const &destination, bool direct, std::string name) const
Definition: FileLocator.cc:190
chain
Definition: chain.py:1
SiteLocalConfig.h