Query ThermalSubsystem/Fans for every Chassis
Fans can have machine level devpaths as well.
Querying them requires the prerequisite that we figure out all the chassis on Redfish.
Created a helper and unit tested separately.
#tlbmc-fast-sanity
Shows on machine correctly
https://paste.googleplex.com/6562953008250880
PiperOrigin-RevId: 783407804
Change-Id: I122d4b3c66d52756272d0a343ea516869291397e
diff --git a/tlbmc/service/fru_service.cc b/tlbmc/service/fru_service.cc
index 30af4f7..f0529c8 100644
--- a/tlbmc/service/fru_service.cc
+++ b/tlbmc/service/fru_service.cc
@@ -17,6 +17,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
+#include "absl/types/span.h"
#include "g3/macros.h"
#include "grpcpp/security/auth_context.h"
#include "grpcpp/server_context.h"
@@ -318,6 +319,28 @@
return reactor;
}
+absl::StatusOr<std::vector<std::string>> FruServiceImpl::GetAllChassisUrls(
+ const nlohmann::json &json) {
+ auto members = json.find("Members");
+ if (members == json.end()) {
+ return absl::InternalError(
+ "Redfish response does not contain `Members` field.");
+ }
+
+ std::vector<std::string> chassis_urls;
+
+ for (const auto &fru : *members) {
+ auto odata_id = fru.find("@odata.id");
+ if (odata_id == fru.end()) {
+ LOG(WARNING) << "No `@odata.id` field found for FRU: " << fru;
+ continue;
+ }
+ chassis_urls.push_back(*odata_id);
+ }
+
+ return chassis_urls;
+}
+
void FruServiceImpl::GenerateMatchedDevpathsFromRedfishPaths(
ServerUnaryReactor &reactor, const GetAllFruInfoRequest &request,
GetAllFruInfoResponse &response) {
@@ -358,8 +381,18 @@
return;
}
+ absl::StatusOr<std::vector<std::string>> chassis_urls =
+ GetAllChassisUrls(res.jsonValue);
+ if (!chassis_urls.ok()) {
+ reactor.Finish(
+ ::grpc::Status(::grpc::StatusCode::INTERNAL,
+ std::string(chassis_urls.status().message())));
+ return;
+ }
+
RequestRedfishAndExtractDevpaths(reactor, request, response,
- *root_chassis_location_code_status);
+ *root_chassis_location_code_status,
+ *chassis_urls);
});
app_->handle(*crow_request_status, async_resp);
}
@@ -367,7 +400,8 @@
void FruServiceImpl::RequestRedfishAndExtractDevpaths(
ServerUnaryReactor &reactor, const GetAllFruInfoRequest &request,
GetAllFruInfoResponse &response,
- absl::string_view root_chassis_location_code) {
+ absl::string_view root_chassis_location_code,
+ absl::Span<const std::string> chassis_urls) {
auto fru_components = std::make_shared<FruComponents>();
// The root chassis is successfully extracted. Need to explicitly add its
@@ -378,12 +412,20 @@
FruComponent::STATUS_OK);
fru_components->AddFruComponent(std::move(root_fru_component));
+ // Combine all urls into one vector.
+ std::vector<std::string> all_urls(kRootUrls.begin(), kRootUrls.end());
+
+ for (const auto &url : chassis_urls) {
+ all_urls.push_back(
+ absl::StrFormat("%s/ThermalSubsystem/Fans?$expand=.", url));
+ }
+
std::shared_ptr<OngoingDevpathExtractionRequestCount>
ongoing_devpath_extraction_request_count =
std::make_shared<OngoingDevpathExtractionRequestCount>(
- kRootUrls.size());
+ all_urls.size());
- for (absl::string_view url : kRootUrls) {
+ for (absl::string_view url : all_urls) {
absl::StatusOr<crow::Request> devpath_request_status =
CreateRedfishRequest(url, boost::beast::http::verb::get);
if (!devpath_request_status.ok()) {
diff --git a/tlbmc/service/fru_service.h b/tlbmc/service/fru_service.h
index 4a2bdc5..95c3acd 100644
--- a/tlbmc/service/fru_service.h
+++ b/tlbmc/service/fru_service.h
@@ -6,12 +6,15 @@
#include <vector>
#include "absl/base/thread_annotations.h"
+#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
+#include "absl/types/span.h"
#include "grpcpp/security/auth_context.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/server_callback.h"
#include "grpcpp/support/status.h"
+#include "nlohmann/json_fwd.hpp"
#include "fru_component_model.pb.h"
#include "fru_service.grpc.pb.h"
#include "app.hpp"
@@ -32,7 +35,7 @@
absl::Mutex mutex;
std::vector<FruComponent> fru_components ABSL_GUARDED_BY(mutex);
- void AddFruComponent(FruComponent&& fru_component) {
+ void AddFruComponent(FruComponent &&fru_component) {
absl::MutexLock lock(&mutex);
fru_components.push_back(std::move(fru_component));
}
@@ -69,11 +72,15 @@
::grpc::Status RequestIsAuthenticated(
const ::grpc::AuthContext *auth_context) const;
+ static absl::StatusOr<std::vector<std::string>> GetAllChassisUrls(
+ const nlohmann::json &json);
+
protected:
void RequestRedfishAndExtractDevpaths(
::grpc::ServerUnaryReactor &reactor, const GetAllFruInfoRequest &request,
GetAllFruInfoResponse &response,
- absl::string_view root_chassis_location_code);
+ absl::string_view root_chassis_location_code,
+ absl::Span<const std::string> chassis_urls);
App *app_;
const bool has_trust_bundle_ = false;