Add SSE filter param support
The Redfish spec require filtering of SSE entries to be supported.
This commit rearranges the code, and implements SSE sorting as well
as support for Last-Event-Id. To do this it adds a dependency on
boost circular_buffer.
Tested:
SSE connections succeed. Show filtered results.
Change-Id: I7aeb266fc40471519674c7b65cd5cc4625019e68
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/http/routing/sserule.hpp b/http/routing/sserule.hpp
index 7f8e284..1a51ab0 100644
--- a/http/routing/sserule.hpp
+++ b/http/routing/sserule.hpp
@@ -38,7 +38,7 @@
boost::beast::http::status::internal_server_error);
}
- void handleUpgrade(const Request& /*req*/,
+ void handleUpgrade(const Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
boost::asio::ip::tcp::socket&& adaptor) override
{
@@ -47,9 +47,9 @@
myConnection = std::make_shared<
crow::sse_socket::ConnectionImpl<boost::asio::ip::tcp::socket>>(
std::move(adaptor), openHandler, closeHandler);
- myConnection->start();
+ myConnection->start(req);
}
- void handleUpgrade(const Request& /*req*/,
+ void handleUpgrade(const Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>&&
adaptor) override
@@ -59,7 +59,7 @@
myConnection = std::make_shared<crow::sse_socket::ConnectionImpl<
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>>(
std::move(adaptor), openHandler, closeHandler);
- myConnection->start();
+ myConnection->start(req);
}
template <typename Func>
@@ -77,7 +77,8 @@
}
private:
- std::function<void(crow::sse_socket::Connection&)> openHandler;
+ std::function<void(crow::sse_socket::Connection&, const crow::Request&)>
+ openHandler;
std::function<void(crow::sse_socket::Connection&)> closeHandler;
};
diff --git a/http/server_sent_event.hpp b/http/server_sent_event.hpp
index 1b644fc..cfc5dfb 100644
--- a/http/server_sent_event.hpp
+++ b/http/server_sent_event.hpp
@@ -38,9 +38,10 @@
class ConnectionImpl : public Connection
{
public:
- ConnectionImpl(Adaptor&& adaptorIn,
- std::function<void(Connection&)> openHandlerIn,
- std::function<void(Connection&)> closeHandlerIn) :
+ ConnectionImpl(
+ Adaptor&& adaptorIn,
+ std::function<void(Connection&, const Request&)> openHandlerIn,
+ std::function<void(Connection&)> closeHandlerIn) :
adaptor(std::move(adaptorIn)),
timer(static_cast<boost::asio::io_context&>(
adaptor.get_executor().context())),
@@ -67,14 +68,14 @@
adaptor.get_executor().context());
}
- void start()
+ void start(const Request& req)
{
if (!openHandler)
{
BMCWEB_LOG_CRITICAL("No open handler???");
return;
}
- openHandler(*this);
+ openHandler(*this, req);
sendSSEHeader();
}
@@ -281,7 +282,7 @@
boost::asio::steady_timer timer;
bool doingWrite = false;
- std::function<void(Connection&)> openHandler;
+ std::function<void(Connection&, const Request&)> openHandler;
std::function<void(Connection&)> closeHandler;
};
} // namespace sse_socket
diff --git a/meson.build b/meson.build
index 9ee276a..bce2c95 100644
--- a/meson.build
+++ b/meson.build
@@ -259,34 +259,30 @@
else
cmake = import('cmake')
opt = cmake.subproject_options()
+ boost_libs = [
+ 'asio',
+ 'beast',
+ 'circular_buffer',
+ 'callable_traits',
+ 'headers',
+ 'process',
+ 'type_index',
+ 'url',
+ 'uuid',
+ 'spirit',
+ ]
opt.add_cmake_defines(
{
- 'BOOST_INCLUDE_LIBRARIES': 'asio;beast;callable_traits;headers;process;type_index;url;uuid;spirit',
+ 'BOOST_INCLUDE_LIBRARIES': ';'.join(boost_libs),
'BUILD_SHARED_LIBS': 'OFF',
},
)
boost = cmake.subproject('boost', required: true, options: opt)
- boost_asio = boost.dependency('boost_asio').as_system()
- boost_beast = boost.dependency('boost_beast').as_system()
- boost_callable_traits = boost.dependency('boost_callable_traits').as_system()
- boost_headers = boost.dependency('boost_headers').as_system()
- boost_process = boost.dependency('boost_process').as_system()
- boost_type_index = boost.dependency('boost_type_index').as_system()
- boost_url = boost.dependency('boost_url').as_system()
- boost_uuid = boost.dependency('boost_uuid').as_system()
- boost_spirit = boost.dependency('boost_spirit').as_system()
- bmcweb_dependencies += [
- boost_asio,
- boost_beast,
- boost_callable_traits,
- boost_headers,
- boost_process,
- boost_type_index,
- boost_url,
- boost_uuid,
- boost_spirit,
- ]
+ foreach boost_lib : boost_libs
+ boost_lib_instance = boost.dependency('boost_' + boost_lib).as_system()
+ bmcweb_dependencies += [boost_lib_instance]
+ endforeach
endif
if get_option('tests').allowed()
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 5abab9d..e95d30b 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -17,6 +17,7 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "event_service_store.hpp"
+#include "filter_expr_executor.hpp"
#include "http_client.hpp"
#include "metric_report.hpp"
#include "ossl_random.hpp"
@@ -31,6 +32,7 @@
#include <sys/inotify.h>
#include <boost/asio/io_context.hpp>
+#include <boost/circular_buffer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/url/format.hpp>
#include <boost/url/url_view_base.hpp>
@@ -69,11 +71,13 @@
static int dirWatchDesc = -1;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static int fileWatchDesc = -1;
-
-// <ID, timestamp, RedfishLogId, registryPrefix, MessageId, MessageArgs>
-using EventLogObjectsType =
- std::tuple<std::string, std::string, std::string, std::string, std::string,
- std::vector<std::string>>;
+struct EventLogObjectsType
+{
+ std::string id;
+ std::string timestamp;
+ std::string messageId;
+ std::vector<std::string> messageArgs;
+};
namespace registries
{
@@ -214,7 +218,7 @@
const std::span<std::string_view> messageArgs,
std::string timestamp,
const std::string& customText,
- nlohmann::json& logEntryJson)
+ nlohmann::json::object_t& logEntryJson)
{
// Get the Message from the MessageRegistry
const registries::Message* message = registries::formatMessage(messageID);
@@ -289,7 +293,6 @@
return false;
}
- // A connection pool will be created if one does not already exist
if (client)
{
client->sendData(
@@ -307,11 +310,71 @@
return true;
}
+ bool eventMatchesFilter(const nlohmann::json::object_t& eventMessage,
+ std::string_view resType)
+ {
+ // If resourceTypes list is empty, assume all
+ if (!resourceTypes.empty())
+ {
+ // Search the resourceTypes list for the subscription.
+ auto resourceTypeIndex = std::ranges::find_if(
+ resourceTypes, [resType](const std::string& rtEntry) {
+ return rtEntry == resType;
+ });
+ if (resourceTypeIndex == resourceTypes.end())
+ {
+ BMCWEB_LOG_DEBUG("Not subscribed to this resource");
+ return false;
+ }
+ BMCWEB_LOG_DEBUG("ResourceType {} found in the subscribed list",
+ resType);
+ }
+
+ // If registryMsgIds list is empty, assume all
+ if (!registryMsgIds.empty())
+ {
+ auto eventJson = eventMessage.find("MessageId");
+ if (eventJson == eventMessage.end())
+ {
+ return false;
+ }
+
+ const std::string* messageId =
+ eventJson->second.get_ptr<const std::string*>();
+ if (messageId == nullptr)
+ {
+ BMCWEB_LOG_ERROR("EventType wasn't a string???");
+ return false;
+ }
+
+ std::string registry;
+ std::string messageKey;
+ event_log::getRegistryAndMessageKey(*messageId, registry,
+ messageKey);
+
+ auto obj = std::ranges::find(registryMsgIds, registry);
+ if (obj == registryMsgIds.end())
+ {
+ return false;
+ }
+ }
+
+ if (filter)
+ {
+ if (!memberMatches(eventMessage, *filter))
+ {
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool sendTestEventLog()
{
- nlohmann::json logEntryArray;
- logEntryArray.push_back({});
- nlohmann::json& logEntryJson = logEntryArray.back();
+ nlohmann::json::array_t logEntryArray;
+ nlohmann::json& logEntryJson = logEntryArray.emplace_back();
logEntryJson["EventId"] = "TestID";
logEntryJson["EventType"] = "Event";
@@ -337,50 +400,27 @@
void filterAndSendEventLogs(
const std::vector<EventLogObjectsType>& eventRecords)
{
- nlohmann::json logEntryArray;
+ nlohmann::json::array_t logEntryArray;
for (const EventLogObjectsType& logEntry : eventRecords)
{
- const std::string& idStr = std::get<0>(logEntry);
- const std::string& timestamp = std::get<1>(logEntry);
- const std::string& messageID = std::get<2>(logEntry);
- const std::string& registryName = std::get<3>(logEntry);
- const std::string& messageKey = std::get<4>(logEntry);
- const std::vector<std::string>& messageArgs = std::get<5>(logEntry);
+ std::vector<std::string_view> messageArgsView(
+ logEntry.messageArgs.begin(), logEntry.messageArgs.end());
- // If registryPrefixes list is empty, don't filter events
- // send everything.
- if (!registryPrefixes.empty())
- {
- auto obj = std::ranges::find(registryPrefixes, registryName);
- if (obj == registryPrefixes.end())
- {
- continue;
- }
- }
-
- // If registryMsgIds list is empty, don't filter events
- // send everything.
- if (!registryMsgIds.empty())
- {
- auto obj = std::ranges::find(registryMsgIds, messageKey);
- if (obj == registryMsgIds.end())
- {
- continue;
- }
- }
-
- std::vector<std::string_view> messageArgsView(messageArgs.begin(),
- messageArgs.end());
-
- logEntryArray.push_back({});
- nlohmann::json& bmcLogEntry = logEntryArray.back();
- if (event_log::formatEventLogEntry(idStr, messageID,
- messageArgsView, timestamp,
- customText, bmcLogEntry) != 0)
+ nlohmann::json::object_t bmcLogEntry;
+ if (event_log::formatEventLogEntry(
+ logEntry.id, logEntry.messageId, messageArgsView,
+ logEntry.timestamp, customText, bmcLogEntry) != 0)
{
BMCWEB_LOG_DEBUG("Read eventLog entry failed");
continue;
}
+
+ if (!eventMatchesFilter(bmcLogEntry, ""))
+ {
+ continue;
+ }
+
+ logEntryArray.emplace_back(std::move(bmcLogEntry));
}
if (logEntryArray.empty())
@@ -393,7 +433,7 @@
msg["@odata.type"] = "#Event.v1_4_0.Event";
msg["Id"] = std::to_string(eventSeqNum);
msg["Name"] = "Event Log";
- msg["Events"] = logEntryArray;
+ msg["Events"] = std::move(logEntryArray);
std::string strMsg = msg.dump(2, ' ', true,
nlohmann::json::error_handler_t::replace);
sendEvent(std::move(strMsg));
@@ -471,16 +511,6 @@
return &thisConn == sseConn;
}
- private:
- std::string subId;
- uint64_t eventSeqNum = 1;
- boost::urls::url host;
- std::shared_ptr<crow::ConnectionPolicy> policy;
- crow::sse_socket::Connection* sseConn = nullptr;
- std::optional<crow::HttpClient> client;
- std::string path;
- std::string uriProto;
-
// Check used to indicate what response codes are valid as part of our retry
// policy. 2XX is considered acceptable
static boost::system::error_code retryRespHandler(unsigned int respCode)
@@ -497,6 +527,18 @@
return boost::system::errc::make_error_code(
boost::system::errc::success);
}
+
+ private:
+ std::string subId;
+ uint64_t eventSeqNum = 1;
+ boost::urls::url host;
+ std::shared_ptr<crow::ConnectionPolicy> policy;
+ crow::sse_socket::Connection* sseConn = nullptr;
+
+ std::optional<crow::HttpClient> client;
+
+ public:
+ std::optional<filter_ast::LogicalAnd> filter;
};
class EventServiceManager
@@ -515,6 +557,15 @@
uint64_t eventId{1};
+ struct Event
+ {
+ std::string id;
+ nlohmann::json message;
+ };
+
+ constexpr static size_t maxMessages = 200;
+ boost::circular_buffer<Event> messages{maxMessages};
+
boost::asio::io_context& ioc;
public:
@@ -796,8 +847,8 @@
return subValue;
}
- std::string addSubscription(const std::shared_ptr<Subscription>& subValue,
- const bool updateFile = true)
+ std::string
+ addSubscriptionInternal(const std::shared_ptr<Subscription>& subValue)
{
std::uniform_int_distribution<uint32_t> dist(0);
bmcweb::OpenSSLGenerator gen;
@@ -846,11 +897,6 @@
updateNoOfSubscribersCount();
- if (updateFile)
- {
- updateSubscriptionData();
- }
-
if constexpr (!BMCWEB_REDFISH_DBUS_LOG)
{
if (redfishLogFilePosition != 0)
@@ -863,6 +909,55 @@
// Set Subscription ID for back trace
subValue->setSubscriptionId(id);
+
+ return id;
+ }
+
+ std::string
+ addSSESubscription(const std::shared_ptr<Subscription>& subValue,
+ std::string_view lastEventId)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ if (!lastEventId.empty())
+ {
+ BMCWEB_LOG_INFO("Attempting to find message for last id {}",
+ lastEventId);
+ boost::circular_buffer<Event>::iterator lastEvent =
+ std::find_if(messages.begin(), messages.end(),
+ [&lastEventId](const Event& event) {
+ return event.id == lastEventId;
+ });
+ // Can't find a matching ID
+ if (lastEvent == messages.end())
+ {
+ nlohmann::json msg = messages::eventBufferExceeded();
+ // If the buffer overloaded, send all messages.
+ subValue->sendEvent(msg);
+ lastEvent = messages.begin();
+ }
+ else
+ {
+ // Skip the last event the user already has
+ lastEvent++;
+ }
+
+ for (boost::circular_buffer<Event>::const_iterator event =
+ lastEvent;
+ lastEvent != messages.end(); lastEvent++)
+ {
+ subValue->sendEvent(event->message);
+ }
+ }
+ return id;
+ }
+
+ std::string
+ addPushSubscription(const std::shared_ptr<Subscription>& subValue)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ updateSubscriptionData();
return id;
}
@@ -944,68 +1039,43 @@
return true;
}
- void sendEvent(nlohmann::json eventMessage, std::string_view origin,
- std::string_view resType)
+ void sendEvent(nlohmann::json::object_t eventMessage,
+ std::string_view origin, std::string_view resourceType)
{
- if (!serviceEnabled || (noOfEventLogSubscribers == 0U))
- {
- BMCWEB_LOG_DEBUG("EventService disabled or no Subscriptions.");
- return;
- }
- nlohmann::json eventRecord = nlohmann::json::array();
-
eventMessage["EventId"] = eventId;
- // MemberId is 0 : since we are sending one event record.
- eventMessage["MemberId"] = 0;
+
eventMessage["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
eventMessage["OriginOfCondition"] = origin;
- eventRecord.emplace_back(std::move(eventMessage));
+ // MemberId is 0 : since we are sending one event record.
+ eventMessage["MemberId"] = 0;
- for (const auto& it : subscriptionsMap)
+ messages.push_back(Event(std::to_string(eventId), eventMessage));
+
+ for (auto& it : subscriptionsMap)
{
- std::shared_ptr<Subscription> entry = it.second;
- bool isSubscribed = false;
- // Search the resourceTypes list for the subscription.
- // If resourceTypes list is empty, don't filter events
- // send everything.
- if (!entry->resourceTypes.empty())
+ std::shared_ptr<Subscription>& entry = it.second;
+ if (!entry->eventMatchesFilter(eventMessage, resourceType))
{
- for (const auto& resource : entry->resourceTypes)
- {
- if (resType == resource)
- {
- BMCWEB_LOG_INFO(
- "ResourceType {} found in the subscribed list",
- resource);
- isSubscribed = true;
- break;
- }
- }
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ continue;
}
- else // resourceTypes list is empty.
- {
- isSubscribed = true;
- }
- if (isSubscribed)
- {
- nlohmann::json msgJson;
- msgJson["@odata.type"] = "#Event.v1_4_0.Event";
- msgJson["Name"] = "Event Log";
- msgJson["Id"] = eventId;
- msgJson["Events"] = eventRecord;
+ nlohmann::json::array_t eventRecord;
+ eventRecord.emplace_back(eventMessage);
- std::string strMsg = msgJson.dump(
- 2, ' ', true, nlohmann::json::error_handler_t::replace);
- entry->sendEvent(std::move(strMsg));
- eventId++; // increment the eventId
- }
- else
- {
- BMCWEB_LOG_INFO("Not subscribed to this resource");
- }
+ nlohmann::json msgJson;
+
+ msgJson["@odata.type"] = "#Event.v1_4_0.Event";
+ msgJson["Name"] = "Event Log";
+ msgJson["Id"] = eventId;
+ msgJson["Events"] = std::move(eventRecord);
+
+ std::string strMsg = msgJson.dump(
+ 2, ' ', true, nlohmann::json::error_handler_t::replace);
+ entry->sendEvent(std::move(strMsg));
+ eventId++; // increment the eventId
}
}
@@ -1078,17 +1148,7 @@
continue;
}
- std::string registryName;
- std::string messageKey;
- event_log::getRegistryAndMessageKey(messageID, registryName,
- messageKey);
- if (registryName.empty() || messageKey.empty())
- {
- continue;
- }
-
- eventRecords.emplace_back(idStr, timestamp, messageID, registryName,
- messageKey, messageArgs);
+ eventRecords.emplace_back(idStr, timestamp, messageID, messageArgs);
}
if (!serviceEnabled || noOfEventLogSubscribers == 0)
diff --git a/redfish-core/include/filter_expr_executor.hpp b/redfish-core/include/filter_expr_executor.hpp
index a5aef04..66217a5 100644
--- a/redfish-core/include/filter_expr_executor.hpp
+++ b/redfish-core/include/filter_expr_executor.hpp
@@ -7,7 +7,10 @@
namespace redfish
{
-bool applyFilter(nlohmann::json& body,
- const filter_ast::LogicalAnd& filterParam);
+bool memberMatches(const nlohmann::json& member,
+ const filter_ast::LogicalAnd& filterParam);
-}
+bool applyFilterToCollection(nlohmann::json& body,
+ const filter_ast::LogicalAnd& filterParam);
+
+} // namespace redfish
diff --git a/redfish-core/include/utils/query_param.hpp b/redfish-core/include/utils/query_param.hpp
index e5f6195..3ec4dc3 100644
--- a/redfish-core/include/utils/query_param.hpp
+++ b/redfish-core/include/utils/query_param.hpp
@@ -1070,7 +1070,7 @@
if (query.filter)
{
- applyFilter(intermediateResponse.jsonValue, *query.filter);
+ applyFilterToCollection(intermediateResponse.jsonValue, *query.filter);
}
// According to Redfish Spec Section 7.3.1, $select is the last parameter to
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index dab53fe..7307571 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -619,7 +619,7 @@
}
std::string id =
- EventServiceManager::getInstance().addSubscription(subValue);
+ EventServiceManager::getInstance().addPushSubscription(subValue);
if (id.empty())
{
messages::internalError(asyncResp->res);
diff --git a/redfish-core/lib/eventservice_sse.hpp b/redfish-core/lib/eventservice_sse.hpp
index 3cbca3b..c0a9527 100644
--- a/redfish-core/lib/eventservice_sse.hpp
+++ b/redfish-core/lib/eventservice_sse.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "filter_expr_executor.hpp"
#include "privileges.hpp"
#include "registries/privilege_registry.hpp"
@@ -12,7 +13,8 @@
namespace redfish
{
-inline void createSubscription(crow::sse_socket::Connection& conn)
+inline void createSubscription(crow::sse_socket::Connection& conn,
+ const crow::Request& req)
{
EventServiceManager& manager =
EventServiceManager::getInstance(&conn.getIoContext());
@@ -23,6 +25,25 @@
conn.close("Max SSE subscriptions reached");
return;
}
+
+ std::optional<filter_ast::LogicalAnd> filter;
+
+ boost::urls::params_base::iterator filterIt =
+ req.url().params().find("$filter");
+
+ if (filterIt != req.url().params().end())
+ {
+ std::string_view filterValue = (*filterIt).value;
+ filter = parseFilter(filterValue);
+ if (!filter)
+ {
+ conn.close(std::format("Bad $filter param: {}", filterValue));
+ return;
+ }
+ }
+
+ std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
+
std::shared_ptr<redfish::Subscription> subValue =
std::make_shared<redfish::Subscription>(conn);
@@ -32,8 +53,9 @@
subValue->protocol = "Redfish";
subValue->retryPolicy = "TerminateAfterRetries";
subValue->eventFormatType = "Event";
+ subValue->filter = filter;
- std::string id = manager.addSubscription(subValue, false);
+ std::string id = manager.addSSESubscription(subValue, lastEventId);
if (id.empty())
{
conn.close("Internal Error");
diff --git a/redfish-core/src/filter_expr_executor.cpp b/redfish-core/src/filter_expr_executor.cpp
index 70046f0..1e2e41b 100644
--- a/redfish-core/src/filter_expr_executor.cpp
+++ b/redfish-core/src/filter_expr_executor.cpp
@@ -88,7 +88,7 @@
{
using result_type = std::variant<std::monostate, double, int64_t,
std::string, DateTimeString>;
- nlohmann::json& body;
+ const nlohmann::json& body;
result_type operator()(double n);
result_type operator()(int64_t x);
result_type operator()(const filter_ast::UnquotedString& x);
@@ -151,7 +151,7 @@
struct ApplyFilter
{
- nlohmann::json& body;
+ const nlohmann::json& body;
const filter_ast::LogicalAnd& filter;
using result_type = bool;
bool operator()(const filter_ast::LogicalNot& x);
@@ -370,9 +370,16 @@
} // namespace
+bool memberMatches(const nlohmann::json& member,
+ const filter_ast::LogicalAnd& filterParam)
+{
+ ApplyFilter filterApplier(member, filterParam);
+ return filterApplier.matches();
+}
+
// Applies a filter expression to a member array
-bool applyFilter(nlohmann::json& body,
- const filter_ast::LogicalAnd& filterParam)
+bool applyFilterToCollection(nlohmann::json& body,
+ const filter_ast::LogicalAnd& filterParam)
{
using nlohmann::json;
@@ -399,8 +406,7 @@
size_t index = 0;
while (it != memberArr->end())
{
- ApplyFilter filterApplier(*it, filterParam);
- if (!filterApplier.matches())
+ if (!memberMatches(*it, filterParam))
{
BMCWEB_LOG_DEBUG("Removing item at index {}", index);
it = memberArr->erase(it);
diff --git a/test/http/server_sent_event_test.cpp b/test/http/server_sent_event_test.cpp
index 43b830d..d8d8836 100644
--- a/test/http/server_sent_event_test.cpp
+++ b/test/http/server_sent_event_test.cpp
@@ -28,15 +28,20 @@
boost::beast::test::stream out(io);
stream.connect(out);
+ Request req;
+
bool openCalled = false;
- auto openHandler = [&openCalled](Connection&) { openCalled = true; };
+ auto openHandler = [&openCalled](Connection&,
+ const Request& /*handedReq*/) {
+ openCalled = true;
+ };
bool closeCalled = false;
auto closeHandler = [&closeCalled](Connection&) { closeCalled = true; };
std::shared_ptr<ConnectionImpl<boost::beast::test::stream>> conn =
std::make_shared<ConnectionImpl<boost::beast::test::stream>>(
std::move(stream), openHandler, closeHandler);
- conn->start();
+ conn->start(req);
// Connect
{
constexpr std::string_view expected =
diff --git a/test/redfish-core/include/filter_expr_executor_test.cpp b/test/redfish-core/include/filter_expr_executor_test.cpp
index 0761668..5770ce1 100644
--- a/test/redfish-core/include/filter_expr_executor_test.cpp
+++ b/test/redfish-core/include/filter_expr_executor_test.cpp
@@ -19,7 +19,7 @@
return;
}
EXPECT_EQ(json["Members"].size(), 1);
- EXPECT_TRUE(applyFilter(json, *ast));
+ EXPECT_TRUE(applyFilterToCollection(json, *ast));
EXPECT_EQ(json["Members"].size(), 1);
}
@@ -32,7 +32,7 @@
return;
}
EXPECT_EQ(json["Members"].size(), 1);
- EXPECT_TRUE(applyFilter(json, *ast));
+ EXPECT_TRUE(applyFilterToCollection(json, *ast));
EXPECT_EQ(json["Members"].size(), 0);
}