blob: 9582998aa2102c6124e5f4471df1754161701dbb [file] [log] [blame] [edit]
#include "service_impl.h"
#include <memory>
#include <ostream>
#include "action_context.h"
#include "daemon_context.h"
#include "safepower_agent.pb.h"
#include "state_updater.h"
#include "absl/base/nullability.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
namespace safepower_agent {
absl::Status ServiceImpl::CheckDisruption() const {
absl::Duration disruption =
DaemonContext::Get().disruption_manager().PendingDisruption();
if (disruption > absl::ZeroDuration()) {
LOG(WARNING) << "Failing RPC because disruption is expected in "
<< disruption;
return absl::FailedPreconditionError(absl::StrCat(
"New operations not allowed because disruption is expected in ",
absl::FormatDuration(disruption)));
}
return absl::OkStatus();
}
void ServiceImpl::DumpSafepowerState(std::ostream& os) const {
os << "--- SafepowerLocalAgentImpl State ---" << std::endl;
action_context_manager_->DumpDebugInfo(os);
os << "--- System State ---" << std::endl;
os << system_state_updater_->state().DebugString() << std::endl;
os << "--- Global System State ---" << std::endl;
os << global_system_state_updater_->state().DebugString() << std::endl;
os << "--- End SafepowerLocalAgentImpl State ---" << std::endl;
}
absl::Status ServiceImpl::StartAction(
const safepower_agent_proto::StartActionRequest& request) {
if (auto status = CheckDisruption(); !status.ok()) return status;
absl::StatusOr<ActionContext* > action_context =
action_context_manager_->StartAction(request);
if (!action_context.ok()) {
LOG(ERROR) << "Failed to start action: " << action_context.status();
return action_context.status();
}
LOG(INFO) << "Started action from request: " << request.DebugString();
return absl::OkStatus();
}
absl::StatusOr<
std::shared_ptr<StateUpdater<safepower_agent_proto::ActionStateLog>>>
ServiceImpl::MonitorAction(
const safepower_agent_proto::MonitorActionRequest& request) {
if (auto status = CheckDisruption(); !status.ok()) return status;
ActionContext* action_context =
action_context_manager_->GetActionContext(request.flight_record());
if (action_context == nullptr) {
LOG(ERROR) << "Action flight_record: "
<< request.flight_record().DebugString() << " not found";
return absl::NotFoundError(absl::StrCat(
"Action flight_id: ", request.flight_record().flight_name(),
" step_id: ", request.flight_record().step_id(), " not found"));
}
return action_context->action_state_updater();
}
absl::StatusOr<
std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>>>
ServiceImpl::MonitorState() {
if (auto status = CheckDisruption(); !status.ok()) return status;
return system_state_updater_;
}
absl::Status ServiceImpl::SystemStateUpdate(
const safepower_agent_proto::SystemState& request) {
if (auto status = CheckDisruption(); !status.ok()) return status;
global_system_state_updater_->UpdateState(request);
return absl::OkStatus();
}
void ServiceImpl::GetSupportedActions(
safepower_agent_proto::GetSupportedActionsResponse& response) {
action_context_manager_->GetSupportedActions(response);
}
} // namespace safepower_agent