virtual ErrorType Execute() = 0;
virtual const std::string GetRequestHandlerType() const = 0;
+ virtual std::list<ResPathInfo> GetResultPathList();
protected:
std::string GetRootPath();
std::string GetSrcRootPath();
std::string GetDstRootPath();
const std::string GetPkgID() const;
- const std::list<ResPathInfo> GetPathList() const;
+ std::list<ResPathInfo>& GetPathList();
uid_t GetUID() const;
private:
uid_t uid_;
std::string root_path_;
std::list<ResPathInfo> path_list_;
+ std::string result_path_;
};
} // namespace res_handler
ErrorType Execute() override;
const std::string GetRequestHandlerType() const override;
+ std::list<ResPathInfo> GetResultPathList() override;
};
} // namespace res_handler
#ifndef EVENT_SIGNAL_SENDER_HH_
#define EVENT_SIGNAL_SENDER_HH_
+#include <list>
#include <memory>
#include <string>
#include <pkgmgr_installer.h>
#include "include/error_type.hh"
+#include "include/res_path_info.hh"
#include "include/request_type.hh"
namespace res_handler {
class EventSignalSender {
public:
EventSignalSender(pkgmgr_installer* installer);
- bool SendStart();
- bool SendOK();
- bool SendFail(ErrorType error);
+ bool SendStart(const std::list<ResPathInfo>& res_path_info);
+ bool SendOK(const std::list<ResPathInfo>& res_path_info);
+ bool SendFail(ErrorType error, const std::list<ResPathInfo>& res_path_info);
void SetPkgID(std::string pkgid);
void SetReqType(ReqType req_type);
void SetUID(uid_t uid);
void SetSessionID(std::string session_id);
private:
- bool SendSignal(const char* status, ErrorType error);
+ bool SendSignal(const char* status, ErrorType error,
+ const std::list<ResPathInfo>& res_path_info);
std::string pkgid_;
ReqType req_type_;
class ResPathInfo {
public:
- ResPathInfo(std::string src, std::string dst);
+ enum class State {
+ NONE,
+ OK,
+ FAILED
+ };
+
+ ResPathInfo(std::string src, std::string dst, State state = State::NONE);
const std::string& GetSrcPath() const;
const std::string& GetDstPath() const;
+ const State GetState() const;
+ void SetState(State state);
private:
std::string src_;
std::string dst_;
+ State state_;
};
} // namespace res_handler
return pkgid_;
}
-const std::list<ResPathInfo> AbstractRequestHandler::GetPathList() const {
+std::list<ResPathInfo>& AbstractRequestHandler::GetPathList() {
return path_list_;
}
return uid_;
}
+std::list<ResPathInfo> AbstractRequestHandler::GetResultPathList() {
+ return path_list_;
+}
+
} // namespace res_handler
bf::path src_path = src_root_path / path_info.GetSrcPath();
if (!bf::exists(src_path)) {
LOG(ERROR) << "Path not exists :" << src_path;
+ path_info.SetState(ResPathInfo::State::FAILED);
return ErrorType::ERROR_RES_NOT_FOUND;
}
if (bf::is_directory(src_path)) {
if (!CopyDir(src_path, dst_path, FS_MERGE_OVERWRITE, true)) {
LOG(ERROR) << "Failed to copy directory " << src_path;
+ path_info.SetState(ResPathInfo::State::FAILED);
return ErrorType::ERROR_SYSTEM_ERROR;
}
} else {
if (!CopyFile(src_path, dst_path)) {
LOG(ERROR) << "Failed to copy directory " << src_path;
+ path_info.SetState(ResPathInfo::State::FAILED);
return ErrorType::ERROR_SYSTEM_ERROR;
}
}
+ path_info.SetState(ResPathInfo::State::OK);
}
return ErrorType::ERROR_NONE;
return kCopyReqHandlerType;
}
+std::list<ResPathInfo> CopyRequestHandler::GetResultPathList() {
+ bf::path src_root_path(GetSrcRootPath());
+ bf::path dst_root_path(GetDstRootPath());
+ std::list<ResPathInfo> result;
+
+ for (const auto& path_info : GetPathList()) {
+ bf::path src_path = src_root_path / path_info.GetSrcPath();
+ bf::path dst_path = dst_root_path / path_info.GetDstPath();
+ bf::path result_path = path_info.GetDstPath();
+
+ if (bf::is_directory(dst_path) && !bf::is_directory(src_path))
+ result_path /= src_path.filename();
+
+ result.emplace_back(result_path.string(), "", path_info.GetState());
+ }
+
+ return result;
+}
+
} // namespace res_handler
for (auto& path_info : GetPathList()) {
bf::path dst_path = dst_root_path / path_info.GetSrcPath();
- if (!CreateDirs(GetPkgID(), dst_path))
+ if (!CreateDirs(GetPkgID(), dst_path)) {
+ path_info.SetState(ResPathInfo::State::FAILED);
return ErrorType::ERROR_SYSTEM_ERROR;
+ }
+ path_info.SetState(ResPathInfo::State::OK);
}
return ErrorType::ERROR_NONE;
#include "include/event_signal_sender.hh"
+#include <package-manager.h>
+
#include <iostream>
#include <string>
-#include <package-manager.h>
-#include <package-manager-types.h>
-
#include "include/error_type.hh"
#include "include/request_type.hh"
#include "include/logging.hh"
: pkgid_(""), req_type_(ReqType::REQ_TYPE_UNKNOWN),
uid_(0), session_id_(""), installer_(installer, pkgmgr_installer_free) {}
-bool EventSignalSender::SendSignal(const char* status, ErrorType error) {
+bool EventSignalSender::SendSignal(const char* status, ErrorType error,
+ const std::list<ResPathInfo>& res_path_info) {
if (!installer_)
return false;
return false;
}
- pkgmgr_res_event_info_set_error_code(event_info.get(),
- static_cast<int>(error));
+ if (pkgmgr_res_event_info_set_error_code(event_info.get(),
+ static_cast<int>(error)) != PKGMGR_R_OK) {
+ LOG(ERROR) << "Fail to set error code";
+ return false;
+ }
+
+ for (const ResPathInfo& info : res_path_info) {
+ pkgmgr_res_event_path_state state = PM_RES_EVENT_PATH_STATE_NONE;
+ if (info.GetState() == ResPathInfo::State::NONE)
+ state = PM_RES_EVENT_PATH_STATE_NONE;
+ else if (info.GetState() == ResPathInfo::State::OK)
+ state = PM_RES_EVENT_PATH_STATE_OK;
+ else if (info.GetState() == ResPathInfo::State::FAILED)
+ state = PM_RES_EVENT_PATH_STATE_FAILED;
+
+ if (pkgmgr_res_event_info_add_path_state(event_info.get(),
+ info.GetSrcPath().c_str(), state) != PKGMGR_R_OK) {
+ LOG(ERROR) << "Fail to add path state";
+ return false;
+ }
+ }
if (pkgmgr_installer_send_res_signal(installer_.get(), pkgid_.c_str(),
status, event_info.get()) != 0) {
return true;
}
-bool EventSignalSender::SendStart() {
- if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, ErrorType::ERROR_NONE)) {
+bool EventSignalSender::SendStart(const std::list<ResPathInfo>& res_path_info) {
+ if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR,
+ ErrorType::ERROR_NONE, res_path_info)) {
LOG(ERROR) << "Fail to send start signal";
return false;
}
return true;
}
-bool EventSignalSender::SendOK() {
- if (!SendSignal(PKGMGR_INSTALLER_OK_EVENT_STR, ErrorType::ERROR_NONE)) {
+bool EventSignalSender::SendOK(const std::list<ResPathInfo>& res_path_info) {
+ if (!SendSignal(PKGMGR_INSTALLER_OK_EVENT_STR,
+ ErrorType::ERROR_NONE, res_path_info)) {
LOG(ERROR) << "Fail to send ok signal";
return false;
}
return true;
}
-bool EventSignalSender::SendFail(ErrorType error) {
- if (!SendSignal(PKGMGR_INSTALLER_FAIL_EVENT_STR, error)) {
+bool EventSignalSender::SendFail(ErrorType error,
+ const std::list<ResPathInfo>& res_path_info) {
+ if (!SendSignal(PKGMGR_INSTALLER_FAIL_EVENT_STR, error, res_path_info)) {
LOG(ERROR) << "Fail to send fail signal";
return false;
}
continue;
}
- if (!RemoveAll(dst_path))
+ if (!RemoveAll(dst_path)) {
+ path_info.SetState(ResPathInfo::State::FAILED);
return ErrorType::ERROR_SYSTEM_ERROR;
+ }
+ path_info.SetState(ResPathInfo::State::OK);
}
return ErrorType::ERROR_NONE;
bool RequestHandlerInvoker::Validate() {
if (handler_ == nullptr) {
LOG(ERROR) << "Failed to initialize handler";
- signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR);
+ signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR, {});
return false;
}
option_.GetRequestType(), option_.GetPathList())
!= ErrorType::ERROR_NONE) {
LOG(ERROR) << "Validation failed";
- signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR);
+ signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR,
+ handler_->GetResultPathList());
return false;
}
bool RequestHandlerInvoker::Execute() {
if (handler_ == nullptr) {
- signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR);
+ signal_->SendFail(ErrorType::ERROR_SYSTEM_ERROR, {});
return false;
}
- signal_->SendStart();
+ signal_->SendStart(handler_->GetResultPathList());
ErrorType ret = handler_->Execute();
if (ret != ErrorType::ERROR_NONE) {
- signal_->SendFail(ret);
+ signal_->SendFail(ret, handler_->GetResultPathList());
return false;
}
- signal_->SendOK();
+ signal_->SendOK(handler_->GetResultPathList());
return true;
}
#include "include/res_handler.hh"
-#include <iostream>
-
#include <pkgmgr_installer.h>
+#include <iostream>
+
#include "include/event_signal_sender.hh"
#include "include/logging.hh"
#include "include/param_checker.hh"
res_handler::ParamChecker option(argc, argv);
if (!option.Validate()) {
LOG(ERROR) << "Invalid argument has given";
- signal->SendFail(ErrorType::ERROR_INVALID_PARAMETER);
+ signal->SendFail(ErrorType::ERROR_INVALID_PARAMETER, {});
return false;
}
signal->SetPkgID(option.GetPkgID());
namespace res_handler {
-ResPathInfo::ResPathInfo(std::string src, std::string dst) :
- src_(src), dst_(dst) {}
+ResPathInfo::ResPathInfo(std::string src, std::string dst, State state)
+ : src_(src), dst_(dst), state_(state) {}
const std::string& ResPathInfo::GetSrcPath() const {
return src_;
return dst_;
}
+const ResPathInfo::State ResPathInfo::GetState() const {
+ return state_;
+}
+
+void ResPathInfo::SetState(ResPathInfo::State state) {
+ state_ = state;
+}
+
} // namespace res_handler
signal.SetUID(0);
signal.SetSessionID("session_id");
- EXPECT_TRUE(signal.SendStart());
- EXPECT_TRUE(signal.SendOK());
- EXPECT_TRUE(signal.SendFail(res_handler::ErrorType::ERROR_NONE));
+ EXPECT_TRUE(signal.SendStart({}));
+ EXPECT_TRUE(signal.SendOK({}));
+ EXPECT_TRUE(signal.SendFail(res_handler::ErrorType::ERROR_NONE, {}));
}
TEST_F(EventSignalSenderTest, SendSignalWithNullPkgMgrInstaller) {
.Times(0);
EventSignalSender signal(nullptr);
- EXPECT_FALSE(signal.SendStart());
- EXPECT_FALSE(signal.SendOK());
- EXPECT_FALSE(signal.SendFail(res_handler::ErrorType::ERROR_NONE));
+ EXPECT_FALSE(signal.SendStart({}));
+ EXPECT_FALSE(signal.SendOK({}));
+ EXPECT_FALSE(signal.SendFail(res_handler::ErrorType::ERROR_NONE, {}));
}