7 #include "cetlib/split.h" 26 split_to_pair(
string const& to_split)
30 cet::split(to_split,
':', std::back_inserter(tmp));
40 <<
"Expected \"key:value\", got multiple \":\".\n";
45 check_metadata_options(bpo::variables_map
const& vm)
47 auto check_for_conflicting_options =
48 [&vm](
string const& firstOpt, std::initializer_list<string> opts) {
49 for (
auto const& opt : opts) {
50 if (vm.count(opt) + vm.count(firstOpt) > 1)
52 <<
"The options '--" << opt <<
"' and '--" << firstOpt
53 <<
"' are mutually exclusive.";
57 check_for_conflicting_options(
58 "sam-file-type", {
"sam-inherit-metadata",
"sam-inherit-file-type"});
59 check_for_conflicting_options(
60 "sam-run-type", {
"sam-inherit-metadata",
"sam-inherit-run-type"});
64 fill_tiers_streams(bpo::variables_map
const& vm,
69 auto const& table = raw_config.
get<
table_t const&>(
"outputs");
70 string const outputs_stem{
"outputs"};
71 string const tier_spec_stem{
"dataTier"};
72 string const stream_name_stem{
"streamName"};
73 vector<string> data_tiers((vm.count(
"sam-data-tier") > 0) ?
74 vm[
"sam-data-tier"].as<vector<string>>() :
76 vector<string> stream_names((vm.count(
"sam-stream-name") > 0) ?
77 vm[
"sam-stream-name"].as<vector<string>>() :
79 std::map<string, string> sep_tiers, sep_streams;
80 for (
auto const& tier : data_tiers) {
81 sep_tiers.insert(split_to_pair(tier));
83 for (
auto const& stream : stream_names) {
84 sep_streams.insert(split_to_pair(stream));
86 auto const def_tier_it(sep_tiers.find(
"_default"));
87 auto const def_tier((def_tier_it != sep_tiers.end()) ? def_tier_it->second :
89 auto const def_stream_it(sep_streams.find(
"_default"));
90 auto const def_stream(
91 (def_stream_it != sep_streams.end()) ? def_stream_it->second :
"");
92 for (
auto const& output : table) {
94 raw_config,
fhicl_key(outputs_stem, output.first,
"module_type"))) {
97 auto const& tier_spec_key =
98 fhicl_key(outputs_stem, output.first, tier_spec_stem);
99 auto const& stream_name_key =
100 fhicl_key(outputs_stem, output.first, stream_name_stem);
101 auto tiers_it(sep_tiers.find(output.first));
103 if (tiers_it != sep_tiers.end()) {
104 tier = tiers_it->second;
109 raw_config.
put(tier_spec_key, tier);
111 auto streams_it(sep_streams.find(output.first));
113 if (streams_it != sep_streams.end()) {
114 stream = streams_it->second;
116 stream = (!def_stream.empty()) ? def_stream : output.first;
118 if (!stream.empty()) {
119 raw_config.
put(stream_name_key, stream);
124 <<
"Output \"" << output.first <<
"\" must be configured with " 125 << tier_spec_stem <<
" (--sam-data-tier=" << output.first
126 <<
":<tier>) and " << stream_name_stem
127 <<
" (--sam-stream-name=" << output.first <<
":<stream>).\n";
137 auto const& ev = table.
find(
"outputs");
150 string const key_stem{
"services.FileCatalogMetadata."};
151 vector<string> missingItems;
153 missingItems.emplace_back(key_stem +
154 "applicationFamily (--sam-application-family)");
157 missingItems.emplace_back(
158 key_stem +
"applicationVersion (--sam-application-version)");
161 missingItems.emplace_back(key_stem +
"group (--sam-group)");
163 if (!missingItems.empty()) {
165 e <<
"SAM metadata information is required -- missing metadata:\n";
166 for (
auto const& s : missingItems) {
175 bpo::options_description& desc)
177 bpo::options_description sam_options{
"SAM options"};
179 sam_options.add_options()
180 (
"sam-web-uri", bpo::value<string>(),
"URI for SAM web service.")
181 (
"sam-process-id", bpo::value<string>(),
"SAM process ID.")
182 (
"sam-application-family",
183 bpo::value<string>(&
appFamily_),
"SAM application family.")
185 bpo::value<string>(&
appFamily_),
"SAM application family.")
186 (
"sam-application-version",
187 bpo::value<string>(&
appVersion_),
"SAM application version.")
189 bpo::value<string>(&
appVersion_),
"SAM application version.")
190 (
"sam-group", bpo::value<string>(),
"SAM group.")
191 (
"sam-file-type", bpo::value<string>(),
"File type for SAM metadata.")
193 bpo::value<vector<string>>(),
194 "SAM data tier (<spec-label>:<tier-spec>).")
195 (
"sam-run-type", bpo::value<string>(),
"Global run-type for SAM metadata.")
197 bpo::value<vector<string>>(),
198 "SAM stream name (<module-label>:<stream-name>).")
199 (
"sam-inherit-metadata",
"Input file provides the file type and run type.")
200 (
"sam-inherit-file-type",
"Input file provides the file type.")
201 (
"sam-inherit-run-type",
"Input file provides the run type.");
203 desc.add(sam_options);
215 bpo::variables_map
const& vm,
218 std::string
const services{
"services"};
219 auto const& ciLocation =
fhicl_key(services,
"CatalogInterface");
220 auto const& ftLocation =
fhicl_key(services,
"FileTransfer");
221 auto const& fcmdLocation =
fhicl_key(services,
"FileCatalogMetadata");
227 if (vm.count(
"sam-web-uri") > 0) {
229 vm[
"sam-web-uri"].as<string>());
231 if (vm.count(
"sam-process-id") > 0) {
233 raw_config.
put(
"source.fileNames",
234 vector<string>{vm[
"sam-process-id"].as<
string>()});
237 vm[
"sam-process-id"].as<string>());
241 raw_config,
fhicl_key(fcmdLocation,
"processID"))) {
243 <<
"configurations " <<
fhicl_key(ciLocation,
"webURI")
244 <<
" (--sam-web-uri) and\n" 246 <<
" (--sam-process-id) must be specified\n" 247 <<
"together or not at all.\n";
249 bool const wantSAMweb{
256 if (vm.count(
"sam-group") > 0) {
258 vm[
"sam-group"].as<string>());
264 check_metadata_options(vm);
266 string const mdFromInput{
"metadataFromInput"};
267 bool specifyDataTier{
false};
271 if (vm.count(
"sam-inherit-metadata") > 0) {
273 vector<string>{
"fileType",
"runType"});
274 specifyDataTier =
true;
279 if (vm.count(
"sam-inherit-file-type") > 0) {
280 md.emplace_back(
"file_type");
281 specifyDataTier =
true;
284 if (vm.count(
"sam-inherit-run-type") > 0) {
287 md.emplace_back(
"art.run_type");
291 raw_config.
put(
fhicl_key(fcmdLocation, mdFromInput), md);
295 if (vm.count(
"sam-run-type") > 0) {
297 vm[
"sam-run-type"].as<string>());
299 if (vm.count(
"sam-file-type") > 0) {
301 vm[
"sam-file-type"].as<string>());
303 bool const requireMetadata =
304 have_outputs(raw_config) &&
307 fhicl_key(fcmdLocation,
"applicationFamily")) ||
309 fhicl_key(fcmdLocation,
"applicationVersion")) ||
314 if (requireMetadata) {
315 fill_tiers_streams(vm, raw_config);
316 maybeThrowOnMissingMetadata(raw_config);
321 process_name = raw_config.
get<
string>(
"process_name");
323 if (requireMetadata && process_name.empty()) {
325 <<
"Non-empty / default process_name required for SAM metadata.\n";
328 raw_config.
put(
fhicl_key(ciLocation,
"service_provider"),
329 "IFCatalogInterface");
330 raw_config.
put(
fhicl_key(ftLocation,
"service_provider"),
"IFFileTransfer");
FileCatalogOptionsHandler(bpo::options_description &desc)
bool exists_outside_prolog(fhicl::intermediate_table const &config, std::string const &key)
int doProcessOptions(bpo::variables_map const &vm, fhicl::intermediate_table &raw_config) override
int doCheckOptions(bpo::variables_map const &vm) override
void ensureTable(fhicl::intermediate_table &table, std::string const &fhicl_spec)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::enable_if_t< std::is_convertible_v< T, std::string >, std::string > fhicl_key(T const &name)
shims::map< std::string, extended_value > table_t
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
std::pair< std::string const, std::string > string_pair_t