Roll forward of cl/707220915
Fixed the unit test. The test was failing because the error message is different in a forge test environment.
Automated g4 rollback of changelist 707704110.
*** Reason for rollback ***
Rolling forward with fixes
*** Original change description ***
Automated g4 rollback of changelist 707220915.
*** Reason for rollback ***
Failing https://tap.corp.google.com/node_os.
*** Original change description ***
#gpowerd - Add build targets for HTTP connection and related
***
***
PiperOrigin-RevId: 713781207
Change-Id: I09b65b089f3461a13cf5a452a617e1876a739f13
diff --git a/bmc/http_connection.cc b/bmc/http_connection.cc
index 6e87ad7..8dec749 100644
--- a/bmc/http_connection.cc
+++ b/bmc/http_connection.cc
@@ -1,18 +1,29 @@
-#include <nlohmann/json.hpp>
#include "bmc/http_connection.h"
-#include "bmc/daemon_context_bmc.h"
-#include "boost/asio/ip/tcp.hpp" // NOLINT
-#include "boost/asio/ssl.hpp" // NOLINT
-#include "boost/asio/ssl/stream.hpp" // NOLINT
-#include "boost/beast/core.hpp" // NOLINT
-#include "boost/beast/core/tcp_stream.hpp" // NOLINT
-#include "boost/beast/http.hpp" // NOLINT
-#include "boost/beast/version.hpp" // NOLINT
-#include "absl/status/status.h"
-#include "absl/strings/string_view.h"
-#include "absl/log/log.h"
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include "bmc/daemon_context_bmc.h"
+#include "absl/functional/any_invocable.h"
+#include "absl/log/log.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+
+// NOLINTBEGIN(readability/boost)
+#include "boost/asio/ip/tcp.hpp"
+#include "boost/beast/core.hpp"
+#include "boost/beast/core/tcp_stream.hpp"
+#include "boost/beast/http.hpp"
+#include "boost/beast/version.hpp"
+// NOLINTEND(readability/boost)
+
+#include "nlohmann/json.hpp"
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
@@ -22,24 +33,20 @@
using boost::beast::flat_buffer;
using boost::beast::tcp_stream;
-
HttpConnection::HttpConnection(absl::Duration connection_timeout,
- absl::Duration write_timeout):
- stream_(boost::asio::make_strand
- (DaemonContextBMC::Get().get_io_context())),
- connection_timeout_(connection_timeout),
- write_timeout_(write_timeout)
-{}
+ absl::Duration write_timeout)
+ : stream_(
+ boost::asio::make_strand(DaemonContextBMC::Get().get_io_context())),
+ connection_timeout_(connection_timeout),
+ write_timeout_(write_timeout) {}
// perform_connection = connect -> write -> read -> callback
// all failing cases, skip to user provided callback with error
void HttpConnection::PerformConnection(
- http::verb verb,
- absl::string_view target,
- absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) && > in_callback,
- const nlohmann::json& body,
- const absl::string_view ip,
- const uint16_t port){
+ http::verb verb, absl::string_view target,
+ absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&> in_callback,
+ const nlohmann::json& body, const absl::string_view ip,
+ const uint16_t port) {
verb_ = verb;
body_ = body.dump();
target_ = target;
@@ -47,10 +54,9 @@
boost::system::error_code ec;
boost::asio::ip::address address =
- boost::asio::ip::address::from_string(std::string(ip).c_str(), ec);
- if (ec){
- LOG(INFO) << "Unable to build address from string ip:" <<
- std::string(ip);
+ boost::asio::ip::address::from_string(std::string(ip).c_str(), ec);
+ if (ec) {
+ LOG(INFO) << "Unable to build address from string ip:" << ip;
}
end_point_.address(address);
end_point_.port(port);
@@ -60,13 +66,10 @@
auto self = shared_from_this();
stream_.async_connect(end_point_,
- [self](beast::error_code ec) {
- self->Write(ec);
- });
+ [self](beast::error_code ec) { self->Write(ec); });
}
-void HttpConnection::Write(beast::error_code ec)
-{
+void HttpConnection::Write(beast::error_code ec) {
if (ec) {
std::move(provided_callback_)(absl::UnavailableError(
absl::StrCat("Failed to connect to BMC: ", ec.message())));
@@ -83,30 +86,24 @@
req_.prepare_payload();
stream_.expires_after(absl::ToChronoMilliseconds(write_timeout_));
auto self = shared_from_this();
- http::async_write(stream_, req_,
- [self](beast::error_code ec, size_t t){
- self->Read(ec, t);
- });
+ http::async_write(stream_, req_, [self](beast::error_code ec, size_t t) {
+ self->Read(ec, t);
+ });
}
-void HttpConnection::Read(beast::error_code ec, size_t ) {
+void HttpConnection::Read(beast::error_code ec, size_t) {
if (ec) {
std::move(provided_callback_)(absl::UnavailableError(
absl::StrCat("Failed in http write:", ec.message())));
return;
}
auto self = shared_from_this();
- http::async_read(stream_, buffer_, res_,
- [self](beast::error_code ec, size_t t)
- {
- self->Callback(ec, t);
- });
+ http::async_read(
+ stream_, buffer_, res_,
+ [self](beast::error_code ec, size_t t) { self->Callback(ec, t); });
}
-void HttpConnection::Callback(
- beast::error_code ec,
- std::size_t )
-{
+void HttpConnection::Callback(beast::error_code ec, std::size_t) {
absl::Status status = absl::OkStatus();
if (ec) {
LOG(ERROR) << "callback error handler: " << ec.message();
@@ -134,6 +131,5 @@
return;
}
std::move(provided_callback_)(js_body);
- return;
}
} // namespace safepower_agent
diff --git a/bmc/http_connection.h b/bmc/http_connection.h
index 3a06bf6..d767632 100644
--- a/bmc/http_connection.h
+++ b/bmc/http_connection.h
@@ -1,19 +1,26 @@
#ifndef PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_HTTP_CONNECTION_H_
#define PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_HTTP_CONNECTION_H_
-#include <nlohmann/json.hpp>
-#include "absl/status/status.h"
-#include "absl/status/statusor.h"
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
#include "absl/functional/any_invocable.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
-#include "boost/asio/ip/tcp.hpp" // NOLINT
-#include "boost/asio/ssl.hpp" // NOLINT
-#include "boost/asio/ssl/stream.hpp" // NOLINT
-#include "boost/beast/core.hpp" // NOLINT
-#include "boost/beast/core/tcp_stream.hpp" // NOLINT
-#include "boost/beast/http.hpp" // NOLINT
-#include "boost/beast/version.hpp" // NOLINT
+// NOLINTBEGIN(readability/boost)
+#include "boost/asio/ip/tcp.hpp"
+#include "boost/beast/core.hpp"
+#include "boost/beast/core/tcp_stream.hpp"
+#include "boost/beast/http.hpp"
+#include "boost/beast/http/string_body.hpp"
+#include "boost/beast/version.hpp"
+// NOLINTEND(readability/boost)
+
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
@@ -24,42 +31,34 @@
class HttpConnection : public std::enable_shared_from_this<HttpConnection> {
public:
- HttpConnection(absl::Duration connection_timeout =
- absl::Seconds(10),
- absl::Duration write_timeout =
- absl::Seconds(10));
+ explicit HttpConnection(absl::Duration connection_timeout = absl::Seconds(10),
+ absl::Duration write_timeout = absl::Seconds(10));
- void PerformConnection(http::verb verb,
- absl::string_view target,
- absl::AnyInvocable
- <void(absl::StatusOr<nlohmann::json>) && >
- callback,
- const nlohmann::json& body,
- absl::string_view ip = "127.0.0.1",
- const uint16_t port = 80);
+ void PerformConnection(
+ http::verb verb, absl::string_view target,
+ absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&> callback,
+ const nlohmann::json& body, absl::string_view ip = "127.0.0.1",
+ uint16_t port = 80);
- void Write(beast::error_code ec);
- void Read(beast::error_code ec,
- size_t bytes_transferred);
- void Callback(beast::error_code ec,
- std::size_t bytes_transferred);
+ void Write(beast::error_code ec);
+ void Read(beast::error_code ec, size_t bytes_transferred);
+ void Callback(beast::error_code ec, std::size_t bytes_transferred);
private:
- http::verb verb_;
- std::string target_;
- std::string body_;
- beast::tcp_stream stream_;
- beast::flat_buffer buffer_;
- absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&>
- provided_callback_;
- http::request<http::string_body> req_;
- http::response<http::string_body> res_;
- boost::asio::ip::tcp::endpoint end_point_;
- absl::Duration connection_timeout_;
- absl::Duration write_timeout_;
+ http::verb verb_;
+ std::string target_;
+ std::string body_;
+ beast::tcp_stream stream_;
+ beast::flat_buffer buffer_;
+ absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&>
+ provided_callback_;
+ http::request<http::string_body> req_;
+ http::response<http::string_body> res_;
+ boost::asio::ip::tcp::endpoint end_point_;
+ absl::Duration connection_timeout_;
+ absl::Duration write_timeout_;
};
-} // namespace safepower_agent
+} // namespace safepower_agent
#endif // PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_HTTP_CONNECTION_H_
-
diff --git a/bmc/http_connection_test.cc b/bmc/http_connection_test.cc
index 11318c8..8eb99dd 100644
--- a/bmc/http_connection_test.cc
+++ b/bmc/http_connection_test.cc
@@ -1,33 +1,39 @@
-#include <absl/status/status.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
+#include "bmc/http_connection.h"
-#include <safepower_agent_config.pb.h>
-
-
-#include <chrono> // NOLINT
-#include <cstdlib>
-#include <ctime>
-#include <iostream>
+#include <chrono> // NOLINT(build/c++11)
#include <memory>
#include <string>
+#include <utility>
+#include <vector>
-#include "state_updater.h"
#include "bmc/daemon_context_bmc.h"
-#include "bmc/http_connection.h"
#include "bmc/mock_server.h"
-#include "bmc/scheduler_bmc.h"
#include "bmc/redfish.h"
#include "bmc/state_monitor_bmc.h"
+#include "safepower_agent.pb.h"
+#include "safepower_agent_config.pb.h"
+#include "state_updater.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/str_cat.h"
+#include "absl/time/time.h"
+// NOLINTBEGIN(readability/boost)
+#include "boost/asio/io_context.hpp"
+#include "boost/beast/core.hpp"
+#include "boost/beast/http.hpp"
+#include "boost/beast/version.hpp"
+// NOLINTEND(readability/boost)
-#include "boost/beast/core.hpp" // NOLINT
-#include "boost/beast/http.hpp" // NOLINT
-#include "boost/beast/version.hpp" // NOLINT
-#include "boost/asio/io_context.hpp" // NOLINT
-
+#include "nlohmann/json.hpp"
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
-namespace mock_server_test {
+namespace {
+
+using mock_server_test::TestBoostServer;
+using ::testing::StartsWith;
TEST(http, NoConnection) {
// DO NOT start the test sever
@@ -37,12 +43,14 @@
bool callback_ran = false;
my_connection->PerformConnection(
(http::verb::post), "/redfish/v1/Systems/system/Actions/Power.Reset",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::UnavailableError(
- absl::StrCat("Failed to connect to BMC: ", "Connection refused")));
- callback_ran = true;
- }, {});
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_FALSE(jres.ok());
+ ASSERT_EQ(jres.status(),
+ absl::UnavailableError(absl::StrCat(
+ "Failed to connect to BMC: ", "Connection refused")));
+ callback_ran = true;
+ },
+ {});
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
@@ -50,21 +58,20 @@
TEST(http, BadAddress) {
DaemonContextBMC context; // only use DaemonContextBMC::Get()
- TestBoostServer my_server;
+ mock_server_test::TestBoostServer my_server;
my_server.Start(DaemonContextBMC::Get().get_io_context());
- auto my_connection = std::make_shared<HttpConnection>(absl::Seconds(0));
+ auto my_connection = std::make_shared<HttpConnection>(absl::ZeroDuration());
bool callback_ran = false;
my_connection->PerformConnection(
- (http::verb::post), "/redfish/v1/Systems/system/Actions/Power.Reset",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::UnavailableError(
- absl::StrCat("Failed to connect to BMC: ",
- "The socket was closed due to a timeout")));
- callback_ran = true;
- },
- {}, "240.0.0.0", 80);
+ (http::verb::post), "/redfish/v1/Systems/system/Actions/Power.Reset",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_TRUE(absl::IsUnavailable(jres.status()));
+ ASSERT_THAT(jres.status().message(),
+ StartsWith("Failed to connect to BMC: "));
+ callback_ran = true;
+ },
+ {}, "240.0.0.0", 80);
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
@@ -75,18 +82,20 @@
TestBoostServer my_server;
my_server.Start(DaemonContextBMC::Get().get_io_context());
- auto my_connection = std::make_shared<HttpConnection>
- (absl::Seconds(2), absl::Seconds(0));
+ auto my_connection =
+ std::make_shared<HttpConnection>(absl::Seconds(2), absl::ZeroDuration());
bool callback_ran = false;
my_connection->PerformConnection(
- (http::verb::post),
- "/redfish/v1/Systems/system/Actions/Power.Reset_never_write",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::UnknownError(
- "Callback error handler: The socket was closed due to a timeout"));
- callback_ran = true;
- }, {});
+ (http::verb::post),
+ "/redfish/v1/Systems/system/Actions/Power.Reset_never_write",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_FALSE(jres.ok());
+ ASSERT_EQ(jres.status(),
+ absl::UnknownError("Callback error handler: The socket was "
+ "closed due to a timeout"));
+ callback_ran = true;
+ },
+ {});
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
}
@@ -99,14 +108,16 @@
auto my_connection = std::make_shared<HttpConnection>();
bool callback_ran = false;
my_connection->PerformConnection(
- http::verb::post,
- "/redfish/v1/Systems/system/Actions/Power.Reset_malformed",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::InvalidArgumentError(
- absl::StrCat("Failed to parse JSON from BMC: ", malformedJson)));
- callback_ran = true;
- }, {});
+ http::verb::post,
+ "/redfish/v1/Systems/system/Actions/Power.Reset_malformed",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_FALSE(jres.ok());
+ ASSERT_EQ(jres.status(), absl::InvalidArgumentError(absl::StrCat(
+ "Failed to parse JSON from BMC: ",
+ mock_server_test::malformedJson)));
+ callback_ran = true;
+ },
+ {});
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
}
@@ -119,14 +130,15 @@
auto my_connection = std::make_shared<HttpConnection>();
bool callback_ran = false;
my_connection->PerformConnection(
- http::verb::post,
- "/redfish/v1/Systems/system/Actions/Power.Reset_NotFound",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::UnavailableError(
- "HTTP request failed with status: 404"));
- callback_ran = true;
- }, {});
+ http::verb::post,
+ "/redfish/v1/Systems/system/Actions/Power.Reset_NotFound",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_FALSE(jres.ok());
+ ASSERT_EQ(jres.status(), absl::UnavailableError(
+ "HTTP request failed with status: 404"));
+ callback_ran = true;
+ },
+ {});
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
}
@@ -139,19 +151,19 @@
auto my_connection = std::make_shared<HttpConnection>();
bool callback_ran = false;
my_connection->PerformConnection(
- http::verb::post, "/redfish/v1/Systems/system/Actions/Power.Reset",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_TRUE(jres.ok());
- callback_ran = true;
- nlohmann::json good = nlohmann::json::parse(goodJson);
- ASSERT_EQ(jres.value(), good);
- }, {});
+ http::verb::post, "/redfish/v1/Systems/system/Actions/Power.Reset",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_TRUE(jres.ok());
+ callback_ran = true;
+ nlohmann::json good = nlohmann::json::parse(mock_server_test::goodJson);
+ ASSERT_EQ(jres.value(), good);
+ },
+ {});
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
}
-
// redfish Tests
// redfish and http test both use mock server
// but they can not run at the same time
@@ -161,15 +173,14 @@
TestBoostServer my_server;
my_server.Start(DaemonContextBMC::Get().get_io_context());
bool callback_ran = false;
- Redfish::Get(
- "/redfish/v1/Systems/system_get",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_TRUE(jres.ok());
- nlohmann::json good = nlohmann::json::parse(goodSystemGet);
- ASSERT_EQ(jres.value(), good);
- callback_ran = true;
- });
-
+ Redfish::Get("/redfish/v1/Systems/system_get",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_TRUE(jres.ok());
+ nlohmann::json good =
+ nlohmann::json::parse(mock_server_test::goodSystemGet);
+ ASSERT_EQ(jres.value(), good);
+ callback_ran = true;
+ });
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
@@ -180,14 +191,14 @@
TestBoostServer my_server;
my_server.Start(DaemonContextBMC::Get().get_io_context());
bool callback_ran = false;
- Redfish::Get(
- "/redfish/v1/Systems/system_NotFound",
- [&callback_ran](absl::StatusOr<nlohmann::json> jres){
- ASSERT_FALSE(jres.ok());
- ASSERT_EQ(jres.status(), absl::UnavailableError(
- "HTTP request failed with status: 404"));
- callback_ran = true;
- });
+ Redfish::Get("/redfish/v1/Systems/system_NotFound",
+ [&callback_ran](absl::StatusOr<nlohmann::json> jres) {
+ ASSERT_FALSE(jres.ok());
+ ASSERT_EQ(jres.status(),
+ absl::UnavailableError(
+ "HTTP request failed with status: 404"));
+ callback_ran = true;
+ });
DaemonContextBMC::Get().get_io_context().run_for(std::chrono::seconds(1));
EXPECT_TRUE(callback_ran);
}
@@ -202,44 +213,41 @@
GpowerdConfig gpower_config;
auto state_monitor_config = gpower_config.add_state_monitor_config();
state_monitor_config->set_state_name("test_state");
- state_monitor_config->mutable_state_gathering_info()->
- set_collection_interval_ms(100);
- state_monitor_config->mutable_state_gathering_info()->mutable_redfish()->
- set_uri("/redfish/v1/Systems/system/_testingPowerState");
+ state_monitor_config->mutable_state_gathering_info()
+ ->set_collection_interval_ms(100);
+ state_monitor_config->mutable_state_gathering_info()
+ ->mutable_redfish()
+ ->set_uri("/redfish/v1/Systems/system/_testingPowerState");
// if the config file has a key, it should also have the corresponding state
- std::vector<std::pair
- <std::string, safepower_agent_proto::PowerStateSpecifier>>
- json_key_to_state_name = {
- {"PowerState_On",
- safepower_agent_proto::POWER_STATE_ON },
- {"PowerState_Off",
- safepower_agent_proto::POWER_STATE_OFF},
- {"PowerState_Paused",
- safepower_agent_proto::POWER_STATE_PAUSED},
- {"PowerState_PoweringOn",
- safepower_agent_proto::POWER_STATE_POWERING_ON},
- {"PowerState_PoweringOff",
- safepower_agent_proto::POWER_STATE_POWERING_OFF},
- {"PowerState_UNSPECIFIED_1",
- safepower_agent_proto::POWER_STATE_UNSPECIFIED},
- {"PowerState_UNSPECIFIED_2",
- safepower_agent_proto::POWER_STATE_UNSPECIFIED},
- {"",
- safepower_agent_proto::POWER_STATE_UNSPECIFIED},
- {"b",
- safepower_agent_proto::POWER_STATE_UNSPECIFIED}
- };
+ std::vector<
+ std::pair<std::string, safepower_agent_proto::PowerStateSpecifier>>
+ json_key_to_state_name = {
+ {"PowerState_On", safepower_agent_proto::POWER_STATE_ON},
+ {"PowerState_Off", safepower_agent_proto::POWER_STATE_OFF},
+ {"PowerState_Paused", safepower_agent_proto::POWER_STATE_PAUSED},
+ {"PowerState_PoweringOn",
+ safepower_agent_proto::POWER_STATE_POWERING_ON},
+ {"PowerState_PoweringOff",
+ safepower_agent_proto::POWER_STATE_POWERING_OFF},
+ {"PowerState_UNSPECIFIED_1",
+ safepower_agent_proto::POWER_STATE_UNSPECIFIED},
+ {"PowerState_UNSPECIFIED_2",
+ safepower_agent_proto::POWER_STATE_UNSPECIFIED},
+ {"", safepower_agent_proto::POWER_STATE_UNSPECIFIED},
+ {"b", safepower_agent_proto::POWER_STATE_UNSPECIFIED}};
for (auto str_state_pair : json_key_to_state_name) {
- state_monitor_config->mutable_state_gathering_info()->
- mutable_redfish()->set_json_key(str_state_pair.first);
+ state_monitor_config->mutable_state_gathering_info()
+ ->mutable_redfish()
+ ->set_json_key(str_state_pair.first);
state_monitor_config->set_state_name(str_state_pair.first);
state_monitor_config->mutable_system_component()->set_node_entity_tag("cn");
state_monitor_config->mutable_system_component()->set_name("PowerState");
- state_monitor_config->mutable_state_gathering_info()->
- mutable_prototype()->mutable_power_state()->set_state(
- safepower_agent_proto::POWER_STATE_POWERING_OFF);
+ state_monitor_config->mutable_state_gathering_info()
+ ->mutable_prototype()
+ ->mutable_power_state()
+ ->set_state(safepower_agent_proto::POWER_STATE_POWERING_OFF);
// build a new system state
safepower_agent_proto::SystemState initialState;
// set default power state
@@ -258,27 +266,27 @@
std::move(initialState), true);
// monitor new systemd state, with specific key
StateMonitorBMC state_monitor(reactor);
- ASSERT_EQ(state_monitor.BuildFromConfig(gpower_config),
- absl::OkStatus());
- DaemonContextBMC::Get().get_io_context().run_for
- (std::chrono::milliseconds(300));
+ ASSERT_EQ(state_monitor.BuildFromConfig(gpower_config), absl::OkStatus());
+ DaemonContextBMC::Get().get_io_context().run_for(
+ std::chrono::milliseconds(300));
// check the state monitor updates its reactor with the correct state
- EXPECT_EQ(reactor->state().node_state().at("cn")
- .component_state().at("PowerState").power_state().state(),
+ EXPECT_EQ(reactor->state()
+ .node_state()
+ .at("cn")
+ .component_state()
+ .at("PowerState")
+ .power_state()
+ .state(),
str_state_pair.second);
ASSERT_EQ(DaemonContextBMC::Get().scheduler().CancelAll(),
absl::OkStatus());
- DaemonContextBMC::Get().get_io_context().
- run_for(std::chrono::milliseconds(300));
+ DaemonContextBMC::Get().get_io_context().run_for(
+ std::chrono::milliseconds(300));
}
- DaemonContextBMC::Get().get_io_context()
- .run_for(std::chrono::milliseconds(1000));
+ DaemonContextBMC::Get().get_io_context().run_for(
+ std::chrono::milliseconds(1000));
}
-
-
-
-} // namespace mock_server_test
-} // namespace safepower_agent
-
+} // namespace
+} // namespace safepower_agent
diff --git a/bmc/mock_server.h b/bmc/mock_server.h
index cd7773e..ab04e06 100644
--- a/bmc/mock_server.h
+++ b/bmc/mock_server.h
@@ -1,23 +1,22 @@
#ifndef PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_MOCK_SERVER_H_
#define PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_MOCK_SERVER_H_
-#include <absl/status/status.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-
-#include <chrono> // NOLINT
+#include <chrono> // NOLINT(build/c++11)
+#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>
+#include <utility>
-#include "boost/beast/core.hpp" // NOLINT
-#include "boost/beast/http.hpp" // NOLINT
-#include "boost/beast/version.hpp" // NOLINT
-#include "boost/asio/io_context.hpp" // NOLINT
-
+// NOLINTBEGIN(readability/boost)
+#include "absl/strings/string_view.h"
+#include "boost/asio/io_context.hpp"
+#include "boost/beast/core.hpp"
+#include "boost/beast/http.hpp"
+#include "boost/beast/version.hpp"
+// NOLINTEND(readability/boost)
namespace safepower_agent {
namespace mock_server_test {
@@ -27,13 +26,12 @@
//
// using a boost http server to test the http client used in gpowerd
+namespace beast = boost::beast; // from <boost/beast.hpp>
+namespace http = beast::http; // from <boost/beast/http.hpp>
+namespace net = boost::asio; // from <boost/asio.hpp>
+using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
-namespace beast = boost::beast; // from <boost/beast.hpp>
-namespace http = beast::http; // from <boost/beast/http.hpp>
-namespace net = boost::asio; // from <boost/asio.hpp>
-using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
-
-std::string_view goodJson = R"(
+constexpr absl::string_view goodJson = R"(
{
"@Message.ExtendedInfo": [
{
@@ -47,7 +45,7 @@
]
})";
-std::string_view testingPowerStateJson = R"(
+constexpr absl::string_view testingPowerStateJson = R"(
{
"@odata.id": "/redfish/v1/Systems/system",
"@odata.type": "#ComputerSystem.v1_16_0.ComputerSystem",
@@ -67,7 +65,7 @@
"PowerState_UNSPECIFIED_2": "a"
})";
-std::string_view malformedJson = R"(
+constexpr absl::string_view malformedJson = R"(
"@Message.ExtendedInfo":
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The request completed successfully.",
@@ -79,7 +77,7 @@
]
})";
-std::string_view goodSystemGet = R"(
+constexpr absl::string_view goodSystemGet = R"(
{
"@odata.id": "/redfish/v1/Chassis",
"@odata.type": "#ChassisCollection.ChassisCollection",
@@ -116,211 +114,180 @@
"Name": "Chassis Collection"
})";
-class http_connection : public std::enable_shared_from_this<http_connection>
-{
+class http_connection : public std::enable_shared_from_this<http_connection> {
public:
- http_connection(tcp::socket socket)
- : socket_(std::move(socket)), skip_write_(false)
- {
- std::cerr <<"Test server connection made" << std::endl;
- }
+ explicit http_connection(tcp::socket socket)
+ : socket_(std::move(socket)), skip_write_(false) {
+ std::cerr << "Test server connection made" << std::endl;
+ }
- // Initiate the asynchronous operations associated with the connection.
- void start()
- {
- read_request();
- check_deadline();
- }
+ // Initiate the asynchronous operations associated with the connection.
+ void start() {
+ read_request();
+ check_deadline();
+ }
+
private:
- // The socket for the currently connected client.
- tcp::socket socket_;
+ // The socket for the currently connected client.
+ tcp::socket socket_;
- // The buffer for performing reads.
- beast::flat_buffer buffer_{8192};
+ // The buffer for performing reads.
+ beast::flat_buffer buffer_{8192};
- // The request message.
- http::request<http::dynamic_body> request_;
+ // The request message.
+ http::request<http::dynamic_body> request_;
- // The response message.
- http::response<http::dynamic_body> response_;
+ // The response message.
+ http::response<http::dynamic_body> response_;
- // The timer for putting a deadline on connection processing.
- net::steady_timer deadline_{
- socket_.get_executor(), std::chrono::seconds(60)};
- // Asynchronously receive a complete request message.
+ // The timer for putting a deadline on connection processing.
+ net::steady_timer deadline_{socket_.get_executor(), std::chrono::seconds(60)};
+ // Asynchronously receive a complete request message.
- bool skip_write_;
+ bool skip_write_;
- void read_request()
- {
- auto self = shared_from_this();
+ void read_request() {
+ auto self = shared_from_this();
- http::async_read(
- socket_,
- buffer_,
- request_,
- [self](beast::error_code ec,
- std::size_t bytes_transferred)
- {
- boost::ignore_unused(bytes_transferred);
- if (!ec)
- {
- self->process_request();
- }
- });
- }
+ http::async_read(
+ socket_, buffer_, request_,
+ [self](beast::error_code ec, std::size_t bytes_transferred) {
+ boost::ignore_unused(bytes_transferred);
+ if (!ec) {
+ self->process_request();
+ }
+ });
+ }
- void process_request()
- {
- response_.version(request_.version());
- response_.keep_alive(false);
+ void process_request() {
+ response_.version(request_.version());
+ response_.keep_alive(false);
- switch (request_.method())
- {
+ switch (request_.method()) {
case http::verb::post:
- response_.result(http::status::ok);
- response_.set(http::field::server, "Beast");
- response_.set(http::field::content_type, "text/plain");
- create_post_response();
- break;
+ response_.result(http::status::ok);
+ response_.set(http::field::server, "Beast");
+ response_.set(http::field::content_type, "text/plain");
+ create_post_response();
+ break;
case http::verb::get:
- response_.result(http::status::ok);
- response_.set(http::field::server, "Beast");
- create_get_response();
- break;
+ response_.result(http::status::ok);
+ response_.set(http::field::server, "Beast");
+ create_get_response();
+ break;
default:
- // We return responses indicating an error if
- // we do not recognize the request method.
- response_.result(http::status::bad_request);
- response_.set(http::field::content_type, "text/plain");
- beast::ostream(response_.body())
- << "Invalid request-method '"
- << std::string(request_.method_string())
- << "'";
- break;
- }
- if (!skip_write_){
- write_response();
+ // We return responses indicating an error if
+ // we do not recognize the request method.
+ response_.result(http::status::bad_request);
+ response_.set(http::field::content_type, "text/plain");
+ beast::ostream(response_.body())
+ << "Invalid request-method '"
+ << std::string(request_.method_string()) << "'";
+ break;
+ }
+ if (!skip_write_) {
+ write_response();
+ }
+ }
+ // Construct a response message based on the program state.
+ void create_post_response() {
+ response_.set(http::field::content_type, "text/html");
+ if (request_.target() == "/count") {
+ beast::ostream(response_.body()) << "count_answer";
+ } else if (request_.target() == "/time") {
+ beast::ostream(response_.body()) << "time_answer";
+ } else if (request_.target() ==
+ "/redfish/v1/Systems/system/Actions/Power.Reset") {
+ beast::ostream(response_.body()) << goodJson;
+ } else if (request_.target() ==
+ "/redfish/v1/Systems/system/Actions/Power.Reset_never_write") {
+ skip_write_ = true;
+ } else if (request_.target() ==
+ "/redfish/v1/Systems/system/Actions/Power.Reset_malformed") {
+ beast::ostream(response_.body()) << malformedJson;
+ } else {
+ std::cerr << "request_.target():" << request_.target() << std::endl;
+ response_.result(http::status::not_found);
+ response_.set(http::field::content_type, "text/plain");
+ beast::ostream(response_.body()) << "File not found\r\n";
+ }
+ }
+ void create_get_response() {
+ if (request_.target() == "/count") {
+ response_.set(http::field::content_type, "text/html");
+ beast::ostream(response_.body()) << "count_answer";
+ } else if (request_.target() == "/redfish/v1/Systems/system_get") {
+ response_.set(http::field::content_type, "text/html");
+ beast::ostream(response_.body()) << goodSystemGet;
+ } else if (request_.target() ==
+ "/redfish/v1/Systems/system/_testingPowerState") {
+ beast::ostream(response_.body()) << testingPowerStateJson;
+ } else {
+ std::cerr << "request_.target():" << request_.target() << std::endl;
+ response_.result(http::status::not_found);
+ response_.set(http::field::content_type, "text/plain");
+ beast::ostream(response_.body()) << "File not found\r\n";
+ }
+ }
+
+ // Asynchronously transmit the response message.
+ void write_response() {
+ auto self = shared_from_this();
+
+ response_.content_length(response_.body().size());
+
+ http::async_write(socket_, response_,
+ [self](beast::error_code ec, std::size_t) {
+ self->socket_.shutdown(tcp::socket::shutdown_send, ec);
+ self->deadline_.cancel();
+ });
+ }
+
+ // Check whether we have spent enough time on this connection.
+ void check_deadline() {
+ auto self = shared_from_this();
+
+ deadline_.async_wait([self](beast::error_code ec) {
+ if (!ec) {
+ // Close socket to cancel any outstanding operation.
+ self->socket_.close(ec);
}
- }
- // Construct a response message based on the program state.
- void create_post_response()
- {
- response_.set(http::field::content_type, "text/html");
- if (request_.target() == "/count"){
- beast::ostream(response_.body())
- << "count_answer";
- } else if (request_.target() == "/time"){
- beast::ostream(response_.body())
- << "time_answer";
- } else if (request_.target() ==
- "/redfish/v1/Systems/system/Actions/Power.Reset"){
- beast::ostream(response_.body()) << goodJson;
- } else if (request_.target() ==
- "/redfish/v1/Systems/system/Actions/Power.Reset_never_write"){
- skip_write_ = true;
- } else if (request_.target() ==
- "/redfish/v1/Systems/system/Actions/Power.Reset_malformed"){
- beast::ostream(response_.body()) << malformedJson;
- } else {
- std::cerr << "request_.target():" << request_.target() << std::endl;
- response_.result(http::status::not_found);
- response_.set(http::field::content_type, "text/plain");
- beast::ostream(response_.body()) << "File not found\r\n";
- }
- }
- void create_get_response()
- {
- if (request_.target() == "/count")
- {
- response_.set(http::field::content_type, "text/html");
- beast::ostream(response_.body())
- << "count_answer";
- }else if (request_.target() == "/redfish/v1/Systems/system_get"){
- response_.set(http::field::content_type, "text/html");
- beast::ostream(response_.body()) << goodSystemGet;
- }else if (request_.target() ==
- "/redfish/v1/Systems/system/_testingPowerState"){
- beast::ostream(response_.body()) << testingPowerStateJson;
- }else{
- std::cerr << "request_.target():" << request_.target() << std::endl;
- response_.result(http::status::not_found);
- response_.set(http::field::content_type, "text/plain");
- beast::ostream(response_.body()) << "File not found\r\n";
- }
- }
-
- // Asynchronously transmit the response message.
- void write_response()
- {
- auto self = shared_from_this();
-
- response_.content_length(response_.body().size());
-
- http::async_write(
- socket_,
- response_,
- [self](beast::error_code ec, std::size_t)
- {
- self->socket_.shutdown(tcp::socket::shutdown_send, ec);
- self->deadline_.cancel();
- });
- }
-
- // Check whether we have spent enough time on this connection.
- void check_deadline()
- {
- auto self = shared_from_this();
-
- deadline_.async_wait(
- [self](beast::error_code ec)
- {
- if (!ec)
- {
- // Close socket to cancel any outstanding operation.
- self->socket_.close(ec);
- }
- });
- }
+ });
+ }
};
-void http_server(tcp::acceptor& acceptor, tcp::socket& socket)
-{
- acceptor.async_accept(socket,
- [&](beast::error_code ec)
- {
- if (!ec){
- std::make_shared<http_connection>(std::move(socket))->start();
- }else{
- std::cerr << "http_server error:" << ec.what() << std::endl;
- }
- http_server(acceptor, socket);
+inline void http_server(tcp::acceptor& acceptor, tcp::socket& socket) {
+ acceptor.async_accept(socket, [&](beast::error_code ec) {
+ if (!ec) {
+ std::make_shared<http_connection>(std::move(socket))->start();
+ } else {
+ std::cerr << "http_server error:" << ec.what() << std::endl;
+ }
+ http_server(acceptor, socket);
});
}
-class TestBoostServer
-{
+class TestBoostServer {
public:
- std::shared_ptr<tcp::acceptor> acceptor_;
- std::shared_ptr<tcp::socket> socket_;
+ std::shared_ptr<tcp::acceptor> acceptor_;
+ std::shared_ptr<tcp::socket> socket_;
- void Start(boost::asio::io_context& io_ctx)
- {
- auto const address = net::ip::make_address("0.0.0.0");
- uint16_t const port = 80;
- auto const doc_root = std::make_shared<std::string>("/redfish/v1/");
- boost::asio::ip::tcp::endpoint ep(address, port);
+ void Start(boost::asio::io_context& io_ctx) {
+ auto const address = net::ip::make_address("0.0.0.0");
+ uint16_t const port = 80;
+ auto const doc_root = std::make_shared<std::string>("/redfish/v1/");
+ boost::asio::ip::tcp::endpoint ep(address, port);
- socket_ = std::make_shared<tcp::socket>(io_ctx);
- acceptor_ = std::make_shared<tcp::acceptor>(io_ctx, ep);
+ socket_ = std::make_shared<tcp::socket>(io_ctx);
+ acceptor_ = std::make_shared<tcp::acceptor>(io_ctx, ep);
- http_server(*acceptor_, *socket_);
+ http_server(*acceptor_, *socket_);
}
- ~TestBoostServer(){
- acceptor_->cancel();
- socket_->close();
+ ~TestBoostServer() {
+ acceptor_->cancel();
+ socket_->close();
}
};
diff --git a/bmc/redfish.cc b/bmc/redfish.cc
index 6740cc8..7af5570 100644
--- a/bmc/redfish.cc
+++ b/bmc/redfish.cc
@@ -1,17 +1,16 @@
#include "bmc/redfish.h"
-#include <nlohmann/json.hpp>
-#include <safepower_agent.h>
-#include <safepower_agent.pb.h>
+#include <cstdint>
+#include <memory>
+#include <utility>
#include "bmc/http_connection.h"
-
-#include "absl/strings/string_view.h"
-#include "absl/status/statusor.h"
#include "absl/functional/any_invocable.h"
-#include "absl/log/log.h"
-
-#include "boost/asio/ip/tcp.hpp" // NOLINT
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "boost/asio/ip/tcp.hpp" // NOLINT(readability/boost)
+#include "nlohmann/json.hpp"
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
@@ -20,22 +19,14 @@
namespace beast = boost::beast;
namespace http = beast::http;
-void Get(
- absl::string_view target,
- absl::AnyInvocable
- <void(absl::StatusOr<nlohmann::json>) && >
- callback,
- absl::string_view ip,
- uint16_t port){
- auto connection = std::make_shared<HttpConnection>();
- connection->PerformConnection(http::verb::get,
- target,
- std::move(callback),
- "",
- ip,
- port);
- }
+void Get(absl::string_view target,
+ absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&> callback,
+ absl::string_view ip, uint16_t port) {
+ auto connection = std::make_shared<HttpConnection>();
+ connection->PerformConnection(http::verb::get, target, std::move(callback),
+ nlohmann::json{}, ip, port);
+}
-} // namespace Redfish
+} // namespace Redfish
-} // namespace safepower_agent
+} // namespace safepower_agent
diff --git a/bmc/redfish.h b/bmc/redfish.h
index a307ccd..5f7b81a 100644
--- a/bmc/redfish.h
+++ b/bmc/redfish.h
@@ -1,29 +1,24 @@
#ifndef PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_REDFISH_H_
#define PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_REDFISH_H_
-#include <nlohmann/json.hpp>
-#include <safepower_agent.pb.h>
-#include <state_persistence.pb.h>
+#include <cstdint>
-#include "absl/strings/string_view.h"
-#include "absl/status/statusor.h"
#include "absl/functional/any_invocable.h"
-
-#include "boost/asio/ip/tcp.hpp" // NOLINT
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "boost/asio/ip/tcp.hpp" // NOLINT(readability/boost)
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
namespace Redfish {
-void Get(absl::string_view URI,
- absl::AnyInvocable
- <void(absl::StatusOr<nlohmann::json>) && >
- callback,
- absl::string_view ip = "127.0.0.1",
- uint16_t port = 80);
+void Get(absl::string_view target,
+ absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&> callback,
+ absl::string_view ip = "127.0.0.1", uint16_t port = 80);
-} // namespace Redfish
+} // namespace Redfish
-} // namespace safepower_agent
+} // namespace safepower_agent
#endif // PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_REDFISH_H_
diff --git a/bmc/state_monitor_bmc.cc b/bmc/state_monitor_bmc.cc
index a25c0f3..da0d856 100644
--- a/bmc/state_monitor_bmc.cc
+++ b/bmc/state_monitor_bmc.cc
@@ -1,193 +1,169 @@
#include "bmc/state_monitor_bmc.h"
-#include <safepower_agent_config.pb.h>
-
-#include <any>
-#include <filesystem> // NOLINT
-#include <fstream>
+#include <cstdint>
+#include <memory>
#include <string>
-#include <unordered_map>
-#include <utility>
-
-#include "nlohmann/json.hpp"
-#include "absl/status/status.h"
-#include "absl/status/statusor.h"
-#include "absl/strings/string_view.h"
-
-#include "safepower_agent.pb.h"
-#include "state_updater.h"
-
-
-#include "bmc/redfish.h"
-#include "absl/base/log_severity.h"
-#include "absl/log/log.h"
#include "bmc/daemon_context_bmc.h"
+#include "bmc/redfish.h"
+#include "safepower_agent.pb.h"
+#include "safepower_agent_config.pb.h"
+#include "state_updater.h"
+#include "absl/log/log.h"
+#include "absl/status/status.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "nlohmann/json.hpp"
+#include "nlohmann/json_fwd.hpp"
namespace safepower_agent {
-using safepower_agent_config::SafePowerAgentConfig;
using safepower_agent_config::GpowerdConfig;
-using safepower_agent_config::StateMonitorConfig;
using safepower_agent_config::StateGatheringInfo;
-using safepower_agent_config::RedfishInfo;
-using safepower_agent_config::DbusInfo;
StateMonitorBMC::StateMonitorBMC(
std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>> reactor)
: reactor_(reactor) {}
-absl::Status StateMonitorBMC::BuildFromConfig(const GpowerdConfig& config)
-{
- for (auto& resource_to_monitor : config.state_monitor_config()){
+absl::Status StateMonitorBMC::BuildFromConfig(const GpowerdConfig& config) {
+ for (auto& resource_to_monitor : config.state_monitor_config()) {
if (resource_to_monitor.state_gathering_info().info_case() ==
StateGatheringInfo::kRedfish) {
std::string state_name = resource_to_monitor.state_name();
- std::string uri = resource_to_monitor.state_gathering_info()
- .redfish().uri();
- std::string json_key = resource_to_monitor.state_gathering_info()
- .redfish().json_key();
- std::string node_entity_tag = resource_to_monitor.system_component()
- .node_entity_tag();
- std::string component_name = resource_to_monitor.system_component()
- .name();
+ std::string uri =
+ resource_to_monitor.state_gathering_info().redfish().uri();
+ std::string json_key =
+ resource_to_monitor.state_gathering_info().redfish().json_key();
+ std::string node_entity_tag =
+ resource_to_monitor.system_component().node_entity_tag();
+ std::string component_name =
+ resource_to_monitor.system_component().name();
uint64_t collection_interval_ms =
resource_to_monitor.state_gathering_info().collection_interval_ms();
- auto prototype = resource_to_monitor.state_gathering_info()
- .prototype();
- if (prototype.has_power_state()
- && (prototype.power_state().has_state())) {
- // create bmcweb state monitor for power state
- if (!CreateRedfishUpdatePowerState(
- state_name, uri, json_key, collection_interval_ms, node_entity_tag,
- component_name).ok()){
+ auto prototype = resource_to_monitor.state_gathering_info().prototype();
+ if (prototype.has_power_state() &&
+ (prototype.power_state().has_state())) {
+ // create bmcweb state monitor for power state
+ if (!CreateRedfishUpdatePowerState(state_name, uri, json_key,
+ collection_interval_ms,
+ node_entity_tag, component_name)
+ .ok()) {
LOG(ERROR) << "failed to create bmcweb state monitor for: "
- << state_name;
- return absl::InvalidArgumentError
- ("failed to create bmcweb state monitor for: " + state_name);
+ << state_name;
+ return absl::InvalidArgumentError(
+ "failed to create bmcweb state monitor for: " + state_name);
}
} else {
LOG(ERROR) << "update function is not supported TODO b/372971177";
return absl::UnimplementedError("update function is not supported ");
}
- } else if (resource_to_monitor.state_gathering_info().info_case() ==
- StateGatheringInfo::kDbus) {
- (void)CreateDbusStateMonitor("", "", "", "", "", 1000);
+ } else if (resource_to_monitor.state_gathering_info().info_case() ==
+ StateGatheringInfo::kDbus) {
+ (void)CreateDbusStateMonitor("", "", "", "", "", 1000);
} else {
LOG(ERROR) << "state monitor type is not supported; "
<< resource_to_monitor.state_gathering_info().info_case();
- return absl::InvalidArgumentError
- ("state monitor type is not supported: " +
- resource_to_monitor.state_gathering_info().info_case());
+ return absl::InvalidArgumentError(
+ absl::StrCat("state monitor type is not supported: ",
+ resource_to_monitor.state_gathering_info().info_case()));
}
}
return absl::OkStatus();
}
absl::Status StateMonitorBMC::CreateRedfishUpdatePowerState(
- std::string state_name,
- std::string uri,
- std::string json_key,
- int collection_interval_ms,
- std::string node_entity_tag,
- std::string component_name)
- {
+ std::string state_name, std::string uri, std::string json_key,
+ int collection_interval_ms, std::string node_entity_tag,
+ std::string component_name) {
LOG(INFO) << "creating bmcweb state monitor for:" << state_name;
LOG(INFO) << "uri: " << uri;
LOG(INFO) << "json_key: " << json_key;
LOG(INFO) << "collection_interval_ms: " << collection_interval_ms;
-
return DaemonContextBMC::Get().scheduler().PeriodicCall(
[state_name, uri, json_key, this, node_entity_tag, component_name] {
- Redfish::Get(uri,
- [state_name, uri, json_key, this,
- node_entity_tag, component_name]
- (absl::StatusOr<nlohmann::json> js) {
- if (!js.ok()) {
- LOG(ERROR) << "Failed to get " << uri << " from BMC: "
- << js.status();
- return;
- }
-
- auto js_value = js->find(json_key);
- std::string state_str = js_value != js->end() ? *js_value : "";
- safepower_agent_proto::PowerStateSpecifier temp_power_state
- = ConvertStatePowerStringToEnum(state_str);
- const safepower_agent_proto::SystemState current_state
- = this->reactor_->state();
-
- safepower_agent_proto::PowerStateSpecifier last_ps =
- safepower_agent_proto::POWER_STATE_UNSPECIFIED;
- auto node_it = current_state.node_state().find(node_entity_tag);
- if (node_it != current_state.node_state().end()){
- auto component_it = node_it->second.component_state().
- find(component_name);
- if (component_it != node_it->second.component_state().end()){
- last_ps = component_it->second.power_state().state();
+ Redfish::Get(uri, [state_name, uri, json_key, this, node_entity_tag,
+ component_name](absl::StatusOr<nlohmann::json> js) {
+ if (!js.ok()) {
+ LOG(ERROR) << "Failed to get " << uri
+ << " from BMC: " << js.status();
+ return;
}
- }
- if (last_ps == temp_power_state) return;
- absl::string_view last_ps_str =
- PowerStateSpecifier_Name(last_ps);
- absl::string_view temp_ps_str =
- PowerStateSpecifier_Name(temp_power_state);
- LOG(INFO) << absl::StrFormat(
- "state changed from: %d (%s) to: %d (%s)", last_ps,
- last_ps_str, temp_power_state, temp_ps_str);
- // add new state power state to a new system proto
- safepower_agent_proto::SystemState new_state;
- safepower_agent_proto::PowerState ps;
- ps.set_state(temp_power_state);
+ auto js_value = js->find(json_key);
+ std::string state_str = js_value != js->end() ? *js_value : "";
+ safepower_agent_proto::PowerStateSpecifier temp_power_state =
+ ConvertStatePowerStringToEnum(state_str);
+ const safepower_agent_proto::SystemState current_state =
+ this->reactor_->state();
- safepower_agent_proto::ComponentState cs;
- *(cs.mutable_power_state()) = ps;
+ safepower_agent_proto::PowerStateSpecifier last_ps =
+ safepower_agent_proto::POWER_STATE_UNSPECIFIED;
+ auto node_it = current_state.node_state().find(node_entity_tag);
+ if (node_it != current_state.node_state().end()) {
+ auto component_it =
+ node_it->second.component_state().find(component_name);
+ if (component_it != node_it->second.component_state().end()) {
+ last_ps = component_it->second.power_state().state();
+ }
+ }
+ if (last_ps == temp_power_state) return;
+ absl::string_view last_ps_str = PowerStateSpecifier_Name(last_ps);
+ absl::string_view temp_ps_str =
+ PowerStateSpecifier_Name(temp_power_state);
+ LOG(INFO) << absl::StrFormat(
+ "state changed from: %d (%s) to: %d (%s)", last_ps, last_ps_str,
+ temp_power_state, temp_ps_str);
- safepower_agent_proto::NodeState ns;
- ns.mutable_component_state()->insert({component_name, cs});
- new_state.mutable_node_state()->insert({node_entity_tag, ns});
+ // add new state power state to a new system proto
+ safepower_agent_proto::SystemState new_state;
+ safepower_agent_proto::PowerState ps;
+ ps.set_state(temp_power_state);
- reactor_->UpdateState(new_state);
- });
+ safepower_agent_proto::ComponentState cs;
+ *(cs.mutable_power_state()) = ps;
+
+ safepower_agent_proto::NodeState ns;
+ ns.mutable_component_state()->insert({component_name, cs});
+ new_state.mutable_node_state()->insert({node_entity_tag, ns});
+
+ reactor_->UpdateState(new_state);
+ });
},
absl::Milliseconds(collection_interval_ms), state_name);
}
safepower_agent_proto::PowerStateSpecifier
- StateMonitorBMC::ConvertStatePowerStringToEnum(absl::string_view state_str){
- if (state_str == "On") {
- return safepower_agent_proto::POWER_STATE_ON;
- } else if (state_str == "Off") {
- return safepower_agent_proto::POWER_STATE_OFF;
- } else if (state_str == "Paused"){ // not in bmcweb
- return safepower_agent_proto::POWER_STATE_PAUSED;
- } else if (state_str == "PoweringOn") {
- return safepower_agent_proto::POWER_STATE_POWERING_ON;
- } else if (state_str == "PoweringOff") {
- return safepower_agent_proto::POWER_STATE_POWERING_OFF;
- } else {
- LOG(ERROR) << "failed to map power state string to enum: "
- << state_str;
- return safepower_agent_proto::POWER_STATE_UNSPECIFIED;
- }
+StateMonitorBMC::ConvertStatePowerStringToEnum(absl::string_view state_str) {
+ if (state_str == "On") {
+ return safepower_agent_proto::POWER_STATE_ON;
+ } else if (state_str == "Off") {
+ return safepower_agent_proto::POWER_STATE_OFF;
+ } else if (state_str == "Paused") { // not in bmcweb
+ return safepower_agent_proto::POWER_STATE_PAUSED;
+ } else if (state_str == "PoweringOn") {
+ return safepower_agent_proto::POWER_STATE_POWERING_ON;
+ } else if (state_str == "PoweringOff") {
+ return safepower_agent_proto::POWER_STATE_POWERING_OFF;
+ } else {
+ LOG(ERROR) << "failed to map power state string to enum: " << state_str;
+ return safepower_agent_proto::POWER_STATE_UNSPECIFIED;
+ }
}
-absl::Status StateMonitorBMC::CreateDbusStateMonitor(std::string state_name,
- std::string dbus_path,
- std::string dbus_method,
- std::string dbus_interface,
- std::string dbus_value,
- int collection_interval_ms)
- {
+absl::Status StateMonitorBMC::CreateDbusStateMonitor(
+ std::string state_name, std::string dbus_path, std::string dbus_method,
+ std::string dbus_interface, std::string dbus_value,
+ int collection_interval_ms) {
LOG(INFO) << "creating dbus state monitor for:" << state_name;
LOG(INFO) << "dbus_path: " << dbus_path;
LOG(INFO) << "dbus_method: " << dbus_method;
LOG(INFO) << "dbus_interface: " << dbus_interface;
LOG(INFO) << "dbus_value: " << dbus_value;
LOG(INFO) << "collection_interval_ms: " << collection_interval_ms;
- return absl::UnimplementedError
- ("CreateDbusStateMonitor is not implemented");
+ return absl::UnimplementedError("CreateDbusStateMonitor is not implemented");
}
} // namespace safepower_agent
diff --git a/bmc/state_monitor_bmc.h b/bmc/state_monitor_bmc.h
index 618268d..9ae35f6 100644
--- a/bmc/state_monitor_bmc.h
+++ b/bmc/state_monitor_bmc.h
@@ -1,24 +1,22 @@
#ifndef PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_STATE_MONITOR_BMC_H_
#define PRODUCTION_SUSHID_SAFEPOWER_AGENT_BMC_STATE_MONITOR_BMC_H_
-#include <safepower_agent_config.pb.h>
-#include <any>
+#include <memory>
#include <string>
-#include <unordered_map>
-#include "absl/strings/string_view.h"
-#include "absl/status/status.h"
-#include "absl/status/statusor.h"
-
-#include "state_updater.h"
#include "safepower_agent.pb.h"
+#include "safepower_agent_config.pb.h"
+#include "state_updater.h"
+#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
namespace safepower_agent {
class StateMonitorBMC {
public:
- StateMonitorBMC(
- std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>> reactor);
+ explicit StateMonitorBMC(
+ std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>>
+ reactor);
~StateMonitorBMC() = default;
absl::Status BuildFromConfig(