Belle II Software prerelease-11-00-00a
HSFCentralMetadataProvider Class Reference

Class to obtain payload metadata from the HSF central server via REST requests. More...

#include <HSFCentralMetadataProvider.h>

Inheritance diagram for HSFCentralMetadataProvider:
Collaboration diagram for HSFCentralMetadataProvider:

Public Types

using PayloadMap = std::unordered_map<std::string, PayloadMetadata>
 Type for the internal list of payloads.
 

Public Member Functions

 HSFCentralMetadataProvider (const std::set< std::string > &usableTagStates)
 Create using the default HSF central base URL and given usable tag states.
 
 HSFCentralMetadataProvider (std::string baseUrl, const std::set< std::string > &usableTagStates)
 Create using a custom base URL for the HSF central server.
 
virtual ~HSFCentralMetadataProvider ()=default
 default destructor
 
std::string getGlobaltagStatus (const std::string &name) override
 Check the status of a given globaltag.
 
bool updatePayloads (const std::string &globaltag, int exp, int run) override
 Update the list of known payloads for the given globaltag/exp/run.
 
bool setTags (const std::vector< std::string > &tags)
 Set the list of globaltag names to be considered for payloads.
 
bool getPayloads (int exp, int run, std::vector< PayloadMetadata > &info)
 Update the information in the vector of metadata instances with the actual values.
 
std::set< std::string > getUsableTagStates ()
 Get the valid tag states when checking globaltag status.
 
void setUsableTagStates (const std::set< std::string > &states)
 Set the valid tag states for this provider when checking globaltag status.
 

Protected Member Functions

void addPayload (PayloadMetadata &&payload, const std::string &messagePrefix="")
 Add a payload information to the internal list.
 
void printInfoMessage (const std::string &provider)
 Print an INFO message about the used metadata provider.
 

Protected Attributes

std::vector< std::string > m_tags
 List of globaltags to consider.
 
std::unordered_map< std::string, PayloadMetadataCachem_cache
 Map of globaltag->known metadata.
 
PayloadMapm_payloads {nullptr}
 Map of known payloads for current conditions.
 
std::set< std::string > m_usableTagStates {"TESTING", "VALIDATED", "RUNNING", "PUBLISHED"}
 Set of global tag states to consider valid (except for 'INVALID' which is always considered invalid)
 

Private Member Functions

nlohmann::json get (const std::string &url)
 Download a given relative url (the baseUrl will be prepended) and return the json description.
 

Private Attributes

Downloaderm_downloader {Downloader::getDefaultInstance()}
 Reference to the downloader instance for convenience.
 
std::string m_baseUrl
 base url of the server
 
std::string m_payloadBaseUrl
 base url of the payload server
 

Static Private Attributes

static constexpr long long m_maxIoV = 9223372036854775807
 Max IoV value, representing infinite end of validity.
 

Detailed Description

Class to obtain payload metadata from the HSF central server via REST requests.

This class connects to the Belle II HSF central server instead of the main Belle II conditions database server. It provides the same functionality as CentralMetadataProvider but uses a different base URL and a different API.

Definition at line 21 of file HSFCentralMetadataProvider.h.

Member Typedef Documentation

◆ PayloadMap

using PayloadMap = std::unordered_map<std::string, PayloadMetadata>
inherited

Type for the internal list of payloads.

Definition at line 30 of file MetadataProvider.h.

Constructor & Destructor Documentation

◆ HSFCentralMetadataProvider()

HSFCentralMetadataProvider ( std::string baseUrl,
const std::set< std::string > & usableTagStates )

Create using a custom base URL for the HSF central server.

Definition at line 19 of file HSFCentralMetadataProvider.cc.

19 :
20 MetadataProvider(usableTagStates), m_baseUrl(std::move(baseUrl))
21 {
22 // We want to be sure on construction that the server is working. So let's
23 // just check the list of valid states
24 const auto result = get("/gtstatus");
25 // check list of valid states
26 auto validStates = getUsableTagStates();
27 std::string invalidStates = "";
28 for (const auto& info : result) {
29 const std::string status = info.at("name");
30 if (not validStates.erase(status)) {
31 if (!invalidStates.empty()) invalidStates += ", ";
32 invalidStates += status;
33 }
34 }
35 B2DEBUG(31, "Infinite IoV value is set to " << m_maxIoV);
36 printInfoMessage(m_baseUrl);
37 B2DEBUG(31, "Conditions Database: unusable globaltag states: " << invalidStates);
38 for (const auto& status : validStates) {
39 B2DEBUG(31, "Conditions Database: status marked as usable for global tags is not known to the database"
40 << LogVar("status", status));
41
42 }
43 const auto payloadUrl = get("user_settings/CDB_PAYLOAD_BASE_URL");
44 m_payloadBaseUrl = payloadUrl.at("CDB_PAYLOAD_BASE_URL");
45 B2DEBUG(31, "Fetched payload location" << LogVar("URL", m_payloadBaseUrl));
46 }

