Implement detection of online/offline mode in admin 39/29339/17
authorAleksander Zdyb <a.zdyb@samsung.com>
Tue, 23 Dec 2014 13:21:47 +0000 (14:21 +0100)
committerAleksander Zdyb <a.zdyb@samsung.com>
Tue, 23 Dec 2014 14:57:31 +0000 (15:57 +0100)
Change-Id: I93a2af08266d7606491abf4f89bf16663c7d0e15

src/admin/CMakeLists.txt
src/admin/api/admin-api.cpp
src/admin/logic/Logic.cpp [new file with mode: 0644]
src/admin/logic/Logic.h [new file with mode: 0644]
src/admin/logic/OfflineLogic.cpp [new file with mode: 0644]
src/admin/logic/OfflineLogic.h [new file with mode: 0644]

index 321ca92..3cbff78 100644 (file)
@@ -23,10 +23,13 @@ SET(CYNARA_LIB_CYNARA_ADMIN_PATH ${CYNARA_PATH}/admin)
 
 SET(LIB_CYNARA_ADMIN_SOURCES
     ${CYNARA_LIB_CYNARA_ADMIN_PATH}/api/admin-api.cpp
+    ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/Logic.cpp
+    ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/OfflineLogic.cpp
     ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/OnlineLogic.cpp
     )
 
 INCLUDE_DIRECTORIES(
+    ${CYNARA_PATH}
     ${CYNARA_PATH}/include
     ${CYNARA_LIB_CYNARA_ADMIN_PATH}
     )
