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