Member Function Documentation

◆ addPayload()

void addPayload ( PayloadMetadata && payload,
const std::string & messagePrefix = "" )
protectedinherited

Add a payload information to the internal list.

This should be called by implementations during updatePayloads() for each payload found.

Parameters
payloadpayload information filled from the globaltag
messagePrefixa message prefix to be shown for possible log messages to indicate the correct metadata provider

Definition at line 91 of file MetadataProvider.cc.

92 {
93 const auto [it, inserted] = m_payloads->emplace(payload.name, payload);
94 if (!inserted) {
95 auto& existing = it->second;
96 if (existing.revision < payload.revision) {
97 std::swap(existing, payload);
98 }
99 B2DEBUG(36, messagePrefix << (messagePrefix.empty() ? "" : ": ") << "Found duplicate payload. Discarding one of them"
100 << LogVar("globaltag", existing.globaltag)
101 << LogVar("name", existing.name)
102 << LogVar("revision", existing.revision)
103 << LogVar("checksum", existing.checksum)
104 << LogVar("discarded revision", payload.revision));
105 } else {
106 B2DEBUG(37, messagePrefix << (messagePrefix.empty() ? "" : ": ") << "Found payload"
107 << LogVar("globaltag", payload.globaltag)
108 << LogVar("name", payload.name)
109 << LogVar("revision", payload.revision)
110 << LogVar("checksum", payload.checksum));
111 }
112 }

◆ get()

json get ( const std::string & url)
private

Download a given relative url (the baseUrl will be prepended) and return the json description.

Will raise exceptions on error

Definition at line 48 of file HSFCentralMetadataProvider.cc.

49 {
50 std::stringstream stream;
51 const auto fullUrl = m_downloader.joinWithSlash(m_baseUrl, url);
52 m_downloader.download(fullUrl, stream);
53 stream.clear();
54 stream.seekg(0, std::ios::beg);
55 return json::parse(stream);
56 }

◆ getGlobaltagStatus()

std::string getGlobaltagStatus ( const std::string & name)
overridevirtual

Check the status of a given globaltag.

Returns
the status of the globaltag (like "OPEN", "INVALID", "PUBLISHED"). Returns empty string on any errors or if the tag doesn't exist.

Implements MetadataProvider.

Definition at line 58 of file HSFCentralMetadataProvider.cc.

59 {
60 auto escaped = m_downloader.escapeString(name);
61 const std::string url = "/globalTag/" + escaped;
62 try {
63 const auto gtinfo = get(url);
64 return gtinfo.at("status").at("name");
65 } catch (std::runtime_error& e) {
66 B2WARNING("Conditions Database: Cannot download information on global tag. "
67 "Either the database is overloaded or the selected globaltag doesn't exist"
68 << LogVar("server url", m_baseUrl) << LogVar("globaltag", name) << LogVar("query", url));
69 } catch (std::exception& e) {
70 B2WARNING("Conditions Database: Problem determining global tag status"
71 << LogVar("server url", m_baseUrl) << LogVar("globaltag", name) << LogVar("query", url) << LogVar("error", e.what()));
72 }
73 return "";
74 }

◆ getPayloads()

bool getPayloads ( int exp,
int run,
std::vector< PayloadMetadata > & info )
inherited

Update the information in the vector of metadata instances with the actual values.

The input is a list of metadata instances and the metadata provider will try to modify them in place and add all the missing information it can find.

  • It will try to find iov, revision, checksum, url for each entry which doesn't have a valid revision number (revision=0)
  • It will ignore any entries with a valid revision number (revision>0)
  • any payload which cannot be found in any globaltag will raise an error as long as required=true
  • the modified list can still contain payloads without a valid revision some payloads could not be found.

This function will call updatePayloads() if necessary to update the list of known payloads for a given run but it will try to cache these results so incrementally asking for new payloads as they get requested is perfectly fine.

updatePayloads() will only called for globaltags if we still need to find payload information. If all payloads are found no further queries will be made so adding additional globaltags that are not used at the end is not expensive.

Parameters
expthe experiment number
runthe run number
[in,out]infoa list of metadata instances which we try to find the missing metadata for.
Returns
true if all required payloads could be found, false if at least one payload which still didn't have a valid revision number and is required could not be found.

Definition at line 36 of file MetadataProvider.cc.

