%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"
export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
%endif
+export CXXFLAGS="$CXXFLAGS -DCYNARA_DB_PATH=\\\"%{db_path}\\\""
export LDFLAGS+="-Wl,--rpath=%{_libdir}"
%cmake . -DVERSION=%{version} \
--- /dev/null
+/*
+ * 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 <a.zdyb@partner.samsung.com>
+ * @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 <string>
+
+#include <exceptions/DatabaseException.h>
+
+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_ */
${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(
#include <memory>
#include <stddef.h>
+#include <log/log.h>
#include <exceptions/InitException.h>
#include <logic/Logic.h>
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<Logic>();
m_socketManager = std::make_shared<SocketManager>();
- m_storageBackend = std::make_shared<InMemoryStorageBackend>();
+ m_storageBackend = std::make_shared<InMemoryStorageBackend>(storageDir());
m_storage = std::make_shared<Storage>(*m_storageBackend);
m_logic->bindStorage(m_storage);
m_logic->bindSocketManager(m_socketManager);
m_socketManager->bindLogic(m_logic);
+
+ m_storage->load();
}
void Cynara::run(void) {
StoragePtr m_storage;
StorageBackendPtr m_storageBackend;
+ const std::string storageDir(void) const;
+
public:
Cynara();
~Cynara();
* @brief Main Cynara daemon file
*/
-//#include <errno.h>
#include <exception>
-//#include <fcntl.h>
-//#include <signal.h>
-//#include <stdio.h>
#include <stdlib.h>
-//#include <string.h>
-//#include <sys/prctl.h>
-//#include <sys/stat.h>
-//#include <sys/types.h>
-//#include <unistd.h>
#include <systemd/sd-journal.h>
#include <systemd/sd-daemon.h>
* @brief Implementation of InMemoryStorageBackend
*/
+#include <fstream>
+#include <functional>
+
+#include <log/log.h>
+#include <exceptions/FileNotFoundException.h>
+#include <storage/BucketDeserializer.h>
+#include <storage/StorageDeserializer.h>
+#include <types/PolicyBucketId.h>
+
#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);
}
}
+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<BucketDeserializer> InMemoryStorageBackend::bucketStreamOpener(
+ const PolicyBucketId &bucketId) {
+ std::string bucketFilename = m_dbPath + "_" + bucketId;
+ std::ifstream bucketStream;
+ try {
+ openFileStream(bucketStream, bucketFilename);
+ return std::make_shared<BucketDeserializer>(bucketStream);
+ } catch (const FileNotFoundException &) {
+ return nullptr;
+ }
+}
+
} /* namespace Cynara */
#ifndef INMEMORYSTORAGEBACKEND_H_
#define INMEMORYSTORAGEBACKEND_H_
-#include "StorageBackend.h"
-#include <exceptions/NotImplementedException.h>
-#include <exceptions/BucketNotExistsException.h>
-#include <types/Policy.h>
-
-#include <unordered_map>
#include <algorithm>
+#include <fstream>
#include <functional>
#include <iostream>
+#include <unordered_map>
+
+#include <exceptions/BucketNotExistsException.h>
+#include <exceptions/NotImplementedException.h>
+#include <storage/BucketDeserializer.h>
+#include <types/Policy.h>
+
+#include "StorageBackend.h"
namespace Cynara {
-class InMemoryStorageBackend: public StorageBackend {
+class InMemoryStorageBackend : public StorageBackend {
public:
typedef std::unordered_map<PolicyBucketId, PolicyBucket> 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);
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<BucketDeserializer> bucketStreamOpener(const PolicyBucketId &bucketId);
+
private:
+ std::string m_dbPath;
Buckets m_buckets;
protected:
}
}
+void Storage::load(void) {
+ m_backend.load();
+}
+
} // namespace Cynara
#include <map>
#include <memory>
+#include <string>
#include <tuple>
#include <vector>
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);
virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) = 0;
virtual void deleteLinking(const PolicyBucketId &bucket) = 0;
+
+ virtual void load(void) = 0;
};
} /* namespace Cynara */