* Copyright (c) 2026 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <cstdlib>
#include <devmon-common/global_model.h>
#include <mc/filesystem.h>
#include <mc/json.h>
#include <mc/log.h>
namespace devmon {
global_model& global_model::get_instance()
{
static global_model instance;
return instance;
}
void global_model::init()
{
m_class_info.clear();
std::string path = find_config_path();
if (!mc::filesystem::exists(path)) {
wlog("${path} does not exist, skip register global object", ("path", path));
hw_stream_warn("${path} does not exist, skip register global object", ("path", path));
return;
}
try {
parse_config(path);
} catch (const std::exception& e) {
elog("parse global object info failed, err: ${err}", ("err", e.what()));
}
}
std::optional<instance_info_t> global_model::get_object_info(const std::string& object_name,
const std::string& prop_name)
{
std::string interface = "bmc.kepler." + object_name;
if (m_class_info.contains(interface) && m_class_info[interface].contains(prop_name)) {
instance_info_t info;
info.path = m_class_info["path"].as<std::string>();
info.app = "persistence";
info.interface = interface;
return info;
}
return std::nullopt;
}
std::string global_model::find_config_path()
{
#if defined(BUILD_TYPE) && defined(BUILD_TYPE_DT) && BUILD_TYPE == BUILD_TYPE_DT
const char* env_path = std::getenv("GLOBAL_JSON_PATH");
std::string path = env_path ? env_path : GLOBAL_MODEL_DEFAULT_PATH;
if (env_path) {
nlog("try to load ${path} to register global object", ("path", path.substr(path.rfind('/') + 1)));
}
return path;
#else
std::optional<std::pair<std::string, std::string>> info = utils::get_product_info();
if (!info.has_value()) {
nlog("get product id failed, try to load global.json to register global object");
return GLOBAL_MODEL_DEFAULT_PATH;
}
std::string path = "/opt/bmc/conf/global/global_" + info->first + "_" + info->second + ".json";
if (!mc::filesystem::exists(path)) {
nlog("${path} does not exist, try to load global.json to register global object",
("path", path.substr(path.rfind('/') + 1)));
return GLOBAL_MODEL_DEFAULT_PATH;
}
nlog("try to load ${path} to register global object", ("path", path.substr(path.rfind('/') + 1)));
return path;
#endif
}
void global_model::parse_config(const std::string& path)
{
auto content = mc::filesystem::read_file(path);
if (!content.has_value()) {
wlog("Failed to read global.json");
return;
}
mc::dict model_json;
try {
model_json = mc::json::json_decode(*content).as_dict();
} catch (const std::exception& e) {
elog("get global object json data failed, err: ${err}", ("err", e.what()));
return;
}
auto& global_data = model_json["Global"];
m_class_info["path"] = global_data["path"];
for (auto& entry : global_data["interfaces"].as_dict()) {
auto value = entry.value;
mc::dict info;
for (auto& sub_entry : value["properties"].as_dict()) {
info[sub_entry.key] = true;
}
m_class_info[entry.key] = info;
}
}
}