37 {
38 if (info.empty()) return true;
39 for (const auto& tag : m_tags) {
40 // Check whether we already know the payloads for this exp,run ...
41 bool present{false};
42 std::tie(present, m_payloads) = m_cache[tag].get(exp, run);
43 // Apparently not, try to get them
44 if (!present && !updatePayloads(tag, exp, run)) {
45 // Error obtaining payloads means something is wrong (server/network/file problem).
46 // In this case we want to fall back to next metadata provider ...
47 throw std::runtime_error("Problem updating metadata");
48 }
49 // And once we got them let's update the info for all requested payloads
50 const auto& existing = *m_payloads;
51 // and check if we found all payloads we're looking for.
52 // Warning: **DO NOT** use `std::all_of` here which looks better but stops
53 // iteration on the first missing payload instead of going through all the
54 // remaining as well.
55 const size_t found = std::count_if(info.begin(), info.end(), [&existing](auto & payload) {
56 // already filled by previous gt or has a filename from testing payloads ... so don't do anything
57 if (payload.revision > 0 or !payload.filename.empty()) return true;
58 // otherwise look for the payload in the list of existing payloads for this run
59 if (auto&& it = existing.find(payload.name); it != existing.end()) {
60 payload.update(it->second);
61 B2DEBUG(35, "Found requested payload metadata"
62 << LogVar("globaltag", payload.globaltag)
63 << LogVar("name", payload.name)
64 << LogVar("revision", payload.revision)
65 << LogVar("checksum", payload.checksum));
66 return true;
67 }
68 // Not found, fine, not a big problem yet, there can be multiple global tags
69 return false;
70 });
71 // If we found all we don't need to check the next global tag at all ...
72 if (found == info.size()) break;
73 }
74 // Check that all payloads could be found (unless they're optional)
75 // Again, we don't use std::all_of here because then it stops early and we
76 // don't get errors for all missing payloads. But at least it would still be correct.
77 const int missing = std::count_if(info.begin(), info.end(), [this, exp, run](const auto & p) {
78 if (p.revision == 0 and p.filename.empty() and p.required) {
79 B2ERROR("Cannot find payload in any of the configured global tags"
80 << LogVar("name", p.name)
81 << LogVar("globaltags", boost::algorithm::join(m_tags, ", "))
82 << LogVar("experiment", exp) << LogVar("run", run));
83 return true;
84 }
85 return false;
86 });
87 // Only happy without missing payloads
88 return missing == 0;
89 }

◆ getUsableTagStates()

std::set< std::string > getUsableTagStates ( )
inlineinherited

Get the valid tag states when checking globaltag status.

Definition at line 122 of file MetadataProvider.h.

122{ return m_usableTagStates; }

◆ printInfoMessage()

void printInfoMessage ( const std::string & provider = "")
protectedinherited

Print an INFO message about the used metadata provider.

Parameters
providerthe actual metadata provider used for the job

Definition at line 114 of file MetadataProvider.cc.

115 {
116 B2INFO("Conditions Database: found working metadata provider"
117 << LogVar("provider", provider));
118 }

◆ setTags()

bool setTags ( const std::vector< std::string > & tags)
inherited

Set the list of globaltag names to be considered for payloads.

This should be called before requesting any payloads but after calling setValidTagStates().

Returns
true if all globaltags can be found and are in a valid state

Definition at line 15 of file MetadataProvider.cc.

16 {
17 m_tags = tags;
18 const size_t validTags = std::count_if(m_tags.begin(), m_tags.end(), [this](const auto & name) {
19 // dispatch obtaining the state to the implementation
20 auto status = getGlobaltagStatus(name);
21 // empty status: Unspecified error already dealt with
22 if (status.empty()) return false;
23 // otherwise check for valid states
24 if (m_usableTagStates.count(status) == 0) {
25 B2ERROR("The globaltag has a status which is not permitted for use. This is for your own protection"
26 << LogVar("globaltag", name)
27 << LogVar("status", status)
28 << LogVar("allowed states", boost::algorithm::join(m_usableTagStates, ", ")));
29 return false;
30 }
31 return true;
32 });
33 return validTags == tags.size();
34 }

◆ setUsableTagStates()

void setUsableTagStates ( const std::set< std::string > & states)
inlineinherited

Set the valid tag states for this provider when checking globaltag status.

Should be called before setTags() if necessary.

Warning
The state "INVALID" will never be accepted and removed from the given set if present

Definition at line 128 of file MetadataProvider.h.

129 {
130 m_usableTagStates = states;
131 m_usableTagStates.erase("INVALID");
132 }

◆ updatePayloads()

bool updatePayloads ( const std::string & globaltag,
int exp,
int run )
overridevirtual

