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