xref: /openbmc/bmcweb/redfish-core/include/redfishoemrule.hpp (revision fdf51f5c824273aafaa9262932735ca443db23eb)
1c1a75ebcSrohitpai #pragma once
2c1a75ebcSrohitpai #include "async_resp.hpp"
3*fdf51f5cSRohit PAI #include "sub_request.hpp"
4c1a75ebcSrohitpai 
5c1a75ebcSrohitpai #include <nlohmann/json.hpp>
6c1a75ebcSrohitpai 
7c1a75ebcSrohitpai #include <functional>
8c1a75ebcSrohitpai #include <memory>
9c1a75ebcSrohitpai #include <stdexcept>
10c1a75ebcSrohitpai #include <string>
11c1a75ebcSrohitpai #include <string_view>
12c1a75ebcSrohitpai #include <type_traits>
13c1a75ebcSrohitpai #include <vector>
14c1a75ebcSrohitpai 
15c1a75ebcSrohitpai namespace redfish
16c1a75ebcSrohitpai {
17c1a75ebcSrohitpai class OemBaseRule
18c1a75ebcSrohitpai {
19c1a75ebcSrohitpai   public:
OemBaseRule(std::string_view thisRule)20c1a75ebcSrohitpai     explicit OemBaseRule(std::string_view thisRule) : rule(thisRule) {}
21c1a75ebcSrohitpai     virtual ~OemBaseRule() = default;
22c1a75ebcSrohitpai     OemBaseRule(const OemBaseRule&) = delete;
23c1a75ebcSrohitpai     OemBaseRule(OemBaseRule&&) = delete;
24c1a75ebcSrohitpai     OemBaseRule& operator=(const OemBaseRule&) = delete;
25c1a75ebcSrohitpai     OemBaseRule& operator=(const OemBaseRule&&) = delete;
26c1a75ebcSrohitpai 
27*fdf51f5cSRohit PAI     virtual void handle(const SubRequest& req,
28c1a75ebcSrohitpai                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29*fdf51f5cSRohit PAI                         const std::vector<std::string>& params) = 0;
30c1a75ebcSrohitpai     std::string rule;
31c1a75ebcSrohitpai };
32c1a75ebcSrohitpai 
33c1a75ebcSrohitpai template <typename... Args>
34c1a75ebcSrohitpai class OemRule : public OemBaseRule
35c1a75ebcSrohitpai {
36c1a75ebcSrohitpai   public:
37c1a75ebcSrohitpai     using self_t = OemRule<Args...>;
38c1a75ebcSrohitpai 
OemRule(std::string_view ruleIn)39c1a75ebcSrohitpai     explicit OemRule(std::string_view ruleIn) : OemBaseRule(ruleIn) {}
40c1a75ebcSrohitpai 
validate()41c1a75ebcSrohitpai     void validate()
42c1a75ebcSrohitpai     {
43c1a75ebcSrohitpai         if (!handler)
44c1a75ebcSrohitpai         {
45c1a75ebcSrohitpai             throw std::runtime_error(
46c1a75ebcSrohitpai                 "no OEM fragment handler for the rule {}" + rule);
47c1a75ebcSrohitpai         }
48c1a75ebcSrohitpai     }
49c1a75ebcSrohitpai 
50c1a75ebcSrohitpai     template <typename Func>
operator ()(Func && f)51c1a75ebcSrohitpai     void operator()(Func&& f)
52c1a75ebcSrohitpai     {
53c1a75ebcSrohitpai         static_assert(
54*fdf51f5cSRohit PAI             std::is_invocable_v<Func, SubRequest,
55c1a75ebcSrohitpai                                 std::shared_ptr<bmcweb::AsyncResp>&, Args...>,
56c1a75ebcSrohitpai             "Handler type is mismatched with URL parameters");
57c1a75ebcSrohitpai         static_assert(
58c1a75ebcSrohitpai             std::is_same_v<
59*fdf51f5cSRohit PAI                 void, std::invoke_result_t<Func, SubRequest,
60c1a75ebcSrohitpai                                            std::shared_ptr<bmcweb::AsyncResp>&,
61c1a75ebcSrohitpai                                            Args...>>,
62c1a75ebcSrohitpai             "Handler function with response argument should have void return type");
63c1a75ebcSrohitpai 
64c1a75ebcSrohitpai         handler = std::forward<Func>(f);
65c1a75ebcSrohitpai     }
66c1a75ebcSrohitpai 
handle(const SubRequest & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)67*fdf51f5cSRohit PAI     void handle(const SubRequest& req,
68c1a75ebcSrohitpai                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
69c1a75ebcSrohitpai                 const std::vector<std::string>& params) override
70c1a75ebcSrohitpai     {
71c1a75ebcSrohitpai         if constexpr (sizeof...(Args) == 0)
72c1a75ebcSrohitpai         {
73c1a75ebcSrohitpai             handler(req, asyncResp);
74c1a75ebcSrohitpai         }
75c1a75ebcSrohitpai         else if constexpr (sizeof...(Args) == 1)
76c1a75ebcSrohitpai         {
77c1a75ebcSrohitpai             handler(req, asyncResp, params[0]);
78c1a75ebcSrohitpai         }
79c1a75ebcSrohitpai         else if constexpr (sizeof...(Args) == 2)
80c1a75ebcSrohitpai         {
81c1a75ebcSrohitpai             handler(req, asyncResp, params[0], params[1]);
82c1a75ebcSrohitpai         }
83c1a75ebcSrohitpai         else if constexpr (sizeof...(Args) == 3)
84c1a75ebcSrohitpai         {
85c1a75ebcSrohitpai             handler(req, asyncResp, params[0], params[1], params[2]);
86c1a75ebcSrohitpai         }
87c1a75ebcSrohitpai         else if constexpr (sizeof...(Args) == 4)
88c1a75ebcSrohitpai         {
89c1a75ebcSrohitpai             handler(req, asyncResp, params[0], params[1], params[2], params[3]);
90c1a75ebcSrohitpai         }
91c1a75ebcSrohitpai         else if constexpr (sizeof...(Args) == 5)
92c1a75ebcSrohitpai         {
93c1a75ebcSrohitpai             handler(req, asyncResp, params[0], params[1], params[2], params[3],
94c1a75ebcSrohitpai                     params[4]);
95c1a75ebcSrohitpai         }
96c1a75ebcSrohitpai         static_assert(sizeof...(Args) <= 5, "More args than are supported");
97c1a75ebcSrohitpai     }
98c1a75ebcSrohitpai 
99c1a75ebcSrohitpai   private:
100*fdf51f5cSRohit PAI     std::function<void(const SubRequest&,
101c1a75ebcSrohitpai                        const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>
102c1a75ebcSrohitpai         handler;
103c1a75ebcSrohitpai };
104c1a75ebcSrohitpai } // namespace redfish
105