• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef KVSTORE_META_MANAGER_H
16 #define KVSTORE_META_MANAGER_H
17 
18 #include <mutex>
19 #include <nlohmann/json.hpp>
20 
21 #include "app_device_change_listener.h"
22 #include "kv_store_delegate.h"
23 #include "kv_store_delegate_manager.h"
24 #include "kv_store_task.h"
25 #include "system_ability.h"
26 #include "types.h"
27 
28 namespace OHOS {
29 namespace DistributedKv {
30 enum FLAG {
31     UPDATE,
32     DELETE,
33     CHECK_EXIST,
34     UPDATE_LOCAL,
35     DELETE_LOCAL,
36     CHECK_EXIST_LOCAL,
37 };
38 
39 enum class CHANGE_FLAG {
40     INSERT,
41     UPDATE,
42     DELETE
43 };
44 
45 struct Serializable {
46     using json = nlohmann::json;
47     template<typename T>
48     static T GetVal(const json &j, const std::string &name, json::value_t type, const T &def);
49     static json ToJson(const std::string &jsonStr);
50 };
51 
52 struct SecretKeyMetaData {
53     static constexpr const char *SKEY = "skey";
54     std::vector<uint8_t> timeValue {};
55     std::vector<uint8_t> secretKey {};
56     KvStoreType kvStoreType = KvStoreType::INVALID_TYPE;
SecretKeyMetaDataSecretKeyMetaData57     SecretKeyMetaData() {}
~SecretKeyMetaDataSecretKeyMetaData58     ~SecretKeyMetaData()
59     {
60         secretKey.assign(secretKey.size(), 0);
61     }
SecretKeyMetaDataSecretKeyMetaData62     explicit SecretKeyMetaData(const nlohmann::json &jObject)
63     {
64         Unmarshal(jObject);
65     }
66 
67     std::vector<uint8_t> Marshal() const;
68     void Unmarshal(const nlohmann::json &jObject);
69     operator std::vector<uint8_t>() const
70     {
71         return Marshal();
72     }
73 private:
74     static constexpr const char *TIME = "time";
75     static constexpr const char *KVSTORE_TYPE = "kvStoreType";
76 };
77 
78 struct KvStoreMetaData {
79     static constexpr const char *APP_ID = "appId";
80     static constexpr const char *BUNDLE_NAME = "bundleName";
81     using json = nlohmann::json;
82     std::string appId = "";
83     std::string appType = "";
84     std::string bundleName = "";
85     std::string dataDir = "";
86     std::string deviceAccountId = "";
87     std::string deviceId = "";
88     bool isAutoSync = false;
89     bool isBackup = false;
90     bool isEncrypt = false;
91     KvStoreType kvStoreType = KvStoreType::DEVICE_COLLABORATION;
92     std::string schema = "";
93     std::string storeId = "";
94     std::uint32_t tokenId = 0;
95     std::string userId = "";
96     std::int32_t uid = -1;
97     std::uint32_t version = 0;
98     int securityLevel = 0;
99     bool isDirty = false;
100     std::string Marshal() const;
101     void Unmarshal(const json &jObject);
102 
GetAppIdKvStoreMetaData103     static inline std::string GetAppId(const json &jObject)
104     {
105         return Serializable::GetVal<std::string>(jObject, APP_ID, json::value_t::string, "");
106     }
107 
GetStoreIdKvStoreMetaData108     static inline std::string GetStoreId(const json &jObject)
109     {
110         return Serializable::GetVal<std::string>(jObject, STORE_ID, json::value_t::string, "");
111     }
112 private:
113     static constexpr const char *KVSTORE_TYPE = "kvStoreType";
114     static constexpr const char *DEVICE_ID = "deviceId";
115     static constexpr const char *USER_ID = "userId";
116     static constexpr const char *STORE_ID = "storeId";
117     static constexpr const char *ENCRYPT = "isEncrypt";
118     static constexpr const char *BACKUP = "isBackup";
119     static constexpr const char *AUTO_SYNC = "isAutoSync";
120     static constexpr const char *SCHEMA = "schema";
121     static constexpr const char *DATA_DIR = "dataDir";
122     static constexpr const char *APP_TYPE = "appType";
123     static constexpr const char *DEVICE_ACCOUNT_ID = "deviceAccountID";
124     static constexpr const char *UID = "UID";
125     static constexpr const char *VERSION = "version";
126     static constexpr const char *SECURITY_LEVEL = "securityLevel";
127     static constexpr const char *DIRTY_KEY = "isDirty";
128     static constexpr const char *TOKEN_ID = "tokenId";
129 };
130 
131 struct MetaData {
132     std::int32_t kvStoreType;
133     KvStoreMetaData kvStoreMetaData;
134     SecretKeyMetaData secretKeyMetaData;
135 
GetKvStoreTypeMetaData136     static inline KvStoreType GetKvStoreType(const nlohmann::json &jObject)
137     {
138         return Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, nlohmann::json::value_t::number_unsigned,
139                                                  KvStoreType::INVALID_TYPE);
140     }
141 private:
142     static constexpr const char *KVSTORE_TYPE = "kvStoreType";
143 };
144 
145 class KvStoreMetaManager {
146 public:
147     static constexpr uint32_t META_STORE_VERSION = 0x03000001;
148     enum DatabaseType {
149         KVDB,
150         RDB,
151     };
152     using ChangeObserver = std::function<void(const std::vector<uint8_t> &, const std::vector<uint8_t> &, CHANGE_FLAG)>;
153 
154     class MetaDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceChangeListener {
155         void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info,
156                              const AppDistributedKv::DeviceChangeType &type) const override;
157 
158         AppDistributedKv::ChangeLevelType GetChangeLevelType() const override;
159     };
160 
161     ~KvStoreMetaManager();
162 
163     static KvStoreMetaManager &GetInstance();
164 
165     void InitMetaParameter();
166     void InitMetaListener();
167     void InitBroadcast();
168     void InitDeviceOnline();
169     void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer);
170 
171     static std::vector<uint8_t> GetMetaKey(
172         const std::string &deviceAccountId, const std::string &groupId, const std::string &bundleName,
173         const std::string &storeId, const std::string &key = "");
174 
175     bool GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData);
176 
177     bool GetFullMetaData(std::map<std::string, MetaData> &entries, enum DatabaseType type = KVDB);
178 
179 private:
180     using NbDelegate = std::shared_ptr<DistributedDB::KvStoreNbDelegate>;
181     NbDelegate GetMetaKvStore();
182 
183     NbDelegate CreateMetaKvStore();
184 
185     void ConfigMetaDataManager();
186 
187     KvStoreMetaManager();
188 
189     void InitMetaData();
190 
191     void SubscribeMetaKvStore();
192 
193     void SyncMeta();
194 
195     std::string GetBackupPath() const;
196 
197     bool GetKvStoreMetaByType(const std::string &name, const std::string &val, KvStoreMetaData &metaData);
198 
199     class KvStoreMetaObserver : public DistributedDB::KvStoreObserver {
200     public:
201         virtual ~KvStoreMetaObserver();
202 
203         // Database change callback
204         void OnChange(const DistributedDB::KvStoreChangedData &data) override;
205         std::map<std::string, ChangeObserver> handlerMap_;
206     private:
207         void HandleChanges(CHANGE_FLAG flag, const std::list<DistributedDB::Entry> &list);
208     };
209 
210     NbDelegate metaDelegate_;
211     std::string metaDBDirectory_;
212     const std::string label_;
213     DistributedDB::KvStoreDelegateManager delegateManager_;
214     static MetaDeviceChangeListenerImpl listener_;
215     KvStoreMetaObserver metaObserver_;
216     std::recursive_mutex mutex_;
217 };
218 }  // namespace DistributedKv
219 }  // namespace OHOS
220 #endif // KVSTORE_META_MANAGER_H
221