From c6e45cd6ad826f5ed174435c3edc9c25295749cd Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Thu, 17 Jul 2014 14:29:53 +0200 Subject: [PATCH] Add loading database in Cynara::init Change-Id: Ie0d0774e4bc539ee4a33d87fb57afe33a5045952 --- packaging/cynara.spec | 3 ++ src/common/exceptions/FileNotFoundException.h | 55 ++++++++++++++++++++++++++ src/service/CMakeLists.txt | 3 ++ src/service/main/Cynara.cpp | 18 ++++++++- src/service/main/Cynara.h | 2 + src/service/main/main.cpp | 9 ----- src/service/storage/InMemoryStorageBackend.cpp | 55 +++++++++++++++++++++++--- src/service/storage/InMemoryStorageBackend.h | 30 +++++++++----- src/service/storage/Storage.cpp | 4 ++ src/service/storage/Storage.h | 3 ++ src/service/storage/StorageBackend.h | 2 + 11 files changed, 160 insertions(+), 24 deletions(-) create mode 100644 src/common/exceptions/FileNotFoundException.h diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 4b68a35..aeca477 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -17,6 +17,8 @@ BuildRequires: pkgconfig(libsystemd-journal) %global user_name %{name} %global group_name %{name} +%global db_path %{_localstatedir}/%{name}/db/ + %global build_type %{?build_type:%build_type}%{!?build_type:RELEASE} %if %{?build_type} == "DEBUG" @@ -84,6 +86,7 @@ export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %endif +export CXXFLAGS="$CXXFLAGS -DCYNARA_DB_PATH=\\\"%{db_path}\\\"" export LDFLAGS+="-Wl,--rpath=%{_libdir}" %cmake . -DVERSION=%{version} \ diff --git a/src/common/exceptions/FileNotFoundException.h b/src/common/exceptions/FileNotFoundException.h new file mode 100644 index 0000000..e353c19 --- /dev/null +++ b/src/common/exceptions/FileNotFoundException.h @@ -0,0 +1,55 @@ +/* + * 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 FileNotFoundException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file defines exception thrown when database file is not found + */ + +#ifndef SRC_COMMON_EXCEPTIONS_FILENOTFOUNDEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_FILENOTFOUNDEXCEPTION_H_ + +#include + +#include + +namespace Cynara { + +class FileNotFoundException : public DatabaseException { +public: + FileNotFoundException(const std::string &filename) : m_filename(filename) {}; + virtual ~FileNotFoundException() = default; + + const std::string message(void) const { + if (m_message.empty()) { + m_message = "File " + filename() + " not found or corrupted badly"; + } + return m_message; + } + + const std::string &filename(void) const { + return m_filename; + } + +private: + mutable std::string m_message; + std::string m_filename; +}; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_EXCEPTIONS_FILENOTFOUNDEXCEPTION_H_ */ diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index 915cc00..9f11ab8 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -24,8 +24,11 @@ SET(CYNARA_SOURCES ${CYNARA_SERVICE_PATH}/main/main.cpp ${CYNARA_SERVICE_PATH}/sockets/Descriptor.cpp ${CYNARA_SERVICE_PATH}/sockets/SocketManager.cpp + ${CYNARA_SERVICE_PATH}/storage/BucketDeserializer.cpp ${CYNARA_SERVICE_PATH}/storage/InMemoryStorageBackend.cpp ${CYNARA_SERVICE_PATH}/storage/Storage.cpp + ${CYNARA_SERVICE_PATH}/storage/StorageDeserializer.cpp + ${CYNARA_SERVICE_PATH}/storage/StorageSerializer.cpp ) SET_SOURCE_FILES_PROPERTIES( diff --git a/src/service/main/Cynara.cpp b/src/service/main/Cynara.cpp index c99bbe4..20bb0ab 100644 --- a/src/service/main/Cynara.cpp +++ b/src/service/main/Cynara.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -43,16 +44,31 @@ Cynara::~Cynara() { finalize(); } +const std::string Cynara::storageDir(void) const { + std::string dir("/var/lib/cynara/db/"); + +#ifdef CYNARA_DB_PATH + dir = CYNARA_DB_PATH; +#else + LOGW("Cynara compiled without CYNARA_DB_PATH flag. Using default database directory."); +#endif + + LOGI("Cynara database path = <%s>", dir.c_str()); + return dir; +} + void Cynara::init(void) { m_logic = std::make_shared(); m_socketManager = std::make_shared(); - m_storageBackend = std::make_shared(); + m_storageBackend = std::make_shared(storageDir()); m_storage = std::make_shared(*m_storageBackend); m_logic->bindStorage(m_storage); m_logic->bindSocketManager(m_socketManager); m_socketManager->bindLogic(m_logic); + + m_storage->load(); } void Cynara::run(void) { diff --git a/src/service/main/Cynara.h b/src/service/main/Cynara.h index 207e1b0..2e962c5 100644 --- a/src/service/main/Cynara.h +++ b/src/service/main/Cynara.h @@ -34,6 +34,8 @@ private: StoragePtr m_storage; StorageBackendPtr m_storageBackend; + const std::string storageDir(void) const; + public: Cynara(); ~Cynara(); diff --git a/src/service/main/main.cpp b/src/service/main/main.cpp index 766a422..ce7b07b 100644 --- a/src/service/main/main.cpp +++ b/src/service/main/main.cpp @@ -23,17 +23,8 @@ * @brief Main Cynara daemon file */ -//#include #include -//#include -//#include -//#include #include -//#include -//#include -//#include -//#include -//#include #include #include diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index b213111..1b7ae44 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -20,16 +20,40 @@ * @brief Implementation of InMemoryStorageBackend */ +#include +#include + +#include +#include +#include +#include +#include + #include "InMemoryStorageBackend.h" namespace Cynara { -InMemoryStorageBackend::InMemoryStorageBackend() { - // Make sure, there's always default bucket - this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() }); -} +void InMemoryStorageBackend::load(void) { + std::string indexFilename = m_dbPath + "buckets"; + + try { + std::ifstream indexStream; + openFileStream(indexStream, indexFilename); -InMemoryStorageBackend::~InMemoryStorageBackend() {} + StorageDeserializer storageDeserializer(indexStream, + std::bind(&InMemoryStorageBackend::bucketStreamOpener, this, std::placeholders::_1)); + + storageDeserializer.initBuckets(buckets()); + storageDeserializer.loadBuckets(buckets()); + } catch (const FileNotFoundException &) { + LOGE("Reading cynara database failed."); + } + + if(!hasBucket(defaultPolicyBucketId)) { + LOGN("Creating defaultBucket."); + this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() }); + } +} PolicyBucket InMemoryStorageBackend::searchDefaultBucket(const PolicyKey &key) { return searchBucket(defaultPolicyBucketId, key); @@ -118,4 +142,25 @@ void InMemoryStorageBackend::deleteLinking(const PolicyBucketId &bucketId) { } } +void InMemoryStorageBackend::openFileStream(std::ifstream &stream, const std::string &filename) { + // TODO: Consider adding exceptions to streams and handling them: + // stream.exceptions(std::ifstream::failbit | std::ifstream::badbit); + stream.open(filename); + + if (!stream.is_open()) + throw FileNotFoundException(filename); +} + +std::shared_ptr InMemoryStorageBackend::bucketStreamOpener( + const PolicyBucketId &bucketId) { + std::string bucketFilename = m_dbPath + "_" + bucketId; + std::ifstream bucketStream; + try { + openFileStream(bucketStream, bucketFilename); + return std::make_shared(bucketStream); + } catch (const FileNotFoundException &) { + return nullptr; + } +} + } /* namespace Cynara */ diff --git a/src/service/storage/InMemoryStorageBackend.h b/src/service/storage/InMemoryStorageBackend.h index 409a84c..1791b00 100644 --- a/src/service/storage/InMemoryStorageBackend.h +++ b/src/service/storage/InMemoryStorageBackend.h @@ -23,24 +23,31 @@ #ifndef INMEMORYSTORAGEBACKEND_H_ #define INMEMORYSTORAGEBACKEND_H_ -#include "StorageBackend.h" -#include -#include -#include - -#include #include +#include #include #include +#include + +#include +#include +#include +#include + +#include "StorageBackend.h" namespace Cynara { -class InMemoryStorageBackend: public StorageBackend { +class InMemoryStorageBackend : public StorageBackend { public: typedef std::unordered_map Buckets; - InMemoryStorageBackend(); - virtual ~InMemoryStorageBackend(); + InMemoryStorageBackend(const std::string &path) : m_dbPath(path) { + } + + virtual ~InMemoryStorageBackend() = default; + + virtual void load(void); virtual PolicyBucket searchDefaultBucket(const PolicyKey &key); virtual PolicyBucket searchBucket(const PolicyBucketId &bucketId, const PolicyKey &key); @@ -52,7 +59,12 @@ public: virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key); virtual void deleteLinking(const PolicyBucketId &bucketId); +protected: + void openFileStream(std::ifstream &stream, const std::string &filename); + std::shared_ptr bucketStreamOpener(const PolicyBucketId &bucketId); + private: + std::string m_dbPath; Buckets m_buckets; protected: diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 60de8ff..319dbda 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -121,4 +121,8 @@ void Storage::deletePolicies(const std::map #include +#include #include #include @@ -52,6 +53,8 @@ public: void addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy); void deleteBucket(const PolicyBucketId &bucketId); + void load(void); + protected: PolicyResult minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key); diff --git a/src/service/storage/StorageBackend.h b/src/service/storage/StorageBackend.h index 6689bae..97e0fd7 100644 --- a/src/service/storage/StorageBackend.h +++ b/src/service/storage/StorageBackend.h @@ -50,6 +50,8 @@ public: virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) = 0; virtual void deleteLinking(const PolicyBucketId &bucket) = 0; + + virtual void load(void) = 0; }; } /* namespace Cynara */ -- 2.7.4