summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--redfish-core/include/event_service_manager.hpp89
-rw-r--r--redfish-core/lib/event_service.hpp58
2 files changed, 143 insertions, 4 deletions
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 03d5dc3159..801a7ad485 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -267,6 +267,95 @@ int formatEventLogEntry(const std::string& logEntryID,
} // namespace event_log
#endif
+bool isFilterQuerySpecialChar(char c)
+{
+ switch (c)
+ {
+ case '(':
+ case ')':
+ case '\'':
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool readSSEQueryParams(std::string sseFilter, std::string& formatType,
+ std::vector<std::string>& messageIds,
+ std::vector<std::string>& registryPrefixes,
+ std::vector<nlohmann::json>& metricReportDefinitions)
+{
+ sseFilter.erase(std::remove_if(sseFilter.begin(), sseFilter.end(),
+ isFilterQuerySpecialChar),
+ sseFilter.end());
+
+ std::vector<std::string> result;
+ boost::split(result, sseFilter, boost::is_any_of(" "),
+ boost::token_compress_on);
+
+ BMCWEB_LOG_DEBUG << "No of tokens in SEE query: " << result.size();
+
+ constexpr uint8_t divisor = 4;
+ constexpr uint8_t minTokenSize = 3;
+ if (result.size() % divisor != minTokenSize)
+ {
+ BMCWEB_LOG_ERROR << "Invalid SSE filter specified.";
+ return false;
+ }
+
+ for (std::size_t i = 0; i < result.size(); i += divisor)
+ {
+ std::string& key = result[i];
+ std::string& op = result[i + 1];
+ std::string& value = result[i + 2];
+
+ if ((i + minTokenSize) < result.size())
+ {
+ std::string& seperator = result[i + minTokenSize];
+ // SSE supports only "or" and "and" in query params.
+ if ((seperator != "or") && (seperator != "and"))
+ {
+ BMCWEB_LOG_ERROR
+ << "Invalid group operator in SSE query parameters";
+ return false;
+ }
+ }
+
+ // SSE supports only "eq" as per spec.
+ if (op != "eq")
+ {
+ BMCWEB_LOG_ERROR
+ << "Invalid assignment operator in SSE query parameters";
+ return false;
+ }
+
+ BMCWEB_LOG_DEBUG << key << " : " << value;
+ if (key == "EventFormatType")
+ {
+ formatType = value;
+ }
+ else if (key == "MessageId")
+ {
+ messageIds.push_back(value);
+ }
+ else if (key == "RegistryPrefix")
+ {
+ registryPrefixes.push_back(value);
+ }
+ else if (key == "MetricReportDefinition")
+ {
+ metricReportDefinitions.push_back(value);
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR << "Invalid property(" << key
+ << ")in SSE filter query.";
+ return false;
+ }
+ }
+ return true;
+}
+
class Subscription
{
public:
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index adb62389cf..da537bfc1e 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -72,6 +72,14 @@ class EventService : public Node
retryTimeoutInterval;
asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
+
+ nlohmann::json supportedSSEFilters = {
+ {"EventFormatType", true}, {"MessageId", true},
+ {"MetricReportDefinition", true}, {"RegistryPrefix", true},
+ {"OriginResource", false}, {"ResourceType", false}};
+
+ asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
+ supportedSSEFilters;
}
void doPatch(crow::Response& res, const crow::Request& req,
@@ -432,19 +440,61 @@ class EventServiceSSE : public Node
// GET on this URI means, Its SSE subscriptionType.
subValue->subscriptionType = "SSE";
+
+ // Default values
subValue->protocol = "Redfish";
+ subValue->retryPolicy = "TerminateAfterRetries";
char* filters = req.urlParams.get("$filter");
if (filters == nullptr)
{
subValue->eventFormatType = "Event";
- subValue->retryPolicy = "TerminateAfterRetries";
}
else
{
- // TODO: Need to read this from query params.
- subValue->eventFormatType = "Event";
- subValue->retryPolicy = "TerminateAfterRetries";
+ // Reading from query params.
+ bool status = readSSEQueryParams(
+ filters, subValue->eventFormatType, subValue->registryMsgIds,
+ subValue->registryPrefixes, subValue->metricReportDefinitions);
+
+ if (!status)
+ {
+ messages::invalidObject(res, filters);
+ return;
+ }
+
+ if (!subValue->eventFormatType.empty())
+ {
+ if (std::find(supportedEvtFormatTypes.begin(),
+ supportedEvtFormatTypes.end(),
+ subValue->eventFormatType) ==
+ supportedEvtFormatTypes.end())
+ {
+ messages::propertyValueNotInList(
+ res, subValue->eventFormatType, "EventFormatType");
+ return;
+ }
+ }
+ else
+ {
+ // If nothing specified, using default "Event"
+ subValue->eventFormatType.assign({"Event"});
+ }
+
+ if (!subValue->registryPrefixes.empty())
+ {
+ for (const std::string& it : subValue->registryPrefixes)
+ {
+ if (std::find(supportedRegPrefixes.begin(),
+ supportedRegPrefixes.end(),
+ it) == supportedRegPrefixes.end())
+ {
+ messages::propertyValueNotInList(res, it,
+ "RegistryPrefixes");
+ return;
+ }
+ }
+ }
}
std::string id =