summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunLin Chen <Jun-Lin.Chen@quantatw.com>2021-02-24 12:13:29 +0300
committerEd Tanous <ed@tanous.net>2021-07-26 18:25:24 +0300
commit28afb49c480790e763b8491be0b5a8e35964dbc9 (patch)
treee24c10b205345073b3ac1e623ff4fac1b19adbef
parent02bdd9672c7619cc1e11fe3daed8e3ec092b207b (diff)
downloadbmcweb-28afb49c480790e763b8491be0b5a8e35964dbc9.tar.xz
EventService: Move subscription persistent data
This commit resolves https://github.com/openbmc/bmcweb/issues/168 Current store mechanism makes it very difficult to keep in sync with the existing files, and has caused several bugs because the path it uses different than the existing bmcweb_persistent_data.json, and it's missing several error checks. If there has old config in /var/lib/bmcweb/eventservice_config.json. Restart bmcweb will move old config to bmcweb_presistent_data.json and delete the old config. Tested: - Create new Subscription via POST https://${bmc}/redfish/v1/EventService/Subscriptions/ The subscription is successfully created and GET succussfully. Restart bmcweb or reboot. The subscription will restore. - Delete the Subscription via DELETE https://${bmc}/redfish/v1/EventService/Subscriptions/${subscription_id} The subscription is successfully delete. bmcweb_persistent_data.json will delete subscription content. - Modify EventService config via PATCH https://{{bmc}}/redfish/v1/EventService GET https://{{bmc}}/redfish/v1/EventService and the changes applied. bmcweb_persistent_data.json will apply modification after PATCH. Restart bmcweb or reboot The config maintains the changed. Signed-off-by: JunLin Chen <Jun-Lin.Chen@quantatw.com> Change-Id: Ic29385ea8231ba976bbf415af2803df2d30cb10a
-rw-r--r--include/event_service_store.hpp264
-rw-r--r--include/persistent_data.hpp67
-rw-r--r--redfish-core/include/event_service_manager.hpp338
-rw-r--r--redfish-core/lib/event_service.hpp28
4 files changed, 495 insertions, 202 deletions
diff --git a/include/event_service_store.hpp b/include/event_service_store.hpp
new file mode 100644
index 0000000000..d51adad572
--- /dev/null
+++ b/include/event_service_store.hpp
@@ -0,0 +1,264 @@
+#pragma once
+#include "logging.hpp"
+
+#include <boost/container/flat_map.hpp>
+#include <nlohmann/json.hpp>
+
+namespace persistent_data
+{
+
+struct UserSubscription
+{
+ 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;
+ std::vector<nlohmann::json> httpHeaders; // key-value pair
+ std::vector<std::string> metricReportDefinitions;
+
+ 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.emplace_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.emplace_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.emplace_back(*value);
+ }
+ }
+ else if (element.key() == "HttpHeaders")
+ {
+ const auto& obj = element.value();
+ for (const auto& val : obj.items())
+ {
+ const auto value =
+ val.value().get_ptr<const nlohmann::json::object_t*>();
+ if (value == nullptr)
+ {
+ continue;
+ }
+ subvalue->httpHeaders.emplace_back(*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.emplace_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->customText.empty() ||
+ subvalue->eventFormatType.empty() ||
+ subvalue->subscriptionType.empty() ||
+ (subvalue->registryPrefixes.empty() &&
+ subvalue->registryMsgIds.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;
+ uint32_t retryTimeoutInterval = 30;
+
+ 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>::lowest()) ||
+ (*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>::lowest()) ||
+ (*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;
+ EventServiceConfig eventServiceConfig;
+
+ static EventServiceStore& getInstance()
+ {
+ static EventServiceStore eventServiceStore;
+ return eventServiceStore;
+ }
+
+ EventServiceConfig& getEventServiceConfig()
+ {
+ return eventServiceConfig;
+ }
+};
+
+} // namespace persistent_data
diff --git a/include/persistent_data.hpp b/include/persistent_data.hpp
index 24f7afd460..4178d7d69f 100644
--- a/include/persistent_data.hpp
+++ b/include/persistent_data.hpp
@@ -5,6 +5,7 @@
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
+#include <event_service_store.hpp>
#include <http_request.hpp>
#include <http_response.hpp>
#include <nlohmann/json.hpp>
@@ -129,6 +130,35 @@ class ConfigFile
SessionStore::getInstance().updateSessionTimeout(
sessionTimeoutInseconds);
}
+ else if (item.key() == "eventservice_config")
+ {
+ EventServiceStore::getInstance()
+ .getEventServiceConfig()
+ .fromJson(item.value());
+ }
+ else if (item.key() == "subscriptions")
+ {
+ for (const auto& elem : item.value())
+ {
+ std::shared_ptr<UserSubscription> newSubscription =
+ UserSubscription::fromJson(elem);
+
+ if (newSubscription == nullptr)
+ {
+ BMCWEB_LOG_ERROR
+ << "Problem reading subscription "
+ "from persistent store";
+ continue;
+ }
+
+ BMCWEB_LOG_DEBUG << "Restored subscription: "
+ << newSubscription->id << " "
+ << newSubscription->customText;
+ EventServiceStore::getInstance()
+ .subscriptionsConfigMap.emplace(
+ newSubscription->id, newSubscription);
+ }
+ }
else
{
// Do nothing in the case of extra fields. We may have
@@ -170,6 +200,8 @@ class ConfigFile
std::filesystem::perms::group_read;
std::filesystem::permissions(filename, permission);
const auto& c = SessionStore::getInstance().getAuthMethodsConfig();
+ const auto& eventServiceConfig =
+ EventServiceStore::getInstance().getEventServiceConfig();
nlohmann::json data{
{"auth_config",
{{"XToken", c.xtoken},
@@ -179,6 +211,13 @@ class ConfigFile
{"TLS", c.tls}}
},
+ {"eventservice_config",
+ {{"ServiceEnabled", eventServiceConfig.enabled},
+ {"DeliveryRetryAttempts", eventServiceConfig.retryAttempts},
+ {"DeliveryRetryIntervalSeconds",
+ eventServiceConfig.retryTimeoutInterval}}
+
+ },
{"system_uuid", systemUuid},
{"revision", jsonRevision},
{"timeout", SessionStore::getInstance().getTimeoutInSeconds()}};
@@ -202,6 +241,34 @@ class ConfigFile
});
}
}
+ nlohmann::json& subscriptions = data["subscriptions"];
+ subscriptions = nlohmann::json::array();
+ for (const auto& it :
+ EventServiceStore::getInstance().subscriptionsConfigMap)
+ {
+ std::shared_ptr<UserSubscription> subValue = it.second;
+ if (subValue->subscriptionType == "SSE")
+ {
+ BMCWEB_LOG_DEBUG
+ << "The subscription type is SSE, so skipping.";
+ continue;
+ }
+ subscriptions.push_back({
+ {"Id", subValue->id},
+ {"Context", subValue->customText},
+ {"DeliveryRetryPolicy", subValue->retryPolicy},
+ {"Destination", subValue->destinationUrl},
+ {"EventFormatType", subValue->eventFormatType},
+ {"HttpHeaders", subValue->httpHeaders},
+ {"MessageIds", subValue->registryMsgIds},
+ {"Protocol", subValue->protocol},
+ {"RegistryPrefixes", subValue->registryPrefixes},
+ {"ResourceTypes", subValue->resourceTypes},
+ {"SubscriptionType", subValue->subscriptionType},
+ {"MetricReportDefinitions", subValue->metricReportDefinitions},
+
+ });
+ }
persistentFile << data;
}
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index de4035616a..d89b789ac1 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -24,7 +24,9 @@
#include <boost/asio/io_context.hpp>
#include <boost/container/flat_map.hpp>
#include <error_messages.hpp>
+#include <event_service_store.hpp>
#include <http_client.hpp>
+#include <persistent_data.hpp>
#include <random.hpp>
#include <server_sent_events.hpp>
#include <utils/json_utils.hpp>
@@ -40,7 +42,6 @@ namespace redfish
using ReadingsObjType =
std::vector<std::tuple<std::string, std::string, double, int32_t>>;
-using EventServiceConfig = std::tuple<bool, uint32_t, uint32_t>;
static constexpr const char* eventFormatType = "Event";
static constexpr const char* metricReportFormatType = "MetricReport";
@@ -369,22 +370,9 @@ inline bool
return true;
}
-class Subscription
+class Subscription : public persistent_data::UserSubscription
{
public:
- 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;
- std::vector<nlohmann::json> httpHeaders; // key-value pair
- std::vector<std::string> metricReportDefinitions;
-
Subscription(const Subscription&) = delete;
Subscription& operator=(const Subscription&) = delete;
Subscription(Subscription&&) = delete;
@@ -600,13 +588,6 @@ class Subscription
std::shared_ptr<crow::ServerSentEvents> sseConn = nullptr;
};
-static constexpr const bool defaultEnabledState = true;
-static constexpr const uint32_t defaultRetryAttempts = 3;
-static constexpr const uint32_t defaultRetryInterval = 30;
-static constexpr const char* defaulEventFormatType = "Event";
-static constexpr const char* defaulSubscriptionType = "RedfishEvent";
-static constexpr const char* defaulRetryPolicy = "TerminateAfterRetries";
-
class EventServiceManager
{
private:
@@ -641,102 +622,30 @@ class EventServiceManager
return handler;
}
- void loadDefaultConfig()
- {
- serviceEnabled = defaultEnabledState;
- retryAttempts = defaultRetryAttempts;
- retryTimeoutInterval = defaultRetryInterval;
- }
-
void initConfig()
{
- std::ifstream eventConfigFile(eventServiceFile);
- if (!eventConfigFile.good())
- {
- BMCWEB_LOG_DEBUG << "EventService config not exist";
- loadDefaultConfig();
- return;
- }
- auto jsonData = nlohmann::json::parse(eventConfigFile, nullptr, false);
- if (jsonData.is_discarded())
- {
- BMCWEB_LOG_ERROR << "EventService config parse error.";
- loadDefaultConfig();
- return;
- }
+ loadOldBehavior();
- nlohmann::json jsonConfig;
- if (json_util::getValueFromJsonObject(jsonData, "Configuration",
- jsonConfig))
- {
- if (!json_util::getValueFromJsonObject(jsonConfig, "ServiceEnabled",
- serviceEnabled))
- {
- serviceEnabled = defaultEnabledState;
- }
- if (!json_util::getValueFromJsonObject(
- jsonConfig, "DeliveryRetryAttempts", retryAttempts))
- {
- retryAttempts = defaultRetryAttempts;
- }
- if (!json_util::getValueFromJsonObject(
- jsonConfig, "DeliveryRetryIntervalSeconds",
- retryTimeoutInterval))
- {
- retryTimeoutInterval = defaultRetryInterval;
- }
- }
- else
- {
- loadDefaultConfig();
- }
+ persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
- nlohmann::json subscriptionsList;
- if (!json_util::getValueFromJsonObject(jsonData, "Subscriptions",
- subscriptionsList))
- {
- BMCWEB_LOG_DEBUG << "EventService: Subscriptions not exist.";
- return;
- }
+ serviceEnabled = eventServiceConfig.enabled;
+ retryAttempts = eventServiceConfig.retryAttempts;
+ retryTimeoutInterval = eventServiceConfig.retryTimeoutInterval;
- for (nlohmann::json& jsonObj : subscriptionsList)
+ for (const auto& it : persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap)
{
- std::string protocol;
- if (!json_util::getValueFromJsonObject(jsonObj, "Protocol",
- protocol))
- {
- BMCWEB_LOG_DEBUG << "Invalid subscription Protocol exist.";
- continue;
- }
+ std::shared_ptr<persistent_data::UserSubscription> newSub =
+ it.second;
- std::string subscriptionType;
- if (!json_util::getValueFromJsonObject(jsonObj, "SubscriptionType",
- subscriptionType))
- {
- subscriptionType = defaulSubscriptionType;
- }
- // SSE connections are initiated from client
- // and can't be re-established from server.
- if (subscriptionType == "SSE")
- {
- BMCWEB_LOG_DEBUG
- << "The subscription type is SSE, so skipping.";
- continue;
- }
-
- std::string destination;
- if (!json_util::getValueFromJsonObject(jsonObj, "Destination",
- destination))
- {
- BMCWEB_LOG_DEBUG << "Invalid subscription destination exist.";
- continue;
- }
std::string host;
std::string urlProto;
std::string port;
std::string path;
- bool status =
- validateAndSplitUrl(destination, urlProto, host, port, path);
+ bool status = validateAndSplitUrl(newSub->destinationUrl, urlProto,
+ host, port, path);
if (!status)
{
@@ -747,112 +656,140 @@ class EventServiceManager
std::shared_ptr<Subscription> subValue =
std::make_shared<Subscription>(host, port, path, urlProto);
- subValue->destinationUrl = destination;
- subValue->protocol = protocol;
- subValue->subscriptionType = subscriptionType;
- if (!json_util::getValueFromJsonObject(
- jsonObj, "DeliveryRetryPolicy", subValue->retryPolicy))
- {
- subValue->retryPolicy = defaulRetryPolicy;
- }
- if (!json_util::getValueFromJsonObject(jsonObj, "EventFormatType",
- subValue->eventFormatType))
+ subValue->id = newSub->id;
+ subValue->destinationUrl = newSub->destinationUrl;
+ subValue->protocol = newSub->protocol;
+ subValue->retryPolicy = newSub->retryPolicy;
+ subValue->customText = newSub->customText;
+ subValue->eventFormatType = newSub->eventFormatType;
+ subValue->subscriptionType = newSub->subscriptionType;
+ subValue->registryMsgIds = newSub->registryMsgIds;
+ subValue->registryPrefixes = newSub->registryPrefixes;
+ subValue->resourceTypes = newSub->resourceTypes;
+ subValue->httpHeaders = newSub->httpHeaders;
+ subValue->metricReportDefinitions = newSub->metricReportDefinitions;
+
+ if (subValue->id.empty())
{
- subValue->eventFormatType = defaulEventFormatType;
+ BMCWEB_LOG_ERROR << "Failed to add subscription";
}
- json_util::getValueFromJsonObject(jsonObj, "Context",
- subValue->customText);
- json_util::getValueFromJsonObject(jsonObj, "MessageIds",
- subValue->registryMsgIds);
- json_util::getValueFromJsonObject(jsonObj, "RegistryPrefixes",
- subValue->registryPrefixes);
- json_util::getValueFromJsonObject(jsonObj, "ResourceTypes",
- subValue->resourceTypes);
- json_util::getValueFromJsonObject(jsonObj, "HttpHeaders",
- subValue->httpHeaders);
- json_util::getValueFromJsonObject(
- jsonObj, "MetricReportDefinitions",
- subValue->metricReportDefinitions);
-
- std::string id = addSubscription(subValue, false);
- if (id.empty())
+ subscriptionsMap.insert(std::pair(subValue->id, subValue));
+
+ updateNoOfSubscribersCount();
+
+#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
+ if (lastEventTStr.empty())
{
- BMCWEB_LOG_ERROR << "Failed to add subscription";
+ cacheLastEventTimestamp();
}
+#endif
+ // Update retry configuration.
+ subValue->updateRetryConfig(retryAttempts, retryTimeoutInterval);
+ subValue->updateRetryPolicy();
}
return;
}
- void updateSubscriptionData()
+ void loadOldBehavior()
{
- // Persist the config and subscription data.
- nlohmann::json jsonData;
-
- nlohmann::json& configObj = jsonData["Configuration"];
- configObj["ServiceEnabled"] = serviceEnabled;
- configObj["DeliveryRetryAttempts"] = retryAttempts;
- configObj["DeliveryRetryIntervalSeconds"] = retryTimeoutInterval;
-
- nlohmann::json& subListArray = jsonData["Subscriptions"];
- subListArray = nlohmann::json::array();
+ std::ifstream eventConfigFile(eventServiceFile);
+ if (!eventConfigFile.good())
+ {
+ BMCWEB_LOG_DEBUG << "Old eventService config not exist";
+ return;
+ }
+ auto jsonData = nlohmann::json::parse(eventConfigFile, nullptr, false);
+ if (jsonData.is_discarded())
+ {
+ BMCWEB_LOG_ERROR << "Old eventService config parse error.";
+ return;
+ }
- for (const auto& it : subscriptionsMap)
+ for (const auto& item : jsonData.items())
{
- std::shared_ptr<Subscription> subValue = it.second;
- // Don't preserve SSE connections. Its initiated from
- // client side and can't be re-established from server.
- if (subValue->subscriptionType == "SSE")
+ if (item.key() == "Configuration")
{
- BMCWEB_LOG_DEBUG
- << "The subscription type is SSE, so skipping.";
- continue;
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig()
+ .fromJson(item.value());
}
+ else if (item.key() == "Subscriptions")
+ {
+ for (const auto& elem : item.value())
+ {
+ std::shared_ptr<persistent_data::UserSubscription>
+ newSubscription =
+ persistent_data::UserSubscription::fromJson(elem,
+ true);
+ if (newSubscription == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Problem reading subscription "
+ "from old persistent store";
+ continue;
+ }
- nlohmann::json entry;
- entry["Context"] = subValue->customText;
- entry["DeliveryRetryPolicy"] = subValue->retryPolicy;
- entry["Destination"] = subValue->destinationUrl;
- entry["EventFormatType"] = subValue->eventFormatType;
- entry["HttpHeaders"] = subValue->httpHeaders;
- entry["MessageIds"] = subValue->registryMsgIds;
- entry["Protocol"] = subValue->protocol;
- entry["RegistryPrefixes"] = subValue->registryPrefixes;
- entry["ResourceTypes"] = subValue->resourceTypes;
- entry["SubscriptionType"] = subValue->subscriptionType;
- entry["MetricReportDefinitions"] =
- subValue->metricReportDefinitions;
-
- subListArray.push_back(entry);
- }
+ std::uniform_int_distribution<uint32_t> dist(0);
+ bmcweb::OpenSSLGenerator gen;
- const std::string tmpFile(std::string(eventServiceFile) + "_tmp");
- std::ofstream ofs(tmpFile, std::ios::out);
- const auto& writeData = jsonData.dump(
- 2, ' ', true, nlohmann::json::error_handler_t::replace);
- ofs << writeData;
- ofs.close();
+ std::string id;
- BMCWEB_LOG_DEBUG << "EventService config updated to file.";
- if (std::rename(tmpFile.c_str(), eventServiceFile) != 0)
- {
- BMCWEB_LOG_ERROR << "Error in renaming temporary file: "
- << tmpFile.c_str();
+ int retry = 3;
+ while (retry)
+ {
+ id = std::to_string(dist(gen));
+ if (gen.error())
+ {
+ retry = 0;
+ break;
+ }
+ newSubscription->id = id;
+ auto inserted =
+ persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap.insert(
+ std::pair(id, newSubscription));
+ if (inserted.second)
+ {
+ break;
+ }
+ --retry;
+ }
+
+ if (retry <= 0)
+ {
+ BMCWEB_LOG_ERROR
+ << "Failed to generate random number from old "
+ "persistent store";
+ continue;
+ }
+ }
+ }
+
+ persistent_data::getConfig().writeData();
+ std::remove(eventServiceFile);
+ BMCWEB_LOG_DEBUG << "Remove old eventservice config";
}
}
- EventServiceConfig getEventServiceConfig()
+ void updateSubscriptionData()
{
- return {serviceEnabled, retryAttempts, retryTimeoutInterval};
+ persistent_data::EventServiceStore::getInstance()
+ .eventServiceConfig.enabled = serviceEnabled;
+ persistent_data::EventServiceStore::getInstance()
+ .eventServiceConfig.retryAttempts = retryAttempts;
+ persistent_data::EventServiceStore::getInstance()
+ .eventServiceConfig.retryTimeoutInterval = retryTimeoutInterval;
+
+ persistent_data::getConfig().writeData();
}
- void setEventServiceConfig(const EventServiceConfig& cfg)
+ void setEventServiceConfig(const persistent_data::EventServiceConfig& cfg)
{
bool updateConfig = false;
bool updateRetryCfg = false;
- if (serviceEnabled != std::get<0>(cfg))
+ if (serviceEnabled != cfg.enabled)
{
- serviceEnabled = std::get<0>(cfg);
+ serviceEnabled = cfg.enabled;
if (serviceEnabled && noOfMetricReportSubscribers)
{
registerMetricReportSignal();
@@ -864,16 +801,16 @@ class EventServiceManager
updateConfig = true;
}
- if (retryAttempts != std::get<1>(cfg))
+ if (retryAttempts != cfg.retryAttempts)
{
- retryAttempts = std::get<1>(cfg);
+ retryAttempts = cfg.retryAttempts;
updateConfig = true;
updateRetryCfg = true;
}
- if (retryTimeoutInterval != std::get<2>(cfg))
+ if (retryTimeoutInterval != cfg.retryTimeoutInterval)
{
- retryTimeoutInterval = std::get<2>(cfg);
+ retryTimeoutInterval = cfg.retryTimeoutInterval;
updateConfig = true;
updateRetryCfg = true;
}
@@ -971,6 +908,23 @@ class EventServiceManager
return std::string("");
}
+ std::shared_ptr<persistent_data::UserSubscription> newSub =
+ std::make_shared<persistent_data::UserSubscription>();
+ newSub->id = id;
+ newSub->destinationUrl = subValue->destinationUrl;
+ newSub->protocol = subValue->protocol;
+ newSub->retryPolicy = subValue->retryPolicy;
+ newSub->customText = subValue->customText;
+ newSub->eventFormatType = subValue->eventFormatType;
+ newSub->subscriptionType = subValue->subscriptionType;
+ newSub->registryMsgIds = subValue->registryMsgIds;
+ newSub->registryPrefixes = subValue->registryPrefixes;
+ newSub->resourceTypes = subValue->resourceTypes;
+ newSub->httpHeaders = subValue->httpHeaders;
+ newSub->metricReportDefinitions = subValue->metricReportDefinitions;
+ persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap.emplace(newSub->id, newSub);
+
updateNoOfSubscribersCount();
if (updateFile)
@@ -1007,6 +961,10 @@ class EventServiceManager
if (obj != subscriptionsMap.end())
{
subscriptionsMap.erase(obj);
+ auto obj2 = persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap.find(id);
+ persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap.erase(obj2);
updateNoOfSubscribersCount();
updateSubscriptionData();
}
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 98c67c66f6..f1d6f5007d 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -58,16 +58,18 @@ inline void requestRoutesEventService(App& app)
"EventService.SubmitTestEvent"}}}}},
{"@odata.id", "/redfish/v1/EventService"}};
- const auto& [enabled, retryAttempts, retryTimeoutInterval] =
- EventServiceManager::getInstance().getEventServiceConfig();
+ const persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
asyncResp->res.jsonValue["Status"]["State"] =
- (enabled ? "Enabled" : "Disabled");
- asyncResp->res.jsonValue["ServiceEnabled"] = enabled;
+ (eventServiceConfig.enabled ? "Enabled" : "Disabled");
+ asyncResp->res.jsonValue["ServiceEnabled"] =
+ eventServiceConfig.enabled;
asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
- retryAttempts;
+ eventServiceConfig.retryAttempts;
asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
- retryTimeoutInterval;
+ eventServiceConfig.retryTimeoutInterval;
asyncResp->res.jsonValue["EventFormatTypes"] =
supportedEvtFormatTypes;
asyncResp->res.jsonValue["RegistryPrefixes"] =
@@ -103,12 +105,13 @@ inline void requestRoutesEventService(App& app)
return;
}
- auto [enabled, retryCount, retryTimeoutInterval] =
- EventServiceManager::getInstance().getEventServiceConfig();
+ persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
if (serviceEnabled)
{
- enabled = *serviceEnabled;
+ eventServiceConfig.enabled = *serviceEnabled;
}
if (retryAttemps)
@@ -122,7 +125,7 @@ inline void requestRoutesEventService(App& app)
}
else
{
- retryCount = *retryAttemps;
+ eventServiceConfig.retryAttempts = *retryAttemps;
}
}
@@ -137,12 +140,13 @@ inline void requestRoutesEventService(App& app)
}
else
{
- retryTimeoutInterval = *retryInterval;
+ eventServiceConfig.retryTimeoutInterval =
+ *retryInterval;
}
}
EventServiceManager::getInstance().setEventServiceConfig(
- std::make_tuple(enabled, retryCount, retryTimeoutInterval));
+ eventServiceConfig);
});
}