blob: 3d473877bd263b22960feaf5ac0db7315ac29bba [file]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_REDFISH_AGGREGATED_SENSOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_REDFISH_AGGREGATED_SENSOR_H_
#include <chrono> // NOLINT
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "google/protobuf/duration.pb.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "boost/asio.hpp" // NOLINT: boost::asio is commonly used in BMC
#include "boost/asio/error.hpp" // NOLINT
#include "boost/asio/random_access_file.hpp" // NOLINT: boost::asio is commonly used in BMC
#include "boost/beast/core.hpp" // NOLINT: boost::beast is commonly used in BMC
#include "boost/beast/http.hpp" // NOLINT: boost::beast is commonly used in BMC
#include "boost/beast/version.hpp" // NOLINT: boost::beast is commonly used in BMC
#include "boost/filesystem.hpp" // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/filesystem/operations.hpp" // NOLINT
#include "boost/system/detail/error_code.hpp" // NOLINT: boost::asio is commonly used in BMC
#include <nlohmann/json.hpp>
#include "liburing.h" // IWYU pragma: keep
#include "hal_common_config.pb.h"
#include "redfish_aggregated_sensor_config.pb.h"
#include "sensor_instance_properties.pb.h"
#include "threshold_config.pb.h"
#include "tlbmc/http/http_client_interface.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/polling_base_sensor.h"
#include "google/protobuf/util/json_util.h"
namespace milotic_tlbmc {
class RedfishAggregatedSensor
: public PollingBaseSensor,
public std::enable_shared_from_this<RedfishAggregatedSensor> {
private:
class Token;
public:
// Creates a RedfishAggregatedSensor.
static absl::StatusOr<std::shared_ptr<RedfishAggregatedSensor>> Create(
const RedfishAggregatedSensorConfig& config,
const std::shared_ptr<boost::asio::io_context>& io_context,
std::unique_ptr<HttpClientInterface> http_client,
std::optional<NotificationCb> on_batch_notify = std::nullopt);
RedfishAggregatedSensor(
Token token, const RedfishAggregatedSensorConfig& config,
const SensorInstanceProperties& sensor_instance_properties,
std::unique_ptr<HttpClientInterface> http_client,
const std::shared_ptr<boost::asio::io_context>& io_context,
std::optional<NotificationCb> on_batch_notify = std::nullopt);
~RedfishAggregatedSensor() override = default;
void RefreshOnceAsync(
absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
callback) override;
// Updates the state and timestamp of the sensor.
void UpdateStateAndTimestamp(Status status, absl::string_view status_message);
// Overrides the GetSensorMetrics function to remove the logic for hardware
// polling latency and include the logic for aggregated polling latency.
SensorMetrics GetSensorMetrics() const override;
// Overrides the ResetMetrics function to add the logic to reset the
// aggregated polling metrics.
void ResetMetrics() override;
// Overrides the GetMetricsAsJson function to remove hardware polling metrics
// and include the aggregated polling metrics.
absl::StatusOr<nlohmann::json> GetMetricsAsJson(
const ::google::protobuf::util::JsonPrintOptions& options) const override;
// Sets the is_managed_ flag to indicate whether the sensor is managed by a
// RedfishAggregatedBatchSensor.
void SetIsManaged(bool is_managed) { is_managed_ = is_managed; }
// Returns the sensor name.
const std::string& GetSensorName() const {
return config_.instance_properties().name();
}
// Returns the property of the sensor (managed sensor only).
const std::string& GetProperty() const { return config_.property(); }
// Updates the aggregated polling metrics from a batch refresh.
void UpdateAggregatedPollingMetricsFromBatch(
std::chrono::steady_clock::time_point time);
// Sets the last refresh start time from a batch refresh.
void SetLastRefreshStartTimeFromBatch(
std::chrono::steady_clock::time_point time);
// Updates the aggregated polling metrics from a batch refresh.
void SetAggregatedPollingStartTimeFromBatch(
std::chrono::steady_clock::time_point time);
// Updates the reading of the sensor from a batch refresh.
void UpdateReadingFromBatch(const nlohmann::json& json);
protected:
// Handles the completion of an http request to get the sensor value.
void HandleScanCompletion(
boost::beast::error_code ec,
boost::beast::http::response<boost::beast::http::string_body> res);
// Updates the aggregated polling metrics.
void UpdateAggregatedPollingMetrics(
std::chrono::steady_clock::duration interval);
// Handles the MetricReports schema from batch refresh.
void HandleMetricReports(const nlohmann::json& json);
// Handles the ProcessorMetrics schema from batch refresh.
void HandleProcessorMetrics(const nlohmann::json& json);
// Stores the reading of the sensor.
void StoreReading(double sensor_value);
private:
class Token {
private:
explicit Token() = default;
friend class RedfishAggregatedSensor;
};
static SensorUnit ConvertUnitStringToSensorUnit(
absl::string_view unit_string);
std::shared_ptr<boost::asio::io_context> io_context_;
std::string sensor_name_;
const RedfishAggregatedSensorConfig config_;
std::unique_ptr<HttpClientInterface> http_client_;
absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)> callback_;
// Sensor metrics variables.
// The start time of the aggregated polling request.
std::chrono::steady_clock::time_point aggregated_polling_start_time_ =
std::chrono::steady_clock::time_point::min();
// The total aggregated polling interval in milliseconds.
uint64_t total_aggregated_polling_interval_ms_ = 0;
// The total number of aggregated polling.
uint64_t total_aggregated_read_cnt_ = 0;
// Whether the sensor is managed by a RedfishAggregatedBatchSensor.
bool is_managed_ = false;
};
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_REDFISH_AGGREGATED_SENSOR_H_