2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file InMemoryStorageBackend.cpp
18 * @author Aleksander Zdyb <a.zdyb@partner.samsung.com>
20 * @brief Implementation of InMemoryStorageBackend
27 #include <exceptions/FileNotFoundException.h>
28 #include <storage/BucketDeserializer.h>
29 #include <storage/StorageDeserializer.h>
30 #include <types/PolicyBucketId.h>
32 #include "InMemoryStorageBackend.h"
36 void InMemoryStorageBackend::load(void) {
37 std::string indexFilename = m_dbPath + "buckets";
40 std::ifstream indexStream;
41 openFileStream(indexStream, indexFilename);
43 StorageDeserializer storageDeserializer(indexStream,
44 std::bind(&InMemoryStorageBackend::bucketStreamOpener, this, std::placeholders::_1));
46 storageDeserializer.initBuckets(buckets());
47 storageDeserializer.loadBuckets(buckets());
48 } catch (const FileNotFoundException &) {
49 LOGE("Reading cynara database failed.");
52 if(!hasBucket(defaultPolicyBucketId)) {
53 LOGN("Creating defaultBucket.");
54 this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() });
58 PolicyBucket InMemoryStorageBackend::searchDefaultBucket(const PolicyKey &key) {
59 return searchBucket(defaultPolicyBucketId, key);
62 PolicyBucket InMemoryStorageBackend::searchBucket(const PolicyBucketId &bucketId,
63 const PolicyKey &key) {
65 const auto &bucket = this->buckets().at(bucketId);
66 return bucket.filtered(key);
67 } catch (const std::out_of_range &) {
68 throw BucketNotExistsException(bucketId);
72 void InMemoryStorageBackend::insertPolicy(const PolicyBucketId &bucketId, PolicyPtr policy) {
74 auto &bucket = buckets().at(bucketId);
75 auto &policies = bucket.policyCollection();
76 policies.push_back(policy);
77 } catch (const std::out_of_range &) {
78 throw BucketNotExistsException(bucketId);
82 void InMemoryStorageBackend::createBucket(const PolicyBucketId &bucketId,
83 const PolicyResult &defaultPolicy) {
84 PolicyBucket newBucket;
85 newBucket.setDefaultPolicy(defaultPolicy);
86 buckets().insert({ bucketId, newBucket });
89 void InMemoryStorageBackend::updateBucket(const PolicyBucketId &bucketId,
90 const PolicyResult &defaultPolicy) {
92 auto &bucket = buckets().at(bucketId);
93 bucket.setDefaultPolicy(defaultPolicy);
94 } catch (const std::out_of_range &) {
95 throw BucketNotExistsException(bucketId);
99 void InMemoryStorageBackend::deleteBucket(const PolicyBucketId &bucketId) {
100 auto bucketErased = buckets().erase(bucketId);
101 if (bucketErased == 0) {
102 throw BucketNotExistsException(bucketId);
106 bool InMemoryStorageBackend::hasBucket(const PolicyBucketId &bucketId) {
107 return buckets().find(bucketId) != buckets().end();
110 void InMemoryStorageBackend::deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) {
112 // TODO: Move the erase code to PolicyCollection maybe?
113 auto &bucket = buckets().at(bucketId);
114 auto &policies = bucket.policyCollection();
115 policies.erase(remove_if(policies.begin(), policies.end(),
116 [key](PolicyPtr policy) -> bool {
117 return policy->key() == key;
119 } catch(const std::out_of_range &) {
120 throw BucketNotExistsException(bucketId);
124 void InMemoryStorageBackend::deleteLinking(const PolicyBucketId &bucketId) {
125 auto bucketIdMatches = [&bucketId] (PolicyPtr policy) -> bool {
126 auto policyResult = policy->result();
128 // Check bucket id only if policy is a bucket policy
129 // TODO: Maybe move the test to PolicyResult
130 if (policyResult.policyType() == PredefinedPolicyType::BUCKET) {
131 return policyResult.metadata() == bucketId;
136 for(auto &bucketIter : buckets()) {
137 // TODO: Move the erase code to PolicyCollection maybe?
138 auto &bucket = bucketIter.second;
139 auto &policies = bucket.policyCollection();
140 policies.erase(remove_if(policies.begin(), policies.end(), bucketIdMatches),
145 void InMemoryStorageBackend::openFileStream(std::ifstream &stream, const std::string &filename) {
146 // TODO: Consider adding exceptions to streams and handling them:
147 // stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
148 stream.open(filename);
150 if (!stream.is_open())
151 throw FileNotFoundException(filename);
154 std::shared_ptr<BucketDeserializer> InMemoryStorageBackend::bucketStreamOpener(
155 const PolicyBucketId &bucketId) {
156 std::string bucketFilename = m_dbPath + "_" + bucketId;
157 std::ifstream bucketStream;
159 openFileStream(bucketStream, bucketFilename);
160 return std::make_shared<BucketDeserializer>(bucketStream);
161 } catch (const FileNotFoundException &) {
166 } /* namespace Cynara */