@@ -43,6 +46,7 @@ SET_TARGET_PROPERTIES(
 TARGET_LINK_LIBRARIES(${TARGET_LIB_CYNARA_ADMIN}
     ${CYNARA_DEP_LIBRARIES}
     ${TARGET_CYNARA_COMMON}
+    ${TARGET_LIB_CYNARA_STORAGE}
     )
 
 INSTALL(TARGETS ${TARGET_LIB_CYNARA_ADMIN} DESTINATION ${LIB_INSTALL_DIR})
index 1dfeb90..d3b6a36 100644 (file)
@@ -30,6 +30,7 @@
 #include <vector>
 
 #include <common.h>
+#include <exceptions/FileLockAcquiringException.h>
 #include <exceptions/TryCatch.h>
 #include <log/log.h>
 #include <types/Policy.h>
@@ -43,7 +44,7 @@
 #include <cynara-error.h>
 
 #include <api/ApiInterface.h>
-#include <logic/OnlineLogic.h>
+#include <logic/Logic.h>
 
 struct cynara_admin {
     Cynara::ApiInterface *impl;
@@ -61,7 +62,12 @@ int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) {
         return CYNARA_API_INVALID_PARAM;
 
     return Cynara::tryCatch([&]() {
-        *pp_cynara_admin = new cynara_admin(new Cynara::OnlineLogic);
+        try {
+            *pp_cynara_admin = new cynara_admin(new Cynara::Logic);
+        } catch (const Cynara::FileLockAcquiringException &ex) {
+            LOGE("%s", ex.what());
+            return CYNARA_API_OPERATION_FAILED;
+        }
 
         init_log();
 
diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp
new file mode 100644 (file)
index 0000000..57fc0b5
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  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/admin/logic/Logic.cpp
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       This file contains implementation of Logic class - main libcynara-admin class
+ */
+
+#include <common.h>
+#include <config/PathConfig.h>
+#include <log/log.h>
+
+#include "Logic.h"
+#include "OfflineLogic.h"
+#include "OnlineLogic.h"
+
+namespace Cynara {
+
+Logic::Logic() : m_onlineLogic(new OnlineLogic()), m_offlineLogic(new OfflineLogic()),
+                 m_lockable(PathConfig::StoragePath::lockFile) {}
+
+Logic::~Logic() {
+    delete m_onlineLogic;
+    delete m_offlineLogic;
+}
+
+int Logic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate,
+                       const ApiInterface::KeysByBucket &remove) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::setPolicies, _1,
+                           std::cref(insertOrUpdate), std::cref(remove)));
+}
+
+int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket,
+                                const PolicyResult &policyResult) {
+    using std::placeholders::_1;
+    auto f = std::bind(&ApiInterface::insertOrUpdateBucket, _1,
+                       std::cref(bucket), std::cref(policyResult));
+    return callApiFunction(f);
+}
+
+int Logic::removeBucket(const PolicyBucketId &bucket) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::removeBucket, _1, std::cref(bucket)));
+}
+
+int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key,
+                      PolicyResult &result) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::adminCheck, _1, std::cref(startBucket),
+                           recursive, std::cref(key), std::ref(result)));
+}
+
+int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
+                        std::vector<Policy> &policies) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::listPolicies, _1, std::cref(bucket),
+                           std::cref(filter), std::ref(policies)));
+}
+
+int Logic::erasePolicies(const PolicyBucketId &startBucket, bool recursive,
+                         const PolicyKey &filter) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::erasePolicies, _1, std::cref(startBucket),
+                           recursive, std::cref(filter)));
+}
+
+int Logic::callApiFunction(std::function<int(ApiInterface *api)> apiCall) {
+    FileLock lock(m_lockable);
+    if (lock.tryLock() == true) {
+        m_offlineLogic->acquireDatabase();
+        LOGI("Admin uses offline API");
+        return apiCall(m_offlineLogic);
+    } else {
+        LOGI("Admin uses online API");
+        return apiCall(m_onlineLogic);
+    }
+}
+
+} // namespace Cynara
diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h
new file mode 100644 (file)
index 0000000..9a24de7
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  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/admin/logic/Logic.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       This file contains definition of Logic class - main libcynara-admin class
+ */
+
+#ifndef SRC_ADMIN_LOGIC_LOGIC_H_
+#define SRC_ADMIN_LOGIC_LOGIC_H_
+
+#include <functional>
+
+#include <common/lock/FileLock.h>
+
+#include <api/ApiInterface.h>
+
+namespace Cynara {
+
+class OnlineLogic;
+class OfflineLogic;
+
+class Logic : public ApiInterface {
+
+public:
+    Logic();
+    virtual ~Logic();
+
+    virtual int setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate,
+                            const ApiInterface::KeysByBucket &remove);
+    virtual int insertOrUpdateBucket(const PolicyBucketId &bucket,
+                                     const PolicyResult &policyResult);
+    virtual int removeBucket(const PolicyBucketId &bucket);
+    virtual int adminCheck(const PolicyBucketId &startBucket, bool recursive,
+                           const PolicyKey &key, PolicyResult &result);
+    virtual int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
+                             std::vector<Policy> &policies);
+    virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
+                              const PolicyKey &filter);
+
+protected:
+    int callApiFunction(std::function<int(ApiInterface *api)> apiCall);
+
+private:
+    OnlineLogic *m_onlineLogic;
+    OfflineLogic *m_offlineLogic;
+    Lockable m_lockable;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_ADMIN_LOGIC_LOGIC_H_ */
diff --git a/src/admin/logic/OfflineLogic.cpp b/src/admin/logic/OfflineLogic.cpp
new file mode 100644 (file)
index 0000000..a52a0fe
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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/admin/logic/OfflineLogic.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       This file contains implementation of OfflineLogic class
+ */
+
+#include <common.h>
+#include <config/PathConfig.h>
+#include <exceptions/BucketNotExistsException.h>
+#include <exceptions/DatabaseBusyException.h>
+#include <exceptions/DatabaseException.h>
+#include <exceptions/DefaultBucketDeletionException.h>
+#include <exceptions/DefaultBucketSetNoneException.h>
+#include <exceptions/InvalidBucketIdException.h>
+
+#include <storage/InMemoryStorageBackend.h>
+#include <storage/Storage.h>
+
+#include <cynara-error.h>
+
+#include "OfflineLogic.h"
+
+namespace Cynara {
+
+OfflineLogic::OfflineLogic() {}
+
+void OfflineLogic::acquireDatabase(void) {
+    m_storageBackend.reset(new InMemoryStorageBackend(PathConfig::StoragePath::dbDir));
+    m_storage.reset(new Storage(*m_storageBackend));
+    m_storage->load();
+}
+
+int OfflineLogic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate,
+                              const ApiInterface::KeysByBucket &remove) {
+    try {
+        m_storage->insertPolicies(insertOrUpdate);
+        m_storage->deletePolicies(remove);
+        onPoliciesChanged();
+    } catch (const BucketNotExistsException &) {
+        return CYNARA_API_BUCKET_NOT_FOUND;
+    } catch (const DatabaseException &) {
+        return CYNARA_API_OPERATION_FAILED;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+int OfflineLogic::insertOrUpdateBucket(const PolicyBucketId &bucket,
+                                       const PolicyResult &policyResult) {
+    try {
+        m_storage->addOrUpdateBucket(bucket, policyResult);
+        onPoliciesChanged();
+    } catch (const DefaultBucketSetNoneException &) {
+        return CYNARA_API_OPERATION_NOT_ALLOWED;
+    } catch (const InvalidBucketIdException &ex) {
+        return CYNARA_API_OPERATION_NOT_ALLOWED;
+    } catch (const DatabaseException &) {
+        return CYNARA_API_OPERATION_FAILED;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+int OfflineLogic::removeBucket(const PolicyBucketId &bucket) {
+    try {
+        m_storage->deleteBucket(bucket);
+        onPoliciesChanged();
+    } catch (const BucketNotExistsException &) {
+        return CYNARA_API_BUCKET_NOT_FOUND;
+    } catch (const DefaultBucketDeletionException &) {
+        return CYNARA_API_OPERATION_NOT_ALLOWED;
+    } catch (const DatabaseException &) {
+        return CYNARA_API_OPERATION_FAILED;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+int OfflineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive,
+                             const PolicyKey &key, PolicyResult &result) {
+    try {
+        result = m_storage->checkPolicy(key, startBucket, recursive);
+    } catch (const BucketNotExistsException &ex) {
+        return CYNARA_API_BUCKET_NOT_FOUND;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+int OfflineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
+                               std::vector<Policy> &policies) {
+    try {
+        policies = m_storage->listPolicies(bucket, filter);
+    } catch (const BucketNotExistsException &ex) {
+        return CYNARA_API_BUCKET_NOT_FOUND;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+int OfflineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive,
+                                const PolicyKey &filter) {
+    try {
+        m_storage->erasePolicies(startBucket, recursive, filter);
+        onPoliciesChanged();
+    } catch (const BucketNotExistsException &) {
+        return CYNARA_API_BUCKET_NOT_FOUND;
+    }
+
+    return CYNARA_API_SUCCESS;
+}
+
+void OfflineLogic::onPoliciesChanged(void) {
+    m_storage->save();
+}
+
+} /* namespace Cynara */
diff --git a/src/admin/logic/OfflineLogic.h b/src/admin/logic/OfflineLogic.h
new file mode 100644 (file)
index 0000000..ec180f2
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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/admin/logic/OfflineLogic.h
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       This file contains definition of OfflineLogic class
+ */
+
+#ifndef SRC_ADMIN_LOGIC_OFFLINELOGIC_H_
+#define SRC_ADMIN_LOGIC_OFFLINELOGIC_H_
+
+#include <memory>
+
+#include <lock/FileLock.h>
+
+#include <storage/Storage.h>
+#include <storage/StorageBackend.h>
+
+#include <api/ApiInterface.h>
+
+namespace Cynara {
+
+class OfflineLogic : public ApiInterface {
+public:
+    OfflineLogic();
+
+    void acquireDatabase(void);
+
+    int setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate,
+                    const ApiInterface::KeysByBucket &remove);
+    int insertOrUpdateBucket(const PolicyBucketId &bucket,
+                             const PolicyResult &policyResult);
+    int removeBucket(const PolicyBucketId &bucket);
+    int adminCheck(const PolicyBucketId &startBucket, bool recursive,
+                   const PolicyKey &key, PolicyResult &result);
+    int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
+                     std::vector<Policy> &policies);
+    int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
+                      const PolicyKey &filter);
+
+protected:
+    void onPoliciesChanged(void);
+
+private:
+    typedef std::unique_ptr<Storage> StorageUniquePtr;
+    typedef std::unique_ptr<StorageBackend> StorageBackendUniquePtr;
+
+    StorageUniquePtr m_storage;
+    StorageBackendUniquePtr m_storageBackend;
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_ADMIN_LOGIC_OFFLINELOGIC_H_ */