16c068982SEd Tanous #pragma once 26c068982SEd Tanous 36c068982SEd Tanous #include "app.hpp" 46c068982SEd Tanous #include "error_messages.hpp" 56c068982SEd Tanous #include "http_request.hpp" 66c068982SEd Tanous #include "http_response.hpp" 76c068982SEd Tanous #include "query.hpp" 88b2521a5SCarson Labrado #include "redfish_aggregator.hpp" 96c068982SEd Tanous #include "registries/privilege_registry.hpp" 106c068982SEd Tanous 11*ef4c65b7SEd Tanous #include <boost/url/format.hpp> 126c068982SEd Tanous #include <nlohmann/json.hpp> 136c068982SEd Tanous 146c068982SEd Tanous #include <functional> 156c068982SEd Tanous #include <memory> 166c068982SEd Tanous 176c068982SEd Tanous namespace redfish 186c068982SEd Tanous { 196c068982SEd Tanous 206c068982SEd Tanous inline void handleAggregationServiceHead( 216c068982SEd Tanous App& app, const crow::Request& req, 226c068982SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 236c068982SEd Tanous { 246c068982SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 256c068982SEd Tanous { 266c068982SEd Tanous return; 276c068982SEd Tanous } 286c068982SEd Tanous asyncResp->res.addHeader( 296c068982SEd Tanous boost::beast::http::field::link, 306c068982SEd Tanous "</redfish/v1/JsonSchemas/AggregationService/AggregationService.json>; rel=describedby"); 316c068982SEd Tanous } 326c068982SEd Tanous 336c068982SEd Tanous inline void handleAggregationServiceGet( 346c068982SEd Tanous App& app, const crow::Request& req, 356c068982SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 366c068982SEd Tanous { 376c068982SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 386c068982SEd Tanous { 396c068982SEd Tanous return; 406c068982SEd Tanous } 416c068982SEd Tanous asyncResp->res.addHeader( 426c068982SEd Tanous boost::beast::http::field::link, 436c068982SEd Tanous "</redfish/v1/JsonSchemas/AggregationService/AggregationService.json>; rel=describedby"); 446c068982SEd Tanous nlohmann::json& json = asyncResp->res.jsonValue; 456c068982SEd Tanous json["@odata.id"] = "/redfish/v1/AggregationService"; 466c068982SEd Tanous json["@odata.type"] = "#AggregationService.v1_0_1.AggregationService"; 476c068982SEd Tanous json["Id"] = "AggregationService"; 486c068982SEd Tanous json["Name"] = "Aggregation Service"; 496c068982SEd Tanous json["Description"] = "Aggregation Service"; 506c068982SEd Tanous json["ServiceEnabled"] = true; 515315c1b1SCarson Labrado json["AggregationSources"]["@odata.id"] = 525315c1b1SCarson Labrado "/redfish/v1/AggregationService/AggregationSources"; 536c068982SEd Tanous } 546c068982SEd Tanous 558b2521a5SCarson Labrado inline void requestRoutesAggregationService(App& app) 566c068982SEd Tanous { 576c068982SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/") 586c068982SEd Tanous .privileges(redfish::privileges::headAggregationService) 596c068982SEd Tanous .methods(boost::beast::http::verb::head)( 606c068982SEd Tanous std::bind_front(handleAggregationServiceHead, std::ref(app))); 616c068982SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/") 626c068982SEd Tanous .privileges(redfish::privileges::getAggregationService) 636c068982SEd Tanous .methods(boost::beast::http::verb::get)( 646c068982SEd Tanous std::bind_front(handleAggregationServiceGet, std::ref(app))); 656c068982SEd Tanous } 666c068982SEd Tanous 678b2521a5SCarson Labrado inline void populateAggregationSourceCollection( 688b2521a5SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 698b2521a5SCarson Labrado const boost::system::error_code ec, 708b2521a5SCarson Labrado const std::unordered_map<std::string, boost::urls::url>& satelliteInfo) 718b2521a5SCarson Labrado { 728b2521a5SCarson Labrado // Something went wrong while querying dbus 738b2521a5SCarson Labrado if (ec) 748b2521a5SCarson Labrado { 758b2521a5SCarson Labrado messages::internalError(asyncResp->res); 768b2521a5SCarson Labrado return; 778b2521a5SCarson Labrado } 788b2521a5SCarson Labrado nlohmann::json::array_t members = nlohmann::json::array(); 798b2521a5SCarson Labrado for (const auto& sat : satelliteInfo) 808b2521a5SCarson Labrado { 818b2521a5SCarson Labrado nlohmann::json::object_t member; 82*ef4c65b7SEd Tanous member["@odata.id"] = boost::urls::format( 83*ef4c65b7SEd Tanous "/redfish/v1/AggregationService/AggregationSources/{}", sat.first); 84ad539545SPatrick Williams members.emplace_back(std::move(member)); 858b2521a5SCarson Labrado } 868b2521a5SCarson Labrado asyncResp->res.jsonValue["Members@odata.count"] = members.size(); 878b2521a5SCarson Labrado asyncResp->res.jsonValue["Members"] = std::move(members); 888b2521a5SCarson Labrado } 898b2521a5SCarson Labrado 908b2521a5SCarson Labrado inline void handleAggregationSourceCollectionGet( 915315c1b1SCarson Labrado App& app, const crow::Request& req, 925315c1b1SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 935315c1b1SCarson Labrado { 945315c1b1SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 955315c1b1SCarson Labrado { 965315c1b1SCarson Labrado return; 975315c1b1SCarson Labrado } 985315c1b1SCarson Labrado asyncResp->res.addHeader( 995315c1b1SCarson Labrado boost::beast::http::field::link, 1005315c1b1SCarson Labrado "</redfish/v1/JsonSchemas/AggregationSourceCollection/AggregationSourceCollection.json>; rel=describedby"); 1015315c1b1SCarson Labrado nlohmann::json& json = asyncResp->res.jsonValue; 1025315c1b1SCarson Labrado json["@odata.id"] = "/redfish/v1/AggregationService/AggregationSources"; 1035315c1b1SCarson Labrado json["@odata.type"] = 1045315c1b1SCarson Labrado "#AggregationSourceCollection.AggregationSourceCollection"; 1055315c1b1SCarson Labrado json["Name"] = "Aggregation Source Collection"; 1065315c1b1SCarson Labrado 1078b2521a5SCarson Labrado // Query D-Bus for satellite configs and add them to the Members array 1088b2521a5SCarson Labrado RedfishAggregator::getSatelliteConfigs( 1098b2521a5SCarson Labrado std::bind_front(populateAggregationSourceCollection, asyncResp)); 1105315c1b1SCarson Labrado } 1115315c1b1SCarson Labrado 1128b2521a5SCarson Labrado inline void handleAggregationSourceCollectionHead( 1138b2521a5SCarson Labrado App& app, const crow::Request& req, 1148b2521a5SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1158b2521a5SCarson Labrado { 1168b2521a5SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 1178b2521a5SCarson Labrado { 1188b2521a5SCarson Labrado return; 1198b2521a5SCarson Labrado } 1208b2521a5SCarson Labrado asyncResp->res.addHeader( 1218b2521a5SCarson Labrado boost::beast::http::field::link, 1228b2521a5SCarson Labrado "</redfish/v1/JsonSchemas/AggregationService/AggregationSourceCollection.json>; rel=describedby"); 1238b2521a5SCarson Labrado } 1248b2521a5SCarson Labrado 1258b2521a5SCarson Labrado inline void requestRoutesAggregationSourceCollection(App& app) 1265315c1b1SCarson Labrado { 1275315c1b1SCarson Labrado BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/AggregationSources/") 1288b2521a5SCarson Labrado .privileges(redfish::privileges::getAggregationSourceCollection) 1298b2521a5SCarson Labrado .methods(boost::beast::http::verb::get)(std::bind_front( 1308b2521a5SCarson Labrado handleAggregationSourceCollectionGet, std::ref(app))); 1318b2521a5SCarson Labrado 1328b2521a5SCarson Labrado BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/AggregationSources/") 1338b2521a5SCarson Labrado .privileges(redfish::privileges::getAggregationSourceCollection) 1348b2521a5SCarson Labrado .methods(boost::beast::http::verb::head)(std::bind_front( 1358b2521a5SCarson Labrado handleAggregationSourceCollectionHead, std::ref(app))); 1368b2521a5SCarson Labrado } 1378b2521a5SCarson Labrado 1388b2521a5SCarson Labrado inline void populateAggregationSource( 1398b2521a5SCarson Labrado const std::string& aggregationSourceId, 1408b2521a5SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1418b2521a5SCarson Labrado const boost::system::error_code ec, 1428b2521a5SCarson Labrado const std::unordered_map<std::string, boost::urls::url>& satelliteInfo) 1438b2521a5SCarson Labrado { 1448b2521a5SCarson Labrado asyncResp->res.addHeader( 1458b2521a5SCarson Labrado boost::beast::http::field::link, 1468b2521a5SCarson Labrado "</redfish/v1/JsonSchemas/AggregationSource/AggregationSource.json>; rel=describedby"); 1478b2521a5SCarson Labrado 1488b2521a5SCarson Labrado // Something went wrong while querying dbus 1498b2521a5SCarson Labrado if (ec) 1508b2521a5SCarson Labrado { 1518b2521a5SCarson Labrado messages::internalError(asyncResp->res); 1528b2521a5SCarson Labrado return; 1538b2521a5SCarson Labrado } 1548b2521a5SCarson Labrado 1558b2521a5SCarson Labrado const auto& sat = satelliteInfo.find(aggregationSourceId); 1568b2521a5SCarson Labrado if (sat == satelliteInfo.end()) 1578b2521a5SCarson Labrado { 1588b2521a5SCarson Labrado messages::resourceNotFound(asyncResp->res, "AggregationSource", 1598b2521a5SCarson Labrado aggregationSourceId); 1608b2521a5SCarson Labrado return; 1618b2521a5SCarson Labrado } 1628b2521a5SCarson Labrado 163*ef4c65b7SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 164*ef4c65b7SEd Tanous "/redfish/v1/AggregationService/AggregationSources/{}", 165*ef4c65b7SEd Tanous aggregationSourceId); 1668b2521a5SCarson Labrado asyncResp->res.jsonValue["@odata.type"] = 1678b2521a5SCarson Labrado "#AggregationSource.v1_3_1.AggregationSource"; 1688b2521a5SCarson Labrado asyncResp->res.jsonValue["Id"] = aggregationSourceId; 1698b2521a5SCarson Labrado 1708b2521a5SCarson Labrado // TODO: We may want to change this whenever we support aggregating multiple 1718b2521a5SCarson Labrado // satellite BMCs. Otherwise all AggregationSource resources will have the 1728b2521a5SCarson Labrado // same "Name". 1738b2521a5SCarson Labrado // TODO: We should use the "Name" from the satellite config whenever we add 1748b2521a5SCarson Labrado // support for including it in the data returned in satelliteInfo. 1758b2521a5SCarson Labrado asyncResp->res.jsonValue["Name"] = "Aggregation source"; 1768b2521a5SCarson Labrado std::string hostName(sat->second.encoded_origin()); 1778b2521a5SCarson Labrado asyncResp->res.jsonValue["HostName"] = std::move(hostName); 1788b2521a5SCarson Labrado 1798b2521a5SCarson Labrado // The Redfish spec requires Password to be null in responses 1808b2521a5SCarson Labrado asyncResp->res.jsonValue["Password"] = nullptr; 1818b2521a5SCarson Labrado } 1828b2521a5SCarson Labrado 1838b2521a5SCarson Labrado inline void handleAggregationSourceGet( 1848b2521a5SCarson Labrado App& app, const crow::Request& req, 1858b2521a5SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1868b2521a5SCarson Labrado const std::string& aggregationSourceId) 1878b2521a5SCarson Labrado { 1888b2521a5SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 1898b2521a5SCarson Labrado { 1908b2521a5SCarson Labrado return; 1918b2521a5SCarson Labrado } 1928b2521a5SCarson Labrado 1938b2521a5SCarson Labrado // Query D-Bus for satellite config corresponding to the specified 1948b2521a5SCarson Labrado // AggregationSource 1958b2521a5SCarson Labrado RedfishAggregator::getSatelliteConfigs(std::bind_front( 1968b2521a5SCarson Labrado populateAggregationSource, aggregationSourceId, asyncResp)); 1978b2521a5SCarson Labrado } 1988b2521a5SCarson Labrado 1998b2521a5SCarson Labrado inline void handleAggregationSourceHead( 2008b2521a5SCarson Labrado App& app, const crow::Request& req, 2018b2521a5SCarson Labrado const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2028b2521a5SCarson Labrado const std::string& aggregationSourceId) 2038b2521a5SCarson Labrado { 2048b2521a5SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2058b2521a5SCarson Labrado { 2068b2521a5SCarson Labrado return; 2078b2521a5SCarson Labrado } 2088b2521a5SCarson Labrado asyncResp->res.addHeader( 2098b2521a5SCarson Labrado boost::beast::http::field::link, 2108b2521a5SCarson Labrado "</redfish/v1/JsonSchemas/AggregationService/AggregationSource.json>; rel=describedby"); 2118b2521a5SCarson Labrado 2128b2521a5SCarson Labrado // Needed to prevent unused variable error 2138b2521a5SCarson Labrado BMCWEB_LOG_DEBUG << "Added link header to response from " 2148b2521a5SCarson Labrado << aggregationSourceId; 2158b2521a5SCarson Labrado } 2168b2521a5SCarson Labrado 2178b2521a5SCarson Labrado inline void requestRoutesAggregationSource(App& app) 2188b2521a5SCarson Labrado { 2198b2521a5SCarson Labrado BMCWEB_ROUTE(app, 2208b2521a5SCarson Labrado "/redfish/v1/AggregationService/AggregationSources/<str>/") 2218b2521a5SCarson Labrado .privileges(redfish::privileges::getAggregationSource) 2225315c1b1SCarson Labrado .methods(boost::beast::http::verb::get)( 2238b2521a5SCarson Labrado std::bind_front(handleAggregationSourceGet, std::ref(app))); 2245315c1b1SCarson Labrado } 2255315c1b1SCarson Labrado 2266c068982SEd Tanous } // namespace redfish 227