Implement action request reply
authorSangyoon Jang <jeremy.jang@samsung.com>
Tue, 8 Apr 2025 05:11:56 +0000 (14:11 +0900)
committer장상윤/Tizen Platform Lab(SR)/삼성전자 <jeremy.jang@samsung.com>
Thu, 10 Apr 2025 01:00:24 +0000 (10:00 +0900)
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
12 files changed:
src/action/action_executor_factory.cc
src/action/action_request_handler.cc
src/action/action_request_handler.hh
src/action/app_control_executor.cc
src/action/app_control_executor.hh
src/action/plugin_executor.cc
src/action/plugin_executor.hh
src/action/request_handler.hh
src/action/request_reply_handler.hh [new file with mode: 0644]
src/action/service.cc
src/action/service.hh
src/common/action_executor.hh

index 965b700f4d381b696eeb5b800d53ee32b5e770db..9d34f9b65cb5e21ee5ff73702d46ce2e980908c2 100644 (file)
@@ -15,9 +15,6 @@ class DefaultActionExecutor : public common::AbstractActionExecutor {
     LOG(ERROR) << "DefaultActionExecutor::Execute";
     return -1;
   }
-  void SetResultHandler(common::IResultHandler* handler) override {
-    LOG(ERROR) << "DefaultActionExecutor::SetResultHandler";
-  }
 };
 
 std::unique_ptr<common::AbstractActionExecutor>
index 6a26867ca54018578fbbdf96f0957a58d5229db2..e0635bb6ae5fdd16fca322ef85ca8fba50fc8682 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <string>
 
 #include "action/action_executor_factory.hh"
@@ -122,9 +123,33 @@ void ActionRequestHandler::OnExecute(const std::string& instance,
   executors_.emplace_back(std::move(executor));
 }
 
+void ActionRequestHandler::RegisterRequestReplyHandler(const std::string& requester,
+    RequestReplyHandler* handler) {
+  reply_handlers_.emplace(requester, handler);
+}
+
+void ActionRequestHandler::UnregisterRequestReplyHandler(const std::string& requester) {
+  auto it = std::find_if(reply_handlers_.begin(), reply_handlers_.end(),
+      [requester](const auto& iterator) {
+        return iterator.first == requester;
+      });
+  if (it != reply_handlers_.end())
+    reply_handlers_.erase(it);
+  else
+    LOG(WARNING) << "No handler found for requester :" << requester;
+}
+
 void ActionRequestHandler::OnResult(const std::string& requester,
                                     const std::string& result) {
   LOG(DEBUG) << "OnResult : " << result << ", from : " << requester;
+  auto it = std::find_if(reply_handlers_.begin(), reply_handlers_.end(),
+      [requester](const auto& iterator) {
+        return iterator.first == requester;
+      });
+  if (it!= reply_handlers_.end())
+    it->second->SendRequestReply(result);
+  else
+    LOG(WARNING) << "No handler found for requester :" << requester;
 }
 
 }  // namespace action
index 023c1108cf641a20edaf87ce056879afc8409c3b..67f4ca64fca7d4604a97f37c33c3e2a4d7912f78 100644 (file)
@@ -41,6 +41,9 @@ class ActionRequestHandler : public IRequestHandler, common::IResultHandler {
                      float search_threshold) override;
   void OnExecute(const std::string& instance,
                  rpc::Action& model) override;
+  void RegisterRequestReplyHandler(const std::string& requester,
+                                   RequestReplyHandler* handler) override;
+  void UnregisterRequestReplyHandler(const std::string& requester) override;
 
   void OnResult(const std::string& requester,
                 const std::string& result) override;
@@ -48,6 +51,7 @@ class ActionRequestHandler : public IRequestHandler, common::IResultHandler {
  private:
   rpc_port::tizen_action_service_stub::stub::ActionService service_;
   std::vector<std::unique_ptr<common::AbstractActionExecutor>> executors_;
+  std::map<std::string, RequestReplyHandler*> reply_handlers_;
 };
 
 }  // namespace action