Update the list of known payloads for the given globaltag/exp/run.

This basically just calls addPayload() for each payload it finds in the globaltag for the given exp/run.

Returns
true on success, false on any error

Implements MetadataProvider.

Definition at line 76 of file HSFCentralMetadataProvider.cc.

77 {
78 auto escaped = m_downloader.escapeString(globaltag);
79 const std::string url = "payloadiovs/?gtName=" + escaped +
80 "&majorIOV=" + std::to_string(exp) +
81 "&minorIOV=" + std::to_string(run) +
82 "&shape=dict";
83 try {
84 const auto payloads = get(url);
85 if (!payloads.is_array()) throw std::runtime_error("expected array");
86 for (const auto& payload : payloads) {
87 if (!payload.is_object()) throw std::runtime_error("expected payload object");
88
89 const long long int experimentHighFromServer = payload.at("major_iov_end");
90 const long long int runHighFromServer = payload.at("minor_iov_end");
91
92 // The infinite IoV is represented by m_maxIoV; in basf2 we replace it for -1 for historical reasons
93 const long long int experimentHigh = (experimentHighFromServer == m_maxIoV) ? -1 : experimentHighFromServer;
94 const long long int runHigh = (runHighFromServer == m_maxIoV) ? -1 : runHighFromServer;
95
96 // Check if the current (exp, run) falls into the payload IoV:
97 // if yes, let's keep the payload, otherwise skip it.
98 const IntervalOfValidity iov{payload.at("major_iov"), payload.at("minor_iov"), static_cast<int>(experimentHigh), static_cast<int>(runHigh)};
99 if (iov.contains(exp, run)) {
100 addPayload(PayloadMetadata(
101 payload.at("payload_type_name"),
102 globaltag,
103 payload.at("payload_url"),
104 m_payloadBaseUrl,
105 payload.at("checksum"),
106 iov.getExperimentLow(),
107 iov.getRunLow(),
108 iov.getExperimentHigh(),
109 iov.getRunHigh(),
110 convertString<unsigned long int>(payload.at("revision"))
111 ));
112 B2DEBUG(31, "Conditions Database: added payload from new central server"
113 << LogVar("Payload type name", payload.at("payload_type_name"))
114 << LogVar("url", payload.at("payload_url"))
115 << LogVar("checksum", payload.at("checksum")));
116 }
117 }
118
119 B2DEBUG(31, "Conditions Database: fetched " << payloads.size() << " payloads for globaltag"
120 << LogVar("globaltag", globaltag) << LogVar("exp", exp) << LogVar("run", run));
121 } catch (std::exception& e) {
122 B2WARNING("Conditions Database: Problem while fetching the list of payloads"
123 << LogVar("globaltag", globaltag) << LogVar("server url", m_baseUrl) << LogVar("query", url) << LogVar("error", e.what()));
124 return false;
125 }
126 return true;
127 }

Member Data Documentation

◆ m_baseUrl

std::string m_baseUrl
private

base url of the server

Definition at line 54 of file HSFCentralMetadataProvider.h.

◆ m_cache

std::unordered_map<std::string, PayloadMetadataCache> m_cache
protectedinherited

Map of globaltag->known metadata.

Definition at line 172 of file MetadataProvider.h.

◆ m_downloader

Downloader& m_downloader {Downloader::getDefaultInstance()}
private

Reference to the downloader instance for convenience.

Definition at line 51 of file HSFCentralMetadataProvider.h.

51{Downloader::getDefaultInstance()};

◆ m_maxIoV

long long m_maxIoV = 9223372036854775807
staticconstexprprivate

Max IoV value, representing infinite end of validity.

Definition at line 60 of file HSFCentralMetadataProvider.h.

◆ m_payloadBaseUrl

std::string m_payloadBaseUrl
private

base url of the payload server

Definition at line 57 of file HSFCentralMetadataProvider.h.

◆ m_payloads

PayloadMap* m_payloads {nullptr}
protectedinherited

Map of known payloads for current conditions.

Definition at line 174 of file MetadataProvider.h.

174{nullptr};

◆ m_tags

std::vector<std::string> m_tags
protectedinherited

List of globaltags to consider.

Definition at line 170 of file MetadataProvider.h.

◆ m_usableTagStates

std::set<std::string> m_usableTagStates {"TESTING", "VALIDATED", "RUNNING", "PUBLISHED"}
protectedinherited

Set of global tag states to consider valid (except for 'INVALID' which is always considered invalid)

Definition at line 176 of file MetadataProvider.h.

176{"TESTING", "VALIDATED", "RUNNING", "PUBLISHED"};

The documentation for this class was generated from the following files: