blob: e4689aad8804295c3624285b4d44517d29325004 [file] [log] [blame]
#include "report_factory.hpp"
#include "metric.hpp"
#include "report.hpp"
#include "sensor.hpp"
#include "utils/transform.hpp"
ReportFactory::ReportFactory(
std::shared_ptr<sdbusplus::asio::connection> bus,
const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
bus(std::move(bus)),
objServer(objServer)
{}
std::unique_ptr<interfaces::Report> ReportFactory::make(
std::optional<std::reference_wrapper<boost::asio::yield_context>> yield,
const std::string& name, const std::string& reportingType,
bool emitsReadingsSignal, bool logToMetricReportsCollection,
std::chrono::milliseconds period, const ReadingParameters& metricParams,
interfaces::ReportManager& reportManager,
interfaces::JsonStorage& reportStorage) const
{
std::optional<std::vector<ReportFactory::SensorTree>> sensorTree;
std::vector<std::shared_ptr<interfaces::Metric>> metrics;
metrics.reserve(metricParams.size());
for (const auto& [sensorPaths, op, id, metadata] : metricParams)
{
if (!sensorTree && yield && sensorPaths.size() > 0)
{
sensorTree = getSensorTree(*yield);
}
std::vector<std::shared_ptr<interfaces::Sensor>> sensors =
getSensors(sensorTree, sensorPaths);
metrics.emplace_back(
std::make_shared<Metric>(std::move(sensors), op, id, metadata));
}
return std::make_unique<Report>(
bus->get_io_context(), objServer, name, reportingType,
emitsReadingsSignal, logToMetricReportsCollection, period, metricParams,
reportManager, reportStorage, std::move(metrics));
}
std::vector<std::shared_ptr<interfaces::Sensor>> ReportFactory::getSensors(
const std::optional<std::vector<ReportFactory::SensorTree>>& tree,
const std::vector<sdbusplus::message::object_path>& sensorPaths) const
{
if (tree)
{
std::vector<std::shared_ptr<interfaces::Sensor>> sensors;
for (const auto& [sensor, ifacesMap] : *tree)
{
auto it = std::find(sensorPaths.begin(), sensorPaths.end(), sensor);
if (it != sensorPaths.end())
{
for (const auto& [service, ifaces] : ifacesMap)
{
sensors.emplace_back(sensorCache.makeSensor<Sensor>(
service, sensor, bus->get_io_context(), bus));
}
}
}
return sensors;
}
else
{
return utils::transform(
sensorPaths,
[this](const std::string& sensor)
-> std::shared_ptr<interfaces::Sensor> {
std::string::size_type pos = sensor.find_first_of(":");
auto service = sensor.substr(0, pos);
auto path = sensor.substr(pos + 1);
return sensorCache.makeSensor<Sensor>(
service, path, bus->get_io_context(), bus);
});
}
}
std::vector<ReportFactory::SensorTree>
ReportFactory::getSensorTree(boost::asio::yield_context& yield) const
{
std::array<const char*, 1> interfaces = {
"xyz.openbmc_project.Sensor.Value"};
boost::system::error_code ec;
auto result = bus->yield_method_call<std::vector<SensorTree>>(
yield, ec, "xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
"xyz.openbmc_project.ObjectMapper", "GetSubTree",
"/xyz/openbmc_project/sensors", 2, interfaces);
if (ec)
{
throw std::runtime_error("failed");
}
return result;
}