Add agent manager 99/29799/10
authorAdam Malinowski <a.malinowsk2@partner.samsung.com>
Fri, 24 Oct 2014 14:05:58 +0000 (16:05 +0200)
committerAdam Malinowski <a.malinowsk2@partner.samsung.com>
Sat, 15 Nov 2014 04:30:03 +0000 (05:30 +0100)
This commit introduces AgentManager class which will help plugins
in communication with agents. Also registering and unregistering agents
will be handled by this class.

Change-Id: Id3f7e5785223c3b0316f97bc8107805572a0fd10

src/service/CMakeLists.txt
src/service/agent/AgentManager.cpp [new file with mode: 0644]
src/service/agent/AgentManager.h [new file with mode: 0644]
src/service/logic/Logic.cpp
src/service/logic/Logic.h
src/service/main/Cynara.cpp
src/service/main/Cynara.h
src/service/main/pointers.h

index d6fd025..675a866 100644 (file)
@@ -19,6 +19,7 @@
 SET(CYNARA_SERVICE_PATH ${CYNARA_PATH}/service)
 
 SET(CYNARA_SOURCES
+    ${CYNARA_SERVICE_PATH}/agent/AgentManager.cpp
     ${CYNARA_SERVICE_PATH}/agent/AgentTalker.cpp
     ${CYNARA_SERVICE_PATH}/logic/Logic.cpp
     ${CYNARA_SERVICE_PATH}/main/Cynara.cpp
diff --git a/src/service/agent/AgentManager.cpp b/src/service/agent/AgentManager.cpp
new file mode 100644 (file)
index 0000000..ee91e64
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+/**
+ * @file        src/service/agent/AgentManager.cpp
+ * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version     1.0
+ * @brief       Definition of AgentManager class
+ */
+
+#include <cstdint>
+
+#include <attributes/attributes.h>
+#include <exceptions/UnexpectedErrorException.h>
+#include <log/log.h>
+
+#include "AgentManager.h"
+
+namespace Cynara {
+
+AgentRegisterResponse::Code AgentManager::registerAgent(const AgentType &agentType,
+                                                        const LinkId &linkId) {
+    if (m_agents.find(agentType) != m_agents.end()) {
+        return AgentRegisterResponse::REJECTED;
+    }
+
+    if (m_agents.insert(std::make_pair(agentType, linkId)).second) {
+        LOGI("Registered agent: <%s>", agentType.c_str());
+        return AgentRegisterResponse::DONE;
+    }
+
+    LOGE("Error in registering agent: <%s>", agentType.c_str());
+    return AgentRegisterResponse::ERROR;
+}
+
+bool AgentManager::getAgentType(const LinkId &linkId, AgentType &agentType) const {
+    for (const auto &x : m_agents) {
+        if (x.second == linkId) {
+           agentType = x.first;
+           return true;
+        }
+    }
+    return false;
+}
+
+void AgentManager::unregisterAgent(const LinkId &linkId) {
+    AgentType agentType;
+    if (!getAgentType(linkId, agentType)) {
+        LOGD("Trying to unregister not registered agent");
+        return;
+    }
+    m_agents.erase(agentType);
+    m_talkers.erase(linkId);
+    LOGI("Unregistered agent: <%s>", agentType.c_str());
+}
+
+AgentTalkerPtr AgentManager::createTalker(const AgentType &agentType) {
+    try {
+        ProtocolFrameSequenceNumber checkId = generateSequenceNumber(agentType);
+        const LinkId &linkId = m_agents.at(agentType);
+
+        AgentTalkerPtr talker = std::make_shared<AgentTalker>(agentType, linkId, checkId);
+        if (m_talkers[linkId].insert(std::make_pair(checkId, talker)).second) {
+            LOGD("Created talker for: <%s>:[%" PRIu16 "]", agentType.c_str(), checkId);
+            return talker;
+        }
+    } catch (const std::out_of_range &) {
+        LOGE("Proper agent not found: <%s>", agentType.c_str());
+    }
+
+    return AgentTalkerPtr();
+}
+
+ProtocolFrameSequenceNumber AgentManager::generateSequenceNumber(const AgentType &agentType UNUSED)
+{
+    // TODO: implement smart sequence number generation, maybe unique per agent
+    return m_sequenceNumber++;
+}
+
+AgentTalkerPtr AgentManager::getTalker(const LinkId &linkId, ProtocolFrameSequenceNumber requestId)
+                             const {
+    const auto talkerMap = m_talkers.find(linkId);
+    if (talkerMap == m_talkers.end()) {
+        return AgentTalkerPtr();
+    }
+
+    const auto talker = talkerMap->second.find(requestId);
+    return talker != talkerMap->second.end() ? talker->second : AgentTalkerPtr();
+}
+
+void AgentManager::removeTalker(const AgentTalkerPtr &agentTalker) {
+    m_talkers[agentTalker->linkId()].erase(agentTalker->checkId());
+}
+
+void AgentManager::cleanupAgent(const LinkId &linkId, TalkerCleanupFunction cleanupFunction) {
+    auto talkerMap = m_talkers.find(linkId);
+    if (talkerMap == m_talkers.end())
+        return;
+
+    if (cleanupFunction) {
+        for (auto p : talkerMap->second) {
+            cleanupFunction(p.second);
+        }
+    }
+    unregisterAgent(linkId);
+}
+
+} // namespace Cynara
diff --git a/src/service/agent/AgentManager.h b/src/service/agent/AgentManager.h
new file mode 100644 (file)
index 0000000..38dca72
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+/**
+ * @file        src/service/agent/AgentManager.h
+ * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version     1.0
+ * @brief       Declaration of AgentManager class
+ */
+
+#ifndef SRC_SERVICE_AGENT_AGENTMANAGER_H_
+#define SRC_SERVICE_AGENT_AGENTMANAGER_H_
+
+#include <functional>
+#include <map>
+
+#include <containers/BinaryQueue.h>
+#include <response/AgentRegisterResponse.h>
+#include <types/Agent.h>
+#include <types/Link.h>
+#include <types/ProtocolFields.h>
+
+#include <agent/AgentTalker.h>
+
+namespace Cynara {
+
+class AgentManager {
+public:
+    typedef std::map<ProtocolFrameSequenceNumber, AgentTalkerPtr> Talkers;
+    typedef std::function<void(const AgentTalkerPtr &agentTalkerPtr)> TalkerCleanupFunction;
+
+    AgentManager() : m_sequenceNumber(0) {}
+    ~AgentManager() {}
+
+    typedef enum {
+        RR_DONE,
+        RR_REJECTED,
+        RR_ERROR
+    } RegisterResult;
+
+    AgentRegisterResponse::Code registerAgent(const AgentType &agentType, const LinkId &linkId);
+
+    AgentTalkerPtr createTalker(const AgentType &agentType);
+    void removeTalker(const AgentTalkerPtr &agentTalkerPtr);
+    AgentTalkerPtr getTalker(const LinkId &linkId, ProtocolFrameSequenceNumber requestId) const;
+    void cleanupAgent(const LinkId &linkId, TalkerCleanupFunction cleanupFunction);
+
+private:
+    std::map<AgentType, LinkId> m_agents;
+    std::map<LinkId, Talkers> m_talkers;
+    ProtocolFrameSequenceNumber m_sequenceNumber;
+
+    ProtocolFrameSequenceNumber generateSequenceNumber(const AgentType &agentType);
+    bool getAgentType(const LinkId &linkId, AgentType &agentType) const;
+    void unregisterAgent(const LinkId &linkId);
+};
+
+} // namespace Cynara
+
+#endif /* SRC_SERVICE_AGENT_AGENTMANAGER_H_ */
index 55f9f63..7227ef9 100644 (file)
@@ -48,6 +48,7 @@
 #include <response/CodeResponse.h>
 
 #include <main/Cynara.h>
+#include <agent/AgentManager.h>
 #include <sockets/SocketManager.h>
 #include <storage/Storage.h>
 
@@ -82,9 +83,9 @@ void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) {
 }
 
 void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) {
-    // MOCKUP
+    auto result = m_agentManager->registerAgent(request->agentType(), context->responseQueue());
     context->returnResponse(context, std::make_shared<AgentRegisterResponse>(
-                            AgentRegisterResponse::DONE, request->sequenceNumber()));
+                            result, request->sequenceNumber()));
 }
 
 void Logic::execute(RequestContextPtr context, CancelRequestPtr request) {
index 18d8abb..fdf338e 100644 (file)
@@ -38,6 +38,10 @@ public:
     Logic();
     virtual ~Logic();
 
+    void bindAgentManager(const AgentManagerPtr &agentManager) {
+        m_agentManager = agentManager;
+    }
+
     void bindPluginManager(PluginManagerPtr pluginManager) {
         m_pluginManager = pluginManager;
     }
@@ -51,6 +55,7 @@ public:
     }
 
     void unbindAll(void) {
+        m_agentManager.reset();
         m_pluginManager.reset();
         m_storage.reset();
         m_socketManager.reset();
@@ -68,6 +73,7 @@ public:
     virtual void contextClosed(RequestContextPtr context);
 
 private:
+    AgentManagerPtr m_agentManager;
     PluginManagerPtr m_pluginManager;
     StoragePtr m_storage;
     SocketManagerPtr m_socketManager;
index c0f77ef..96443ce 100644 (file)
@@ -27,6 +27,7 @@
 #include <log/log.h>
 #include <exceptions/InitException.h>
 
+#include <agent/AgentManager.h>
 #include <logic/Logic.h>
 #include <plugin/PluginManager.h>
 #include <sockets/SocketManager.h>
@@ -47,12 +48,14 @@ Cynara::~Cynara() {
 }
 
 void Cynara::init(void) {
+    m_agentManager = std::make_shared<AgentManager>();
     m_logic = std::make_shared<Logic>();
     m_pluginManager = std::make_shared<PluginManager>(PathConfig::PluginPath::serviceDir);
     m_socketManager = std::make_shared<SocketManager>();
     m_storageBackend = std::make_shared<InMemoryStorageBackend>(PathConfig::StoragePath::dbDir);
     m_storage = std::make_shared<Storage>(*m_storageBackend);
 
+    m_logic->bindAgentManager(m_agentManager);
     m_logic->bindPluginManager(m_pluginManager);
     m_logic->bindStorage(m_storage);
     m_logic->bindSocketManager(m_socketManager);
@@ -79,6 +82,7 @@ void Cynara::finalize(void) {
         m_socketManager->unbindAll();
     }
 
+    m_agentManager.reset();
     m_logic.reset();
     m_pluginManager.reset();
     m_socketManager.reset();
index 2eb94dc..89bdd76 100644 (file)
@@ -37,6 +37,7 @@ public:
     void finalize(void);
 
 private:
+    AgentManagerPtr m_agentManager;
     LogicPtr m_logic;
     PluginManagerPtr m_pluginManager;
     SocketManagerPtr m_socketManager;
index e31eeb8..f32c4ab 100644 (file)
@@ -27,6 +27,9 @@
 
 namespace Cynara {
 
+class AgentManager;
+typedef std::shared_ptr<AgentManager> AgentManagerPtr;
+
 class Logic;
 typedef std::shared_ptr<Logic> LogicPtr;