xref: /openbmc/bmcweb/features/redfish/lib/eventservice_sse.hpp (revision f80a87f2c458a4d8092aae91249aec1adcec6cd5)
15e44e3d8SAppaRao Puli #pragma once
25e44e3d8SAppaRao Puli 
3*f80a87f2SEd Tanous #include "filter_expr_executor.hpp"
45b90429aSEd Tanous #include "privileges.hpp"
55b90429aSEd Tanous #include "registries/privilege_registry.hpp"
65b90429aSEd Tanous 
75e44e3d8SAppaRao Puli #include <app.hpp>
85e44e3d8SAppaRao Puli #include <event_service_manager.hpp>
95e44e3d8SAppaRao Puli 
105b90429aSEd Tanous #include <memory>
115b90429aSEd Tanous #include <string>
125b90429aSEd Tanous 
135e44e3d8SAppaRao Puli namespace redfish
145e44e3d8SAppaRao Puli {
155e44e3d8SAppaRao Puli 
16*f80a87f2SEd Tanous inline void createSubscription(crow::sse_socket::Connection& conn,
17*f80a87f2SEd Tanous                                const crow::Request& req)
185e44e3d8SAppaRao Puli {
195e44e3d8SAppaRao Puli     EventServiceManager& manager =
205e44e3d8SAppaRao Puli         EventServiceManager::getInstance(&conn.getIoContext());
215e44e3d8SAppaRao Puli     if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) ||
225e44e3d8SAppaRao Puli         manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions)
235e44e3d8SAppaRao Puli     {
2462598e31SEd Tanous         BMCWEB_LOG_WARNING("Max SSE subscriptions reached");
255e44e3d8SAppaRao Puli         conn.close("Max SSE subscriptions reached");
265e44e3d8SAppaRao Puli         return;
275e44e3d8SAppaRao Puli     }
28*f80a87f2SEd Tanous 
29*f80a87f2SEd Tanous     std::optional<filter_ast::LogicalAnd> filter;
30*f80a87f2SEd Tanous 
31*f80a87f2SEd Tanous     boost::urls::params_base::iterator filterIt =
32*f80a87f2SEd Tanous         req.url().params().find("$filter");
33*f80a87f2SEd Tanous 
34*f80a87f2SEd Tanous     if (filterIt != req.url().params().end())
35*f80a87f2SEd Tanous     {
36*f80a87f2SEd Tanous         std::string_view filterValue = (*filterIt).value;
37*f80a87f2SEd Tanous         filter = parseFilter(filterValue);
38*f80a87f2SEd Tanous         if (!filter)
39*f80a87f2SEd Tanous         {
40*f80a87f2SEd Tanous             conn.close(std::format("Bad $filter param: {}", filterValue));
41*f80a87f2SEd Tanous             return;
42*f80a87f2SEd Tanous         }
43*f80a87f2SEd Tanous     }
44*f80a87f2SEd Tanous 
45*f80a87f2SEd Tanous     std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
46*f80a87f2SEd Tanous 
475e44e3d8SAppaRao Puli     std::shared_ptr<redfish::Subscription> subValue =
485e44e3d8SAppaRao Puli         std::make_shared<redfish::Subscription>(conn);
495e44e3d8SAppaRao Puli 
505e44e3d8SAppaRao Puli     // GET on this URI means, Its SSE subscriptionType.
515e44e3d8SAppaRao Puli     subValue->subscriptionType = redfish::subscriptionTypeSSE;
525e44e3d8SAppaRao Puli 
535e44e3d8SAppaRao Puli     subValue->protocol = "Redfish";
545e44e3d8SAppaRao Puli     subValue->retryPolicy = "TerminateAfterRetries";
555e44e3d8SAppaRao Puli     subValue->eventFormatType = "Event";
56*f80a87f2SEd Tanous     subValue->filter = filter;
575e44e3d8SAppaRao Puli 
58*f80a87f2SEd Tanous     std::string id = manager.addSSESubscription(subValue, lastEventId);
595e44e3d8SAppaRao Puli     if (id.empty())
605e44e3d8SAppaRao Puli     {
615e44e3d8SAppaRao Puli         conn.close("Internal Error");
625e44e3d8SAppaRao Puli     }
635e44e3d8SAppaRao Puli }
645e44e3d8SAppaRao Puli 
655e44e3d8SAppaRao Puli inline void deleteSubscription(crow::sse_socket::Connection& conn)
665e44e3d8SAppaRao Puli {
675e44e3d8SAppaRao Puli     redfish::EventServiceManager::getInstance(&conn.getIoContext())
685e44e3d8SAppaRao Puli         .deleteSseSubscription(conn);
695e44e3d8SAppaRao Puli }
705e44e3d8SAppaRao Puli 
715e44e3d8SAppaRao Puli inline void requestRoutesEventServiceSse(App& app)
725e44e3d8SAppaRao Puli {
735e44e3d8SAppaRao Puli     // Note, this endpoint is given the same privilege level as creating a
745e44e3d8SAppaRao Puli     // subscription, because functionally, that's the operation being done
755e44e3d8SAppaRao Puli     BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE")
765e44e3d8SAppaRao Puli         .privileges(redfish::privileges::postEventDestinationCollection)
775e44e3d8SAppaRao Puli         .serverSentEvent()
785e44e3d8SAppaRao Puli         .onopen(createSubscription)
795e44e3d8SAppaRao Puli         .onclose(deleteSubscription);
805e44e3d8SAppaRao Puli }
815e44e3d8SAppaRao Puli } // namespace redfish
82