1 #pragma once 2 3 #include "filter_expr_executor.hpp" 4 #include "privileges.hpp" 5 #include "registries/privilege_registry.hpp" 6 7 #include <app.hpp> 8 #include <event_service_manager.hpp> 9 10 #include <memory> 11 #include <string> 12 13 namespace redfish 14 { 15 16 inline void createSubscription(crow::sse_socket::Connection& conn, 17 const crow::Request& req) 18 { 19 EventServiceManager& manager = 20 EventServiceManager::getInstance(&conn.getIoContext()); 21 if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) || 22 manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions) 23 { 24 BMCWEB_LOG_WARNING("Max SSE subscriptions reached"); 25 conn.close("Max SSE subscriptions reached"); 26 return; 27 } 28 29 std::optional<filter_ast::LogicalAnd> filter; 30 31 boost::urls::params_base::iterator filterIt = 32 req.url().params().find("$filter"); 33 34 if (filterIt != req.url().params().end()) 35 { 36 std::string_view filterValue = (*filterIt).value; 37 filter = parseFilter(filterValue); 38 if (!filter) 39 { 40 conn.close(std::format("Bad $filter param: {}", filterValue)); 41 return; 42 } 43 } 44 45 std::string lastEventId(req.getHeaderValue("Last-Event-Id")); 46 47 std::shared_ptr<redfish::Subscription> subValue = 48 std::make_shared<redfish::Subscription>(conn); 49 50 // GET on this URI means, Its SSE subscriptionType. 51 subValue->subscriptionType = redfish::subscriptionTypeSSE; 52 53 subValue->protocol = "Redfish"; 54 subValue->retryPolicy = "TerminateAfterRetries"; 55 subValue->eventFormatType = "Event"; 56 subValue->filter = filter; 57 58 std::string id = manager.addSSESubscription(subValue, lastEventId); 59 if (id.empty()) 60 { 61 conn.close("Internal Error"); 62 } 63 } 64 65 inline void deleteSubscription(crow::sse_socket::Connection& conn) 66 { 67 redfish::EventServiceManager::getInstance(&conn.getIoContext()) 68 .deleteSseSubscription(conn); 69 } 70 71 inline void requestRoutesEventServiceSse(App& app) 72 { 73 // Note, this endpoint is given the same privilege level as creating a 74 // subscription, because functionally, that's the operation being done 75 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE") 76 .privileges(redfish::privileges::postEventDestinationCollection) 77 .serverSentEvent() 78 .onopen(createSubscription) 79 .onclose(deleteSubscription); 80 } 81 } // namespace redfish 82