| #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 = false; | |
| 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_ |