blob: bfd97c1788ca1adfcb4236945f1a706fdaa53011 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
AppaRao Puli5e44e3d2021-03-16 15:37:24 +00003#pragma once
4
Ed Tanousd7857202025-01-28 15:32:26 -08005#include "filter_expr_parser_ast.hpp"
6#include "filter_expr_printer.hpp"
7#include "http_request.hpp"
8#include "logging.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -07009#include "registries/privilege_registry.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080010#include "server_sent_event.hpp"
11#include "subscription.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070012
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000013#include <app.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080014#include <boost/url/params_base.hpp>
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000015#include <event_service_manager.hpp>
16
Ed Tanousd7857202025-01-28 15:32:26 -080017#include <format>
Ed Tanous5b904292024-04-16 11:10:17 -070018#include <memory>
Ed Tanousd7857202025-01-28 15:32:26 -080019#include <optional>
Ed Tanous5b904292024-04-16 11:10:17 -070020#include <string>
21
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000022namespace redfish
23{
24
Ed Tanousf80a87f2024-06-16 12:10:33 -070025inline void createSubscription(crow::sse_socket::Connection& conn,
26 const crow::Request& req)
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000027{
Ed Tanous9838eb22025-01-29 16:24:42 -080028 EventServiceManager& manager = EventServiceManager::getInstance();
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000029 if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) ||
30 manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions)
31 {
Ed Tanous62598e32023-07-17 17:06:25 -070032 BMCWEB_LOG_WARNING("Max SSE subscriptions reached");
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000033 conn.close("Max SSE subscriptions reached");
34 return;
35 }
Ed Tanousf80a87f2024-06-16 12:10:33 -070036
37 std::optional<filter_ast::LogicalAnd> filter;
38
39 boost::urls::params_base::iterator filterIt =
40 req.url().params().find("$filter");
41
42 if (filterIt != req.url().params().end())
43 {
Ed Tanous3d158642025-05-12 14:20:49 -070044 const boost::urls::param& filterParam = *filterIt;
45 filter = parseFilter(filterParam.value);
Ed Tanousf80a87f2024-06-16 12:10:33 -070046 if (!filter)
47 {
Ed Tanous3d158642025-05-12 14:20:49 -070048 conn.close(std::format("Bad $filter param: {}", filterParam.value));
Ed Tanousf80a87f2024-06-16 12:10:33 -070049 return;
50 }
51 }
52
53 std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
54
Ed Tanous4b712a22023-08-02 12:56:52 -070055 std::shared_ptr<Subscription> subValue =
56 std::make_shared<Subscription>(conn);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000057
Myung Bae5fe4ef32024-10-19 09:56:02 -040058 if (subValue->userSub == nullptr)
59 {
60 BMCWEB_LOG_ERROR("Subscription data is null");
61 conn.close("Internal Error");
62 return;
63 }
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000064
Myung Bae5fe4ef32024-10-19 09:56:02 -040065 // GET on this URI means, Its SSE subscriptionType.
66 subValue->userSub->subscriptionType = redfish::subscriptionTypeSSE;
67
68 subValue->userSub->protocol = "Redfish";
69 subValue->userSub->retryPolicy = "TerminateAfterRetries";
70 subValue->userSub->eventFormatType = "Event";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000071
Ed Tanousf80a87f2024-06-16 12:10:33 -070072 std::string id = manager.addSSESubscription(subValue, lastEventId);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000073 if (id.empty())
74 {
75 conn.close("Internal Error");
76 }
77}
78
79inline void deleteSubscription(crow::sse_socket::Connection& conn)
80{
Ed Tanous9838eb22025-01-29 16:24:42 -080081 EventServiceManager::getInstance().deleteSseSubscription(conn);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000082}
83
84inline void requestRoutesEventServiceSse(App& app)
85{
86 // Note, this endpoint is given the same privilege level as creating a
87 // subscription, because functionally, that's the operation being done
88 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE")
89 .privileges(redfish::privileges::postEventDestinationCollection)
90 .serverSentEvent()
91 .onopen(createSubscription)
92 .onclose(deleteSubscription);
93}
94} // namespace redfish