Prepare Cache for async API 13/26513/4
authorZofia Abramowska <z.abramowska@samsung.com>
Mon, 25 Aug 2014 14:52:33 +0000 (16:52 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Thu, 28 Aug 2014 15:24:41 +0000 (08:24 -0700)
Change-Id: I4f2eba2db4a0f35efaa6fa00a924e582211a1e45

src/client/cache/CacheInterface.h
src/client/cache/CapacityCache.cpp
src/client/cache/CapacityCache.h
src/client/logic/Logic.cpp
src/client/logic/Logic.h

index 0279fdb..ec76a2e 100644 (file)
@@ -61,8 +61,11 @@ public:
 
 class PluginCache {
 public:
-    PluginCache(ResultGetterInterfacePtr getter) : m_getter(getter) {}
+    PluginCache() {}
     virtual int get(const std::string &session, const PolicyKey &key) = 0;
+    virtual int update(const std::string &session,
+                       const PolicyKey &key,
+                       const PolicyResult &result) = 0;
 
     void registerPlugin(const PolicyType policyType, InterpreterInterfacePtr plugin) {
         m_plugins[policyType] = plugin;
@@ -76,7 +79,6 @@ public:
 
 protected:
     std::map<PolicyType, InterpreterInterfacePtr> m_plugins;
-    ResultGetterInterfacePtr m_getter;
 };
 
 } // namespace Cynara
index a0025b2..412d231 100644 (file)
@@ -33,9 +33,9 @@ int CapacityCache::get(const std::string &session, const PolicyKey &key) {
     //This can be very time heavy. This part is welcomed to be optimized.
     if (session != m_session) {
         LOGD("Session changed from %s to %s.", m_session.c_str(), session.c_str());
-        m_keyValue.clear();
-        m_keyUsage.clear();
+        clear();
         m_session = session;
+        return CYNARA_API_CACHE_MISS;
     }
     auto resultIt = m_keyValue.find(keyToString(key));
     //Do we have entry in cache?
@@ -44,7 +44,7 @@ int CapacityCache::get(const std::string &session, const PolicyKey &key) {
                 key.client().toString().c_str(),
                 key.user().toString().c_str(),
                 key.privilege().toString().c_str());
-        return update(key);
+        return CYNARA_API_CACHE_MISS;
     } else {
         LOGD("Entry available for client=%s user=%s privilege=%s",
                 key.client().toString().c_str(),
@@ -64,14 +64,13 @@ int CapacityCache::get(const std::string &session, const PolicyKey &key) {
             LOGD("Entry usable.");
             m_keyUsage.splice(m_keyUsage.begin(), m_keyUsage, resultIt->second.second);
             return plugin->toResult(resultIt->second.first);
-        } else {
-            //remove from list and map and update
-            LOGD("Entry not usable.");
-            auto usage_it = resultIt->second.second;
-            m_keyUsage.erase(usage_it);
-            m_keyValue.erase(resultIt);
-            return update(key);
         }
+        //Remove unusable entry
+        LOGD("Entry not usable");
+        auto usageIt = resultIt->second.second;
+        m_keyUsage.erase(usageIt);
+        m_keyValue.erase(resultIt);
+        return CYNARA_API_CACHE_MISS;
     }
 }
 
@@ -101,14 +100,16 @@ void CapacityCache::evict(void) {
     m_keyValue.erase(value_it);
 }
 
-int CapacityCache::update(const PolicyKey &key) {
-    int ret;
-    PolicyResult result;
-    if ((ret = m_getter->requestResult(key, result)) != CYNARA_API_SUCCESS) {
-        LOGE("Error fetching new entry.");
-        return ret;
+int CapacityCache::update(const std::string &session,
+                          const PolicyKey &key,
+                          const PolicyResult &result) {
+    //This can be very time heavy. This part is welcomed to be optimized.
+    if (session != m_session) {
+        LOGD("Session changed from %s to %s.", m_session.c_str(), session.c_str());
+        clear();
+        m_session = session;
     }
-    LOGD("Fetched new entry.");
+
     auto pluginIt = m_plugins.find(result.policyType());
 
     //No registered plugin for returned type of policy
index 12101db..921a16b 100644 (file)
@@ -34,12 +34,13 @@ class CapacityCache : public PluginCache {
 public:
     static const std::size_t CACHE_DEFAULT_CAPACITY = 10000;
 
-    CapacityCache(ResultGetterInterfacePtr getter,
-                   std::size_t capacity = CACHE_DEFAULT_CAPACITY) :
-        PluginCache(getter),
+    CapacityCache(std::size_t capacity = CACHE_DEFAULT_CAPACITY) :
         m_capacity(capacity) {}
 
     int get(const std::string &session, const PolicyKey &key);
+    int update(const std::string& session,
+               const PolicyKey &key,
+               const PolicyResult &result);
     void clear(void);
 
 private:
@@ -50,7 +51,7 @@ private:
 
     static std::string keyToString(const PolicyKey &key);
     void evict(void);
-    int update(const PolicyKey &key);
+
 
     std::size_t m_capacity;
     std::string m_session;
index dbdcf36..0c8ffc9 100644 (file)
@@ -39,7 +39,8 @@ const std::string clientSocketPath("/run/cynara/cynara.socket");
 
 Logic::Logic() {
     m_socket = std::make_shared<SocketClient>(clientSocketPath, std::make_shared<ProtocolClient>());
-    m_cache = std::make_shared<CapacityCache>(std::make_shared<PolicyGetter>(m_socket));
+    m_resultGetter = std::make_shared<PolicyGetter>(m_socket);
+    m_cache = std::make_shared<CapacityCache>();
     auto naiveInterpreter = std::make_shared<NaiveInterpreter>();
     m_cache->registerPlugin(PredefinedPolicyType::ALLOW, naiveInterpreter);
     m_cache->registerPlugin(PredefinedPolicyType::DENY, naiveInterpreter);
@@ -49,15 +50,26 @@ Logic::Logic() {
 int Logic::check(const std::string &client, const std::string &session, const std::string &user,
                  const std::string &privilege) noexcept
 {
-    PolicyKey key(client, user, privilege);
-
-    if (!m_socket->isConnected())
+    if (!m_socket->isConnected()){
         onDisconnected();
+    }
 
+    PolicyKey key(client, user, privilege);
     auto ret = m_cache->get(session, key);
-    if (ret == CYNARA_API_SERVICE_NOT_AVAILABLE)
-        onDisconnected();
-    return ret;
+    //Any other situation than cache miss
+    if (ret != CYNARA_API_CACHE_MISS) {
+        return ret;
+    }
+
+    //No value in Cache
+    PolicyResult result;
+    ret = m_resultGetter->requestResult(key, result);
+    if (ret != CYNARA_API_SUCCESS) {
+        LOGE("Error fetching new entry.");
+        return ret;
+    }
+
+    return m_cache->update(session, key, result);
 }
 
 void Logic::onDisconnected(void) {
index ec298da..3d2ee95 100644 (file)
@@ -34,8 +34,9 @@ namespace Cynara {
 
 class Logic : public ApiInterface {
 private:
-    PluginCachePtr m_cache;
     SocketClientPtr m_socket;
+    ResultGetterInterfacePtr m_resultGetter;
+    PluginCachePtr m_cache;
 
     void onDisconnected(void);