const std::string InMemoryStorageBackend::m_bucketFilenamePrefix(
PathConfig::StoragePath::bucketFilenamePrefix);
+InMemoryStorageBackend::InMemoryStorageBackend(const std::string &path) : m_dbPath(path) {
+ m_integrity.reset(new Integrity(path));
+}
+
void InMemoryStorageBackend::load(void) {
- Integrity integrity(m_dbPath, m_indexFilename, m_backupFilenameSuffix, m_bucketFilenamePrefix);
- bool isBackupValid = integrity.backupGuardExists();
+ bool isBackupValid = m_integrity->backupGuardExists();
std::string bucketSuffix = "";
std::string indexFilename = m_dbPath + m_indexFilename;
this->buckets().insert({ defaultPolicyBucketId, PolicyBucket(defaultPolicyBucketId) });
}
- if (isBackupValid) {
- integrity.revalidatePrimaryDatabase(buckets());
- }
- //in case there were unnecessary files in db directory
- integrity.deleteNonIndexedFiles(std::bind(&InMemoryStorageBackend::hasBucket, this,
- std::placeholders::_1));
+ postLoadCleanup(isBackupValid);
}
void InMemoryStorageBackend::save(void) {
storageSerializer.dump(buckets(), std::bind(&InMemoryStorageBackend::bucketDumpStreamOpener,
this, std::placeholders::_1));
- Integrity integrity(m_dbPath, m_indexFilename, m_backupFilenameSuffix, m_bucketFilenamePrefix);
-
- integrity.syncDatabase(buckets(), true);
- integrity.createBackupGuard();
- integrity.revalidatePrimaryDatabase(buckets());
+ m_integrity->syncDatabase(buckets(), true);
+ m_integrity->createBackupGuard();
+ m_integrity->revalidatePrimaryDatabase(buckets());
//guard is removed during revalidation
}
return std::make_shared<StorageSerializer>(bucketStream);
}
+void InMemoryStorageBackend::postLoadCleanup(bool isBackupValid) {
+ if (isBackupValid) {
+ m_integrity->revalidatePrimaryDatabase(buckets());
+ }
+ //in case there were unnecessary files in db directory
+ m_integrity->deleteNonIndexedFiles(std::bind(&InMemoryStorageBackend::hasBucket, this,
+ std::placeholders::_1));
+}
+
} /* namespace Cynara */
#include <storage/BucketDeserializer.h>
#include <storage/Buckets.h>
+#include <storage/Integrity.h>
#include <storage/StorageBackend.h>
#include <storage/StorageSerializer.h>
class InMemoryStorageBackend : public StorageBackend {
public:
- InMemoryStorageBackend(const std::string &path) : m_dbPath(path) {
- }
+ InMemoryStorageBackend(const std::string &path);
virtual ~InMemoryStorageBackend() {};
virtual void load(void);
const std::string &filename);
std::shared_ptr<StorageSerializer> bucketDumpStreamOpener(const PolicyBucketId &bucketId);
+ virtual void postLoadCleanup(bool isBackupValid);
+
private:
std::string m_dbPath;
Buckets m_buckets;
+ IntegrityUniquePtr m_integrity;
static const std::string m_indexFilename;
static const std::string m_backupFilenameSuffix;
static const std::string m_bucketFilenamePrefix;
namespace Cynara {
-const std::string Integrity::m_guardFilename(PathConfig::StoragePath::guardFilename);
+namespace StorageConfig = PathConfig::StoragePath;
+
+const std::string Integrity::m_guardFilename(StorageConfig::guardFilename);
+const std::string Integrity::m_indexFilename(StorageConfig::indexFilename);
+const std::string Integrity::m_backupFilenameSuffix(StorageConfig::backupFilenameSuffix);
+const std::string Integrity::m_bucketFilenamePrefix(StorageConfig::bucketFilenamePrefix);
bool Integrity::backupGuardExists(void) const {
struct stat buffer;
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 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.
#define SRC_STORAGE_INTEGRITY_H_
#include <fcntl.h>
+#include <memory>
#include <string>
#include <storage/Buckets.h>
namespace Cynara {
+class Integrity;
+typedef std::unique_ptr<Integrity> IntegrityUniquePtr;
+
class Integrity
{
public:
typedef std::function<bool(const PolicyBucketId &)> BucketPresenceTester;
- Integrity(const std::string &path, const std::string &index, const std::string &backupSuffix,
- const std::string &bucketPrefix)
- : m_dbPath(path), m_indexFilename(index), m_backupFilenameSuffix(backupSuffix),
- m_bucketFilenamePrefix(bucketPrefix) {
- }
+ Integrity(const std::string &path) : m_dbPath(path) {}
virtual ~Integrity() {};
virtual bool backupGuardExists(void) const;
private:
const std::string m_dbPath;
- const std::string m_indexFilename;
- const std::string m_backupFilenameSuffix;
- const std::string m_bucketFilenamePrefix;
+ static const std::string m_indexFilename;
+ static const std::string m_backupFilenameSuffix;
+ static const std::string m_bucketFilenamePrefix;
static const std::string m_guardFilename;
};
public:
using Cynara::InMemoryStorageBackend::InMemoryStorageBackend;
MOCK_METHOD0(buckets, Cynara::Buckets&(void));
+ MOCK_METHOD1(postLoadCleanup, void(bool isBackupValid));
};
// Database dir is empty
TEST_F(InMemeoryStorageBackendFixture, load_no_db) {
using ::testing::ReturnRef;
+ using ::testing::Return;
auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/empty_db/";
FakeInMemoryStorageBackend backend(testDbPath);
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
backend.load();
ASSERT_DB_VIRGIN(m_buckets);
}
// Database dir contains index with default bucket, but no file for this bucket
TEST_F(InMemeoryStorageBackendFixture, load_no_default) {
using ::testing::ReturnRef;
+ using ::testing::Return;
auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db2/";
FakeInMemoryStorageBackend backend(testDbPath);
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
backend.load();
ASSERT_DB_VIRGIN(m_buckets);
}
// Database contains index with default bucket and an empty bucket file
TEST_F(InMemeoryStorageBackendFixture, load_default_only) {
using ::testing::ReturnRef;
+ using ::testing::Return;
auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db3/";
FakeInMemoryStorageBackend backend(testDbPath);
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
backend.load();
ASSERT_DB_VIRGIN(m_buckets);
}
// There are files for both buckets present
TEST_F(InMemeoryStorageBackendFixture, load_2_buckets) {
using ::testing::ReturnRef;
+ using ::testing::Return;
using ::testing::IsEmpty;
auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db4/";
FakeInMemoryStorageBackend backend(testDbPath);
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
backend.load();
std::vector<std::string> bucketIds = { "", "additional" };
// Database contains index with 2 buckets; 1st bucket is valid, but second is corrupted
TEST_F(InMemeoryStorageBackendFixture, second_bucket_corrupted) {
using ::testing::ReturnRef;
+ using ::testing::Return;
auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db5/";
FakeInMemoryStorageBackend backend(testDbPath);
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(false)).WillOnce(Return());
backend.load();
ASSERT_DB_VIRGIN(m_buckets);
}
*/
TEST_F(InMemeoryStorageBackendFixture, load_from_backup) {
using ::testing::ReturnRef;
+ using ::testing::Return;
using ::testing::IsEmpty;
using ::testing::InSequence;
// Calls are expected in a specific order
InSequence s;
EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets));
+ EXPECT_CALL(backend, postLoadCleanup(true)).WillOnce(Return());
backend.load();
}