blob: f61bc843c0e52efe15ea00c65ac9c24ed2c5d067 [file] [log] [blame]
#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_EVENT_SERVICE_STORE_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_EVENT_SERVICE_STORE_H_
#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include "boost/beast/http/fields.hpp" // NOLINT
#include "boost/container/flat_map.hpp" // NOLINT
#include "logging.hpp"
#include <nlohmann/json.hpp>
namespace persistent_data {
struct UserSubscription {
// NOLINTBEGIN
std::string id;
std::string destinationUrl;
std::string protocol;
std::string retryPolicy;
std::string customText;
std::string eventFormatType;
std::string subscriptionType;
std::vector<std::string> registryMsgIds;
std::vector<std::string> registryPrefixes;
std::vector<std::string> resourceTypes;
boost::beast::http::fields httpHeaders;
std::vector<std::string> metricReportDefinitions;
// NOLINTEND
static std::shared_ptr<UserSubscription> fromJson(
const nlohmann::json& j, const bool loadFromOldConfig = false) {
std::shared_ptr<UserSubscription> subvalue =
std::make_shared<UserSubscription>();
for (const auto& element : j.items()) {
if (element.key() == "Id") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->id = *value;
} else if (element.key() == "Destination") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->destinationUrl = *value;
} else if (element.key() == "Protocol") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->protocol = *value;
} else if (element.key() == "DeliveryRetryPolicy") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->retryPolicy = *value;
} else if (element.key() == "Context") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->customText = *value;
} else if (element.key() == "EventFormatType") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->eventFormatType = *value;
} else if (element.key() == "SubscriptionType") {
const std::string* value =
element.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->subscriptionType = *value;
} else if (element.key() == "MessageIds") {
const auto& obj = element.value();
for (const auto& val : obj.items()) {
const std::string* value = val.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->registryMsgIds.push_back(*value);
}
} else if (element.key() == "RegistryPrefixes") {
const auto& obj = element.value();
for (const auto& val : obj.items()) {
const std::string* value = val.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->registryPrefixes.push_back(*value);
}
} else if (element.key() == "ResourceTypes") {
const auto& obj = element.value();
for (const auto& val : obj.items()) {
const std::string* value = val.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->resourceTypes.push_back(*value);
}
} else if (element.key() == "HttpHeaders") {
const auto& obj = element.value();
for (const auto& val : obj.items()) {
const std::string* value = val.value().get_ptr<const std::string*>();
if (value == nullptr) {
BMCWEB_LOG_ERROR << "Failed to parse value for key" << val.key();
continue;
}
subvalue->httpHeaders.set(val.key(), *value);
}
} else if (element.key() == "MetricReportDefinitions") {
const auto& obj = element.value();
for (const auto& val : obj.items()) {
const std::string* value = val.value().get_ptr<const std::string*>();
if (value == nullptr) {
continue;
}
subvalue->metricReportDefinitions.push_back(*value);
}
} else {
BMCWEB_LOG_ERROR << "Got unexpected property reading persistent file: "
<< element.key();
continue;
}
}
if ((subvalue->id.empty() && !loadFromOldConfig) ||
subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
subvalue->retryPolicy.empty() || subvalue->eventFormatType.empty() ||
subvalue->subscriptionType.empty()) {
BMCWEB_LOG_ERROR << "Subscription missing required field "
"information, refusing to restore";
return nullptr;
}
return subvalue;
}
};
struct EventServiceConfig {
bool enabled = true;
uint32_t retryAttempts = 3; // NOLINT
uint32_t retryTimeoutInterval = 30; // NOLINT
void fromJson(const nlohmann::json& j) {
for (const auto& element : j.items()) {
if (element.key() == "ServiceEnabled") {
const bool* value = element.value().get_ptr<const bool*>();
if (value == nullptr) {
continue;
}
enabled = *value;
} else if (element.key() == "DeliveryRetryAttempts") {
const uint64_t* value = element.value().get_ptr<const uint64_t*>();
if ((value == nullptr) ||
(*value > std::numeric_limits<uint32_t>::max())) {
continue;
}
retryAttempts = static_cast<uint32_t>(*value);
} else if (element.key() == "DeliveryRetryIntervalSeconds") {
const uint64_t* value = element.value().get_ptr<const uint64_t*>();
if ((value == nullptr) ||
(*value > std::numeric_limits<uint32_t>::max())) {
continue;
}
retryTimeoutInterval = static_cast<uint32_t>(*value);
}
}
}
};
class EventServiceStore {
public:
boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
subscriptionsConfigMap; // NOLINT
EventServiceConfig eventServiceConfig; // NOLINT
static EventServiceStore& getInstance() {
static EventServiceStore eventServiceStore; // NOLINT
return eventServiceStore;
}
EventServiceConfig& getEventServiceConfig() { return eventServiceConfig; }
};
} // namespace persistent_data
#endif // THIRD_PARTY_GBMCWEB_INCLUDE_EVENT_SERVICE_STORE_H_