index 5e277b424988d75d556dfcbd905f2b328e0c9892..f54723608943ad58f1c1d4b9358bbf356f3ac9cd 100644 (file)
@@ -95,7 +95,7 @@ int AppControlExecutor::Execute(const common::ActionModel& model) {
 void AppControlExecutor::OnAppControlReply(const std::string& reply) {
   // TODO: Handle reply
   LOG(DEBUG) << "reply from instance: " << GetId() << ", reply: " << reply;
-  result_handler_->OnResult(GetId(), reply);
+  NotifyResult(reply);
 }
 
 void AppControlExecutor::AddExtraData(const common::ActionModel& model) {
@@ -119,8 +119,4 @@ bool AppControlExecutor::SendAppControl() {
   return true;
 }
 
-void AppControlExecutor::SetResultHandler(common::IResultHandler* handler) {
-  result_handler_ = handler;
-}
-
 }  // namespace action
index aa35822f77827d2b17309233c6224f9496aaa171..5c4f75d7ea281642e69fd948499ef606606fb81f 100644 (file)
@@ -31,7 +31,6 @@ class AppControlExecutor : public common::AbstractActionExecutor {
   int Execute(const common::ActionModel& model) override;
 
   void OnAppControlReply(const std::string& reply);
-  void SetResultHandler(common::IResultHandler* handler) override;
 
  private:
   void AddExtraData(const common::ActionModel& model);
@@ -39,7 +38,6 @@ class AppControlExecutor : public common::AbstractActionExecutor {
 
   common::ActionModel model_;
   app_control_h app_control_;
-  common::IResultHandler* result_handler_ = nullptr;
 };
 
 }  // namespace action
index 5b2bd9857e366eff7a0e4f04c540172a4eb728cb..cc98c2a5b1d4331497c305548903be0a8c3e2695 100644 (file)
@@ -79,13 +79,8 @@ int PluginExecutor::Execute(const common::ActionModel& model) {
 }
 
 void PluginExecutor::OnResultReceived(const std::string& result) {
-  // TODO: Handle result
   LOG(DEBUG) << "result from instance: " << GetId() << ", result: " << result;
-  result_handler_->OnResult(GetId(), result);
-}
-
-void PluginExecutor::SetResultHandler(common::IResultHandler* handler) {
-  result_handler_ = handler;
+  NotifyResult(result);
 }
 
 bool PluginExecutor::Connect() {
index ac9777dac0753b2260687e57c9d69e99202e1b18..aa4c3d4a764ef97bf42d7788e65bcf96f255dc7a 100644 (file)
@@ -32,7 +32,6 @@ class PluginExecutor : public common::AbstractActionExecutor,
   explicit PluginExecutor(std::string instance);
   ~PluginExecutor();
   int Execute(const common::ActionModel& model) override;
-  void SetResultHandler(common::IResultHandler* handler) override;
   void OnResultReceived(const std::string& result);
 
  private:
index 7311fdf7ecf2f5fb55986321343e62a1e5fa6f40..b26bf200cabc86baea99d64bd8c91392f574e2f5 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "common/action_model.h"
 
+#include "action/request_reply_handler.hh"
 #include "action/tizen_action_service_stub.h"
 
 namespace rpc = rpc_port::tizen_action_service_stub;
@@ -35,6 +36,9 @@ class IRequestHandler {
   virtual void OnGetActionId(const std::string& user_description, int top_k,
       float search_threshold) = 0;
   virtual void OnExecute(const std::string& requester, rpc::Action& model) = 0;
+  virtual void RegisterRequestReplyHandler(const std::string& requester,
+      RequestReplyHandler* handler) = 0;
+  virtual void UnregisterRequestReplyHandler(const std::string& requester) = 0;
 };
 
 }  // namespace action
diff --git a/src/action/request_reply_handler.hh b/src/action/request_reply_handler.hh
new file mode 100644 (file)
index 0000000..8dfa3fe
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ACTION_REQUEST_REPLY_HANDLER_HH_
+#define ACTION_REQUEST_REPLY_HANDLER_HH_
+
+#include <string>
+
+namespace action {
+
+class RequestReplyHandler {
+ public:
+  virtual ~RequestReplyHandler() = default;
+  virtual void SendRequestReply(const std::string& reply) = 0;
+};
+
+}  // namespace action
+
+#endif  // ACTION_REQUEST_REPLY_HANDLER_HH_
index 77f8334a7635b9451b27e3e4ce863fe5eccb2bd4..11561c35a6555d34a75c69612bd13aef101ab631 100644 (file)
@@ -34,6 +34,16 @@ Service::Service(std::string sender, std::string instance,
 Service::~Service() {
 }
 
+void Service::OnCreate() {
+  LOG(DEBUG) << "OnCreate: " << GetInstance();
+  handler_.RegisterRequestReplyHandler(GetInstance(), this);
+}
+
+void Service::OnTerminate() {
+  LOG(DEBUG) << "OnTerminate: " << GetInstance();
+  handler_.UnregisterRequestReplyHandler(GetInstance());
+}
+
 std::vector<rpc::Action> Service::ListActions() {
   return handler_.OnListActions();
 }
@@ -58,23 +68,27 @@ int Service::Execute(rpc::Action action) {
 
 int Service::RegisterActionReplyCb(std::unique_ptr<ActionReplyCb> cb) {
   int id = cb->GetSeqId();
-  reply_cbs_.emplace(GetInstance(), std::move(cb));
+  reply_cbs_.emplace_back(std::move(cb));
   return id;
 }
 
 bool Service::UnregisterActionReplyCb(int id) {
   auto it = std::find_if(reply_cbs_.begin(), reply_cbs_.end(),
       [id](const auto& iterator) {
-        return iterator.second->GetSeqId() == id;
+        return iterator->GetSeqId() == id;
       });
   if (it != reply_cbs_.end()) {
     reply_cbs_.erase(it);
     return true;
   } else {
-    LOG(ERROR) << "Not found callback for unregistration for instance "
-        << GetInstance();
+    LOG(ERROR) << "Not found callback for unregistration for id: " << id;
     return false;
   }
 }
 
+void Service::SendRequestReply(const std::string& reply) {
+  for (const auto& cb : reply_cbs_)
+    cb->Invoke(reply);
+}
+
 }  // namespace action
index ba39e1ef7ee586d5d8674e60f3f1550dfe2839ef..85efc65628a65bbec204a3e354cb827d8c4758cf 100644 (file)
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "action/request_handler.hh"
+#include "action/request_reply_handler.hh"
 #include "action/tizen_action_service_stub.h"
 
 using ActionReplyCb =
@@ -31,7 +32,8 @@ namespace action {
 
 namespace rpc = rpc_port::tizen_action_service_stub;
 
-class Service : public rpc::stub::ActionService::ServiceBase {
+class Service : public rpc::stub::ActionService::ServiceBase,
+                public RequestReplyHandler {
  public:
   class Factory : public rpc::stub::ActionService::ServiceBase::Factory {
    public:
@@ -49,8 +51,8 @@ class Service : public rpc::stub::ActionService::ServiceBase {
   Service(std::string sender, std::string instance, IRequestHandler& handler);
   ~Service();
 
-  void OnCreate() override {}
-  void OnTerminate() override {}
+  void OnCreate() override;
+  void OnTerminate() override;
   std::vector<rpc::Action> ListActions() override;
   rpc::Action GetAction(std::string action_id) override;
   std::vector<rpc::VectorDbResult> GetActionId(std::string user_description,
@@ -58,10 +60,11 @@ class Service : public rpc::stub::ActionService::ServiceBase {
   int Execute(rpc::Action action) override;
   int RegisterActionReplyCb(std::unique_ptr<ActionReplyCb> cb) override;
   bool UnregisterActionReplyCb(int id) override;
+  void SendRequestReply(const std::string& reply) override;
 
  private:
   IRequestHandler& handler_;
-  std::map<std::string, std::unique_ptr<ActionReplyCb>> reply_cbs_;
+  std::vector<std::unique_ptr<ActionReplyCb>> reply_cbs_;
 };
 
 }  // namespace action
index 08878d98e1fc871caffdba234c75ee2f4265a05a..b1e4eea19fadc7c66d7608f72ae7dc70d715f97b 100644 (file)
@@ -30,11 +30,15 @@ class AbstractActionExecutor {
   explicit AbstractActionExecutor(std::string id) : id_(std::move(id)) {}
   virtual ~AbstractActionExecutor() = default;
   virtual int Execute(const ActionModel& model) = 0;
-  virtual std::string GetId() { return id_; }
-  virtual void SetResultHandler(IResultHandler* handler) = 0;
+  std::string GetId() { return id_; }
+  void SetResultHandler(IResultHandler* handler) { handler_ = handler; }
+  void NotifyResult(const std::string& result) {
+    handler_->OnResult(id_, result);
+  }
 
  private:
   std::string id_;
+  IResultHandler* handler_;
 };
 
 }  // namespace common