Belle II Software prerelease-11-00-00a
HSFCentralMetadataProvider.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/database/HSFCentralMetadataProvider.h>
10#include <framework/database/MetadataProvider.h>
11#include <framework/database/Downloader.h>
12#include <framework/logging/Logger.h>
13#include <framework/utilities/Conversion.h>
14
15using json = nlohmann::json;
16
17namespace Belle2::Conditions {
18
19 HSFCentralMetadataProvider::HSFCentralMetadataProvider(std::string baseUrl, const std::set<std::string>& usableTagStates):
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);
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 }
47
48 json HSFCentralMetadataProvider::get(const std::string& url)
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 }
57
58 std::string HSFCentralMetadataProvider::getGlobaltagStatus(const std::string& name)
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 }
75
76 bool HSFCentralMetadataProvider::updatePayloads(const std::string& globaltag, int exp, int run)
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)) {
101 payload.at("payload_type_name"),
102 globaltag,
103 payload.at("payload_url"),
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 }
128
129} // Belle2::Conditions namespace
std::string getGlobaltagStatus(const std::string &name) override
Check the status of a given globaltag.
HSFCentralMetadataProvider(const std::set< std::string > &usableTagStates)
Create using the default HSF central base URL and given usable tag states.
bool updatePayloads(const std::string &globaltag, int exp, int run) override
Update the list of known payloads for the given globaltag/exp/run.
Downloader & m_downloader
Reference to the downloader instance for convenience.
static constexpr long long m_maxIoV
Max IoV value, representing infinite end of validity.
nlohmann::json get(const std::string &url)
Download a given relative url (the baseUrl will be prepended) and return the json description.
std::string m_payloadBaseUrl
base url of the payload server
std::set< std::string > getUsableTagStates()
Get the valid tag states when checking globaltag status.
MetadataProvider()=default
Default constructible.
void printInfoMessage(const std::string &provider)
Print an INFO message about the used metadata provider.
void addPayload(PayloadMetadata &&payload, const std::string &messagePrefix="")
Add a payload information to the internal list.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Class to store variables with their name which were sent to the logging service.
T convertString(const std::string &str)
Converts a string to type T (one of float, double, long double, int, long int, unsigned long int).
STL namespace.
Simple struct to group all information necessary for a single payload.