blob: 80c0a3a5460981e3cbb7734f78fd530470eaf404 [file] [log] [blame]
AppaRao Puli5e44e3d2021-03-16 15:37:24 +00001#pragma once
2
Ed Tanousf80a87f2024-06-16 12:10:33 -07003#include "filter_expr_executor.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -07004#include "privileges.hpp"
5#include "registries/privilege_registry.hpp"
6
AppaRao Puli5e44e3d2021-03-16 15:37:24 +00007#include <app.hpp>
8#include <event_service_manager.hpp>
9
Ed Tanous5b904292024-04-16 11:10:17 -070010#include <memory>
11#include <string>
12
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000013namespace redfish
14{
15
Ed Tanousf80a87f2024-06-16 12:10:33 -070016inline void createSubscription(crow::sse_socket::Connection& conn,
17 const crow::Request& req)
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000018{
19 EventServiceManager& manager =
20 EventServiceManager::getInstance(&conn.getIoContext());
21 if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) ||
22 manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions)
23 {
Ed Tanous62598e32023-07-17 17:06:25 -070024 BMCWEB_LOG_WARNING("Max SSE subscriptions reached");
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000025 conn.close("Max SSE subscriptions reached");
26 return;
27 }
Ed Tanousf80a87f2024-06-16 12:10:33 -070028
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
Ed Tanous4b712a22023-08-02 12:56:52 -070047 std::shared_ptr<Subscription> subValue =
48 std::make_shared<Subscription>(conn);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000049
50 // GET on this URI means, Its SSE subscriptionType.
Ed Tanous4b712a22023-08-02 12:56:52 -070051 subValue->userSub.subscriptionType = redfish::subscriptionTypeSSE;
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000052
Ed Tanous4b712a22023-08-02 12:56:52 -070053 subValue->userSub.protocol = "Redfish";
54 subValue->userSub.retryPolicy = "TerminateAfterRetries";
55 subValue->userSub.eventFormatType = "Event";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000056
Ed Tanousf80a87f2024-06-16 12:10:33 -070057 std::string id = manager.addSSESubscription(subValue, lastEventId);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000058 if (id.empty())
59 {
60 conn.close("Internal Error");
61 }
62}
63
64inline void deleteSubscription(crow::sse_socket::Connection& conn)
65{
66 redfish::EventServiceManager::getInstance(&conn.getIoContext())
67 .deleteSseSubscription(conn);
68}
69
70inline void requestRoutesEventServiceSse(App& app)
71{
72 // Note, this endpoint is given the same privilege level as creating a
73 // subscription, because functionally, that's the operation being done
74 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE")
75 .privileges(redfish::privileges::postEventDestinationCollection)
76 .serverSentEvent()
77 .onopen(createSubscription)
78 .onclose(deleteSubscription);
79}
80} // namespace redfish