blob: a74d6e2c74857b9242b5c8940677ec63cba04a4c [file] [log] [blame]
#pragma once
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include <boost/system/error_code.hpp>
#include <sdbusplus/message/types.hpp>
#include <array>
#include <string_view>
#include <utility>
#include "managed_store.hpp"
#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif
namespace redfish
{
namespace system_utils
{
constexpr std::array<std::string_view, 1> systemInterfaces{
{"xyz.openbmc_project.Inventory.Item.System"}};
template <typename Callback>
inline void findSystemPathAndTriggerCallback(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName,
const dbus::utility::MapperGetSubTreePathsResponse& objects,
Callback&& callback)
{
// If there are less than 2 Item.Systems assume singlehost
if (objects.size() < 2)
{
if (systemName != "system")
{
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
systemName);
return;
}
callback(asyncResp, "");
return;
}
// Otherwise find system
for (const auto& object : objects)
{
std::string objectName =
sdbusplus::message::object_path(object).filename();
// Found system object
if (systemName == objectName)
{
callback(asyncResp, object);
return;
}
}
// Could not find system object
messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
}
/**
* @brief Retrieves valid system path
* @param asyncResp Pointer to object holding response data
* @param callback Callback for next step to get valid system path
* Callback should take in asyncResp pointer and full object path of Item.System
* Single Host Systems will return empty string as the object path of
* Item.System.
*/
template <typename Callback>
void getSystemInformation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, Callback&& callback)
{
managedStore::ManagedObjectStoreContext requestContext(asyncResp);
managedStore::GetManagedObjectStore()->getSubTreePaths(
"/", 0, systemInterfaces, requestContext,
[callback{std::forward<Callback>(callback)}, asyncResp, systemName](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& objects) {
if (ec)
{
BMCWEB_LOG_ERROR << "DBUS response error " << ec;
messages::internalError(asyncResp->res);
return;
}
findSystemPathAndTriggerCallback(asyncResp, systemName, objects,
callback);
});
}
inline std::string getSystemName(const std::string& systemPath) {
// If the systemPath is empty, then the system is single host
bool multiHost = !systemPath.empty();
// Default systemName is system
if (!multiHost)
{
return "system";
}
return sdbusplus::message::object_path(systemPath).filename();
}
} // namespace system_utils
} // namespace redfish