blob: 1e2bc32397b8a370b446f88f14f4e5bef406c58c [file]
#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_
#include <systemd/sd-daemon.h>
#include <chrono> // NOLINT
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <thread> // NOLINT
#include <utility>
// NOLINTBEGIN
#include "absl/base/log_severity.h"
#include "absl/flags/declare.h"
#include "absl/types/optional.h"
#include "boost/asio/thread_pool.hpp" // NOLINT
#include "g3/event_store.h"
#include "subscription.h"
#include "subscription_impl.h"
#include "subscription_store_impl.h"
#include "bmcweb_config.h"
#include "app.hpp"
#include "app_singleton.hpp"
#ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
#include "exception_stack_tracer.hpp"
#endif
#include "logging.hpp"
#include "cors_preflight.hpp"
#include "persistent_data.hpp"
#include "request_stats.hpp"
#include "user_monitor.hpp"
#include "webassets.hpp"
#include "interface.hpp"
#include "redfish.hpp"
#include "health.hpp"
#include "tlbmc/credentials/credential_manager.h"
#include "tlbmc/credentials/credential_manager_impl.h"
#include "tlbmc/hal/system_registry.h"
#include "tlbmc/hal/system_registry_impl.h"
#include "tlbmc/redfish/app.h"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "subscription_backend_impl.hpp"
#ifdef BMCWEB_ENABLE_GRPC
#include "absl/flags/flag.h"
#include "absl/log/initialize.h"
#include "absl/log/log.h"
#include "server.h"
// NOLINTEND
// See absl/log/globals.h for detailed instructions
ABSL_DECLARE_FLAG(int, stderrthreshold);
ABSL_DECLARE_FLAG(int, minloglevel);
ABSL_DECLARE_FLAG(absl::optional<int>, httpport);
ABSL_DECLARE_FLAG(int, mtls_grpc_port);
ABSL_DECLARE_FLAG(int, insecure_grpc_port);
// BMCWEB_ENABLE_STATEFUL_BMCWEB:
ABSL_DECLARE_FLAG(absl::optional<bool>, stateful);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_pending_max);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tfixed_sec);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tgrace_sec);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tlru_sec);
ABSL_DECLARE_FLAG(absl::optional<bool>, request_stats);
ABSL_DECLARE_FLAG(absl::optional<bool>, timetrace);
ABSL_DECLARE_FLAG(absl::optional<uint64_t>, timetrace_size_max);
ABSL_DECLARE_FLAG(absl::optional<bool>, stateful_logs);
ABSL_DECLARE_FLAG(bool, redfish_events);
ABSL_DECLARE_FLAG(bool, testing_events);
ABSL_DECLARE_FLAG(absl::optional<size_t>, redfish_event_store_size);
ABSL_DECLARE_FLAG(absl::optional<bool>, rde_ratelimit);
ABSL_DECLARE_FLAG(absl::optional<int>, rde_errors_max);
ABSL_DECLARE_FLAG(absl::optional<int>, rde_skips_max);
ABSL_DECLARE_FLAG(bool, multi_thread_get);
ABSL_DECLARE_FLAG(bool, exception_stack_tracer);
ABSL_DECLARE_FLAG(bool, enable_tlbmc);
ABSL_DECLARE_FLAG(bool, enable_tlbmc_trace);
ABSL_DECLARE_FLAG(bool, enable_tlbmc_thermal_control);
ABSL_DECLARE_FLAG(bool, enable_fast_sanity);
ABSL_DECLARE_FLAG(std::string, entity_config_location);
ABSL_DECLARE_FLAG(std::string, server_cert_path);
ABSL_DECLARE_FLAG(std::string, server_private_key_path);
ABSL_DECLARE_FLAG(bool, enable_configure_core_count);
ABSL_DECLARE_FLAG(bool, enable_redfish_configure_ifs);
ABSL_DECLARE_FLAG(std::string, smbios_single_host_file_path);
ABSL_DECLARE_FLAG(std::string, smbios_multihost_host_file_path_prefix);
#endif // BMCWEB_ENABLE_GRPC
#include <memory>
#include <string>
#include "boost/asio/io_context.hpp" // NOLINT
#include "redfish_devpath_injector.hpp"
#include "google/google_service_nvme.hpp"
#include "google/google_service_root.hpp"
#include "sdbusplus/asio/connection.hpp"
// Default number of Redfish Events stored.
constexpr size_t defaultRedfishEventStoreSize = 1000;
inline void setupSocket(crow::App& app) {
constexpr uint16_t defaultPort = 18080;
int listenFd = sd_listen_fds(0);
uint16_t portNumber = defaultPort;
#ifdef BMCWEB_ENABLE_GRPC
portNumber = static_cast<uint16_t>(
absl::GetFlag(FLAGS_httpport).value_or(defaultPort));
#endif
BMCWEB_LOG_ALWAYS << "setupSocket: defaultPort: " << defaultPort
<< " portNumber: " << portNumber
<< " listenFd: " << listenFd;
if (1 == listenFd) {
BMCWEB_LOG_INFO << "attempting systemd socket activation";
if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1, 0) !=
0) {
BMCWEB_LOG_INFO << "Starting webserver on socket handle "
<< SD_LISTEN_FDS_START;
app.socket(SD_LISTEN_FDS_START);
} else {
BMCWEB_LOG_ERROR << "bad incoming socket, starting webserver on port "
<< portNumber;
app.port(portNumber);
}
} else {
BMCWEB_LOG_INFO << "Starting webserver on port: " << portNumber;
app.port(portNumber);
}
}
inline std::shared_ptr<milotic_tlbmc::SystemRegistryImpl>
createSystemRegistryImpl() {
milotic_tlbmc::SystemRegistryImpl::Config config{};
#ifdef ENABLE_CONFIGURE_CORE_COUNT
config.bios_config_config =
std::make_unique<::platforms::gbmc::hal::BiosConfigConfig>();
#endif
absl::StatusOr<std::shared_ptr<milotic_tlbmc::SystemRegistryImpl>>
system_registry = milotic_tlbmc::SystemRegistryImpl::Create(config);
if (!system_registry.ok()) {
LOG(WARNING) << "Failed to create system registry: "
<< system_registry.status();
return nullptr;
}
return *system_registry;
}
inline std::shared_ptr<milotic_tlbmc::CredentialManager>
createCredentialManagerImpl(
const milotic::RedfishServiceConfig& config,
const milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams*
custom_params = nullptr) {
if (custom_params != nullptr) {
absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>>
credential_manager =
milotic_tlbmc::CredentialManagerImpl::Create(*custom_params);
if (!credential_manager.ok()) {
LOG(WARNING) << "Failed to create credential manager: "
<< credential_manager.status();
return nullptr;
}
return *std::move(credential_manager);
}
milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams params{
.private_key_path = config.private_key_path,
.cert_path = config.own_cert_path,
.owner_verification_cert_path = config.owner_verification_cert_path,
.owner_verification_config_path = config.owner_verification_config_path,
.bmc_ssh_trusted_user_ca_keys_path =
config.bmc_ssh_trusted_user_ca_keys_path,
.trust_bundle_path = config.trust_bundle_path,
.trust_bundle_signature_path = config.trust_bundle_signature_path,
.os_verification_cert_path = config.os_verification_cert_path,
.os_verification_key_path = config.os_verification_key_path,
.serial_console_trusted_user_ca_keys_path =
config.serial_console_trusted_user_ca_keys_path,
.serial_console_detatched_signature_path =
config.serial_console_detatched_signature_path,
.serial_console_access_level_dir = config.serial_console_access_level_dir,
.syslog_client_conf_override_path =
config.syslog_client_conf_override_path,
.syslog_root_cert_path = config.syslog_root_cert_path,
};
absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>>
credential_manager = milotic_tlbmc::CredentialManagerImpl::Create(params);
if (!credential_manager.ok()) {
LOG(WARNING) << "Failed to create credential manager: "
<< credential_manager.status();
return nullptr;
}
return *std::move(credential_manager);
}
inline int run() {
// First so even startup-path exceptions terminate with a throw-site stack.
// Also the explicit reference that pulls the tracer TU (and its __cxa_throw
// interposer) out of the bmcweblib archive despite --gc-sections.
#ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
installExceptionStackTracer(absl::GetFlag(FLAGS_exception_stack_tracer));
#endif // BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
std::shared_ptr<milotic_tlbmc::CredentialManager> credential_manager =
nullptr;
#ifdef BMCWEB_ENABLE_GRPC
absl::InitializeLog();
std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry =
createSystemRegistryImpl();
#ifdef ENABLE_CONFIGURE_CORE_COUNT
absl::Status status = system_registry->SetInitialCoreCounts();
if (!status.ok()) {
LOG(WARNING) << "Failed to set initial core counts: " << status;
}
#endif
milotic::RedfishServiceConfig secure_service_config;
secure_service_config.port = absl::GetFlag(FLAGS_mtls_grpc_port);
secure_service_config.private_key_path =
absl::GetFlag(FLAGS_server_private_key_path);
secure_service_config.own_cert_path = absl::GetFlag(FLAGS_server_cert_path);
secure_service_config.tlbmc_entity_config_location =
absl::GetFlag(FLAGS_entity_config_location);
secure_service_config.smbios_single_host_file_path =
absl::GetFlag(FLAGS_smbios_single_host_file_path);
secure_service_config.smbios_multihost_host_file_path_prefix =
absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix);
secure_service_config.multi_thread_get =
absl::GetFlag(FLAGS_multi_thread_get);
secure_service_config.enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc);
secure_service_config.generate_testing_events =
absl::GetFlag(FLAGS_testing_events);
secure_service_config.enable_fast_sanity =
absl::GetFlag(FLAGS_enable_fast_sanity);
secure_service_config.enable_hft_test_sensor = true;
secure_service_config.enable_tlbmc_trace =
absl::GetFlag(FLAGS_enable_tlbmc_trace);
secure_service_config.enable_tlbmc_thermal_control =
absl::GetFlag(FLAGS_enable_tlbmc_thermal_control);
secure_service_config.tlbmc_defer_router_registration_and_validation = true;
secure_service_config.system_registry = system_registry;
credential_manager = createCredentialManagerImpl(secure_service_config);
secure_service_config.credential_manager = credential_manager;
std::unique_ptr<milotic_tlbmc::RedfishApp> tlbmc_app =
milotic::GrpcRedfishService::CreateTlbmcApp(secure_service_config);
#ifdef ENABLE_LOAS3_VALIDATION
secure_service_config.check_loas3_policy = true;
LOG(WARNING) << "check_loas3_policy is enabled";
#endif
auto crowLogLevel = crow::LogLevel::Debug;
crow::Logger::setLogLevel(crowLogLevel);
const auto minAbslLogLevel =
static_cast<absl::LogSeverity>(absl::GetFlag(FLAGS_minloglevel));
BMCWEB_LOG_ALWAYS << "=> minAbslLogLevel: "
<< static_cast<int>(minAbslLogLevel);
switch (minAbslLogLevel) {
// unfortunately there is no: absl::LogSeverity::kInfo; so kInfo ->
// Debug for now.
case absl::LogSeverity::kInfo:
crowLogLevel = crow::LogLevel::Debug;
break;
case absl::LogSeverity::kWarning:
crowLogLevel = crow::LogLevel::Warning;
break;
case absl::LogSeverity::kError:
crowLogLevel = crow::LogLevel::Error;
break;
case absl::LogSeverity::kFatal:
crowLogLevel = crow::LogLevel::Critical;
break;
default:
crowLogLevel = crow::LogLevel::Error;
break;
}
BMCWEB_LOG_ALWAYS << "=> crowLogLevel: " << static_cast<int>(crowLogLevel);
crow::Logger::setLogLevel(crowLogLevel);
#else
crow::Logger::setLogLevel(crow::LogLevel::Debug);
#endif
auto io = std::make_shared<boost::asio::io_context>();
bool allowSessionEmpty = false;
#ifdef BMCWEB_INSECURE_DISABLE_AUTHX
allowSessionEmpty = true;
#endif
std::unique_ptr<devpath_plugin::RedfishDevpathInjector> devpath_injector =
nullptr;
absl::StatusOr<std::unique_ptr<devpath_plugin::RedfishDevpathInjector>>
injector = devpath_plugin::RedfishDevpathInjector::Create(
"/usr/share/redfish_to_uhm_mappings/"
"redfish_to_uhm_mappings.textproto");
if (injector.ok()) {
devpath_injector = std::move(*injector);
BMCWEB_LOG_ALWAYS << "RedfishDevpathInjector successfully initialized from "
"/usr/share/redfish_to_uhm_mappings/"
"redfish_to_uhm_mappings.textproto";
} else {
BMCWEB_LOG_ERROR << "Failed to initialize RedfishDevpathInjector: "
<< injector.status().message();
}
App app(allowSessionEmpty, io, tlbmc_app.get(), devpath_injector.get());
crow::globalBmcWebApp = &app;
std::shared_ptr<sdbusplus::asio::connection> systemBusPtr =
std::make_shared<sdbusplus::asio::connection>(*io);
#ifdef BMCWEB_ENABLE_GRPC
BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful: "
<< absl::GetFlag(FLAGS_stateful).value_or(false);
#endif
managedStore::ManagedObjectStoreConfig config;
// default to the compiler flag:
#ifdef BMCWEB_ENABLE_STATEFUL_BMCWEB
config.isEnabled = true;
#else
config.isEnabled = false;
#endif
// request stats config:
#ifdef BMCWEB_ENABLE_GRPC
{
const auto& persistentDataConfig = persistent_data::getConfig();
managedStore::RequestStatsStoreConfig requestStatsConfig;
requestStatsConfig.enable = false;
requestStatsConfig.enableRdeRateLimit = false;
// command line first:
if (absl::GetFlag(FLAGS_request_stats).has_value()) {
requestStatsConfig.enable =
absl::GetFlag(FLAGS_request_stats).value_or(false);
}
// enable rde rate limiter
if (absl::GetFlag(FLAGS_rde_ratelimit).has_value()) {
requestStatsConfig.enableRdeRateLimit =
absl::GetFlag(FLAGS_rde_ratelimit).value_or(false);
}
if (absl::GetFlag(FLAGS_rde_errors_max).has_value()) {
requestStatsConfig.rdeDbusErrorThreshold =
absl::GetFlag(FLAGS_rde_errors_max).value_or(10);
}
if (absl::GetFlag(FLAGS_rde_skips_max).has_value()) {
requestStatsConfig.rdeMaxSkips =
absl::GetFlag(FLAGS_rde_skips_max).value_or(30);
} else if (persistentDataConfig.isStatefulEnabled
.has_value()) { // persistent config:
requestStatsConfig.enable =
persistentDataConfig.isRequestStatsEnabled.value();
}
BMCWEB_LOG_STATEFUL_ALWAYS << "=> request_stats: "
<< requestStatsConfig.toJson();
managedStore::RequestStatsStore::initialize(requestStatsConfig);
}
#endif
// stateful logs:
#ifdef BMCWEB_ENABLE_GRPC
{
const auto& persistentDataConfig = persistent_data::getConfig();
bool enable_stateful_logs = false;
// command line first:
if (absl::GetFlag(FLAGS_stateful_logs).has_value()) {
enable_stateful_logs = absl::GetFlag(FLAGS_stateful_logs).value_or(false);
} else if (persistentDataConfig.isStatefulLogsEnabled
.has_value()) { // persistent config:
enable_stateful_logs = persistentDataConfig.isStatefulLogsEnabled.value();
}
BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful_logs flag: "
<< enable_stateful_logs;
if (enable_stateful_logs) {
crow::Logger::enableStatefulLogs();
}
}
#endif
// stateful config:
#ifdef BMCWEB_ENABLE_GRPC
// command line is always higher priority if set:
if (absl::GetFlag(FLAGS_stateful).has_value()) {
config.isEnabled = absl::GetFlag(FLAGS_stateful).value();
} else // NOLINT
#endif
{
// read the persistent data config:
const auto& persistentDataConfig = persistent_data::getConfig();
if (persistentDataConfig.isStatefulEnabled.has_value()) {
config.isEnabled = persistentDataConfig.isStatefulEnabled.value();
}
}
#ifdef BMCWEB_ENABLE_GRPC
// other flags:
if (absl::GetFlag(FLAGS_stateful_pending_max).has_value()) {
config.pendingDbusResponsesMax = static_cast<uint64_t>(
absl::GetFlag(FLAGS_stateful_pending_max).value());
}
if (absl::GetFlag(FLAGS_stateful_tfixed_sec).has_value()) {
config.tfixedThreshold =
std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tfixed_sec).value());
}
if (absl::GetFlag(FLAGS_stateful_tgrace_sec).has_value()) {
config.tgraceThreshold =
std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tgrace_sec).value());
}
if (absl::GetFlag(FLAGS_stateful_tlru_sec).has_value()) {
config.tLRUThreshold =
std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tlru_sec).value());
}
if (absl::GetFlag(FLAGS_timetrace).has_value()) {
config.timetrace = absl::GetFlag(FLAGS_timetrace).value();
}
if (absl::GetFlag(FLAGS_timetrace_size_max).has_value()) {
config.timetrace_size_max = absl::GetFlag(FLAGS_timetrace_size_max).value();
}
#endif
BMCWEB_LOG_STATEFUL_ALWAYS << "=> ManagedObjectStoreConfig: "
<< config.toString();
#ifndef BMCWEB_ENABLE_STATEFUL_BMCWEB
if (config.isEnabled) {
BMCWEB_LOG_WARNING
<< "ManagedObjectStore can't be enabled without "
<< "BMCWEB_ENABLE_STATEFUL_BMCWEB; reverting to stateful=0";
config.isEnabled = false;
}
#endif // BMCWEB_ENABLE_STATEFUL_BMCWEB
setupSocket(app);
std::unique_ptr<ecclesia::SubscriptionService> subscriptionService = nullptr;
#ifdef BMCWEB_ENABLE_GRPC
bool enableRedfishEvents = absl::GetFlag(FLAGS_redfish_events);
size_t number_of_events_stored = defaultRedfishEventStoreSize;
if (absl::GetFlag(FLAGS_redfish_event_store_size).has_value()) {
number_of_events_stored =
absl::GetFlag(FLAGS_redfish_event_store_size).value();
}
using ::milotic::GrpcRedfishService;
using ::milotic::RedfishServiceConfig;
if (enableRedfishEvents) {
BMCWEB_LOG_ALWAYS << "Redfish events enabled\n";
subscriptionService = CreateSubscriptionService(
milotic::BmcWebBackend::Create(&app),
ecclesia::CreateSubscriptionStore(),
ecclesia::CreateEventStore(number_of_events_stored));
}
#endif
// ManagedStore should be initialized regardless of whether grpc is enabled
auto io_worker_threads = std::make_shared<boost::asio::io_context>();
uint num_workers = std::thread::hardware_concurrency();
boost::asio::thread_pool worker_threads(num_workers);
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
work_guard_worker_threads(
boost::asio::make_work_guard(*io_worker_threads));
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
work_guard_main_thread(boost::asio::make_work_guard(*io));
for (uint i = 0; i < num_workers; ++i) {
boost::asio::post(worker_threads,
[io_worker_threads]() { io_worker_threads->run(); });
}
managedStore::InitializeManagedStore(&config, io.get(), io_worker_threads,
subscriptionService.get(),
systemBusPtr.get(), system_registry);
// Static assets need to be initialized before Authorization, because auth
// needs to build the whitelist from the static routes
#ifdef BMCWEB_ENABLE_STATIC_HOSTING
crow::webassets::requestRoutes(app);
#endif
#ifdef BMCWEB_ENABLE_REDFISH
redfish::RedfishService redfish(app);
#endif
#ifdef BMCWEB_ENABLE_DBUS_REST
crow::image_upload::requestRoutes(app);
crow::openbmc_mapper::requestRoutes(app);
#endif
#ifdef BMCWEB_ENABLE_GOOGLE_API
crow::google_api::setupCredentialManager(credential_manager);
crow::google_api::requestRoutes(app);
crow::google_api::requestGoogleNVMeCollection(app);
crow::google_api::requestGoogleNVMe(app);
crow::google_api::requestGoogleNVMeController(app);
crow::google_api::requestGoogleNVMeControllerCollection(app);
crow::google_api::setupGoogleNVMeFdFetchIOContext(io);
crow::google_api::requestGoogleNVMeControllerActionIdentify(app);
crow::google_api::requestGoogleNVMeControllerActionLog(app);
crow::google_api::requestGoogleNVMeControllerActionCustomNVMeIdentify(app);
crow::google_api::requestGoogleNVMeControllerActionAdminNonData(app);
crow::google_api::requestGoogleNVMeControllerActionLockdownInband(app);
#endif
if (bmcwebInsecureDisableXssPrevention != 0) {
cors_preflight::requestRoutes(app);
}
#ifdef BMCWEB_ENABLE_GRPC
#ifdef BMCWEB_ENABLE_INSECURE_GRPC
std::cerr << "insecure grpc opened!\n";
RedfishServiceConfig insecure_config{
.port = absl::GetFlag(FLAGS_insecure_grpc_port),
.self_signed_key_cert_path = "/var/volatile/self_signed_key_cert2.pem",
.tlbmc_entity_config_location =
absl::GetFlag(FLAGS_entity_config_location),
.smbios_single_host_file_path =
absl::GetFlag(FLAGS_smbios_single_host_file_path),
.smbios_multihost_host_file_path_prefix =
absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix),
.multi_thread_get = absl::GetFlag(FLAGS_multi_thread_get),
.enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc),
.enable_insecure_server = true,
.enable_fast_sanity = absl::GetFlag(FLAGS_enable_fast_sanity),
.enable_tlbmc_thermal_control =
absl::GetFlag(FLAGS_enable_tlbmc_thermal_control),
.tlbmc_defer_router_registration_and_validation = true,
.system_registry = system_registry,
.credential_manager = credential_manager,
};
GrpcRedfishService insecure_grpc_service(
&app, tlbmc_app.get(), io, io_worker_threads, insecure_config, nullptr);
#endif
GrpcRedfishService grpc_service(&app, tlbmc_app.get(), io, io_worker_threads,
secure_service_config,
subscriptionService.get());
#endif
// Register tlBMC append plugins before gBMCWeb plugins
GrpcRedfishService::RegisterTlbmcRoutesAndValidate(tlbmc_app.get());
// These have to be registered after managedStore initialization
#ifdef BMCWEB_ENABLE_SSL
BMCWEB_LOG_INFO << "Start Hostname Monitor Service...";
crow::hostname_monitor::registerHostnameSignal();
#endif
bmcweb::registerUserRemovedSignal();
#ifdef PLATFORM_PLUGINS_ENABLED
redfish_plugin::loadPlatformPlugins();
#endif
#ifdef GOOGLE_COMMON_PLUGINS_ENABLED
redfish_plugin::loadGooglePlugins();
#endif
#ifdef GOOGLE_PLUGINS_INTERNAL_ENABLED
redfish_plugin::loadGooglePluginsInternal();
#endif
#ifdef HEALTH_POPULATE
redfish::HealthStatusCache::getInstance();
#ifndef UNIT_TEST_BUILD
/*
* This call subscribes to a live D-Bus signal from the HealthMonitor.
* This directive excludes the live subscription call during the unit test
* build, allowing the test to verify logic without attempting to create
* a real signal match which does not exist in the test environment.
*/
managedStore::GetManagedObjectStore()->subscribeToEntityManagerChange(
[](const std::string& objPath) {
redfish::HealthStatusCache::getInstance().getHealthAttributes(objPath);
});
#endif /* UNIT_TEST_BUILD */
#endif /* HEALTH_POPULATE */
app.validate();
sd_notify(0, "READY=1");
app.run();
// This will block forever, so skipping these in unit test builds
#ifndef UNIT_TEST_BUILD
io->run();
io_worker_threads->stop();
worker_threads.join();
#endif
return 0;
}
#endif // THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_