!2412 修改概率性数据变更通知失败问题

Merge pull request !2412 from wellinleo/master
This commit is contained in:
oh_ci 2024-11-21 12:42:45 +00:00 committed by Gitee
commit 833c5322f7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
10 changed files with 49 additions and 311 deletions

View File

@ -362,12 +362,11 @@ void KvStoreDataService::StartService()
// subscribe account event listener to EventNotificationMgr
auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam &param) -> bool {
auto status = ResolveAutoLaunchParamByIdentifier(identifier, param);
features_.ForEachCopies([&identifier, &param](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
value->ResolveAutoLaunch(identifier, param);
return false;
});
return status;
return false;
};
KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch);
ZLOGI("Start distributedata Success, Publish ret: %{public}d", static_cast<int>(ret));
@ -395,180 +394,6 @@ void KvStoreDataService::OnStoreMetaChanged(
ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str());
}
bool KvStoreDataService::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier,
const StoreMetaData &storeMeta)
{
std::vector<std::string> accountIds { accountId, "ohosAnonymousUid", "default" };
for (auto &id : accountIds) {
auto convertedIds =
AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user);
const std::string &tempTripleIdentifier =
DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first,
storeMeta.storeId, false);
if (tempTripleIdentifier == identifier) {
ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s",
Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str());
return true;
}
}
return false;
}
bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(
const std::string &identifier, DistributedDB::AutoLaunchParam &param)
{
std::vector<StoreMetaData> entries;
std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) {
ZLOGE("get full meta failed");
return false;
}
auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId();
for (const auto &storeMeta : entries) {
if ((!param.userId.empty() && (param.userId != storeMeta.user)) || (localDeviceId != storeMeta.deviceId) ||
((StoreMetaData::STORE_RELATIONAL_BEGIN <= storeMeta.storeType) &&
(StoreMetaData::STORE_RELATIONAL_END >= storeMeta.storeType))) {
// judge local userid and local meta
continue;
}
bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta);
const std::string &itemDualIdentifier =
DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
if (isTripleIdentifierEqual && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) {
ResolveAutoLaunchCompatible(storeMeta, identifier, accountId);
}
if (identifier == itemDualIdentifier || isTripleIdentifierEqual) {
ZLOGI("identifier find");
DistributedDB::AutoLaunchOption option;
option.createIfNecessary = false;
option.isEncryptedDb = storeMeta.isEncrypt;
SecretKeyMeta secretKey;
if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
std::vector<uint8_t> decryptKey;
CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
option.passwd.SetValue(decryptKey.data(), decryptKey.size());
std::fill(decryptKey.begin(), decryptKey.end(), 0);
}
if (storeMeta.bundleName == Bootstrap::GetInstance().GetProcessLabel()) {
param.userId = storeMeta.user;
}
option.schema = storeMeta.schema;
option.createDirByStoreIdOnly = true;
option.dataDir = storeMeta.dataDir;
option.secOption = ConvertSecurity(storeMeta.securityLevel);
option.isAutoSync = storeMeta.isAutoSync;
option.syncDualTupleMode = true; // dual tuple flag
param.appId = storeMeta.appId;
param.storeId = storeMeta.storeId;
param.option = option;
return true;
}
}
ZLOGI("not find identifier");
return false;
}
DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLevel)
{
if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) {
return {DistributedDB::NOT_SET, DistributedDB::ECE};
}
switch (securityLevel) {
case SecurityLevel::S3:
return {DistributedDB::S3, DistributedDB::SECE};
case SecurityLevel::S4:
return {DistributedDB::S4, DistributedDB::ECE};
default:
return {securityLevel, DistributedDB::ECE};
}
}
void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier,
const std::string &accountId)
{
if (storeMeta.storeType > KvStoreType::SINGLE_VERSION) {
ZLOGW("no longer support multi or higher version store type");
return;
}
ZLOGI("AutoLaunch:peer device is old tuple, begin to open store, storeId: %{public}s",
Anonymous::Change(storeMeta.storeId).c_str());
// open store and SetEqualIdentifier, then close store after 60s
DistributedDB::KvStoreDelegateManager delegateManager(storeMeta.appId, storeMeta.user);
delegateManager.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(storeMeta) });
Options options = {
.createIfMissing = false,
.encrypt = storeMeta.isEncrypt,
.autoSync = storeMeta.isAutoSync,
.securityLevel = storeMeta.securityLevel,
.kvStoreType = static_cast<KvStoreType>(storeMeta.storeType),
};
DistributedDB::KvStoreNbDelegate::Option dbOptions;
SecretKeyMeta secretKey;
if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
std::vector<uint8_t> decryptKey;
CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
std::fill(secretKey.sKey.begin(), secretKey.sKey.end(), 0);
secretKey.sKey = std::move(decryptKey);
std::fill(decryptKey.begin(), decryptKey.end(), 0);
}
InitNbDbOption(options, secretKey.sKey, dbOptions);
DistributedDB::KvStoreNbDelegate *store = nullptr;
delegateManager.GetKvStore(storeMeta.storeId, dbOptions,
[&store, &storeMeta, &accountId](int status, DistributedDB::KvStoreNbDelegate *delegate) {
ZLOGI("temporary open db for equal identifier, ret:%{public}d", status);
if (delegate != nullptr) {
KvStoreTuple tuple = { accountId, storeMeta.appId, storeMeta.storeId };
UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple);
store = delegate;
}
});
ExecutorPool::Task delayTask([store]() {
ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied");
DistributedDB::KvStoreDelegateManager delegateManager("", "");
delegateManager.CloseKvStore(store);
});
constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds
executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask));
}
Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
DistributedDB::KvStoreNbDelegate::Option &dbOption)
{
DistributedDB::CipherPassword password;
auto status = password.SetValue(cipherKey.data(), cipherKey.size());
if (status != DistributedDB::CipherPassword::ErrorCode::OK) {
ZLOGE("Failed to set the passwd.");
return Status::DB_ERROR;
}
dbOption.syncDualTupleMode = true; // tuple of (appid+storeid)
dbOption.createIfNecessary = options.createIfMissing;
dbOption.isMemoryDb = (!options.persistent);
dbOption.isEncryptedDb = options.encrypt;
dbOption.isNeedCompressOnSync = options.isNeedCompress;
if (options.encrypt) {
dbOption.cipher = DistributedDB::CipherType::AES_256_GCM;
dbOption.passwd = password;
}
if (options.kvStoreType == KvStoreType::SINGLE_VERSION) {
dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN;
} else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) {
dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION;
} else {
ZLOGE("kvStoreType is invalid");
return Status::INVALID_ARGUMENT;
}
dbOption.schema = options.schema;
dbOption.createDirByStoreIdOnly = true;
dbOption.secOption = ConvertSecurity(options.securityLevel);
return Status::SUCCESS;
}
void KvStoreDataService::OnStop()
{
ZLOGI("begin.");

View File

@ -166,18 +166,8 @@ private:
Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId);
bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam &param);
void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier,
const std::string &accountId);
void LoadConfigs();
bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier,
const StoreMetaData &storeMeta);
static DistributedDB::SecurityOption ConvertSecurity(int securityLevel);
static Status InitNbDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
DistributedDB::KvStoreNbDelegate::Option &dbOption);
static constexpr int TEN_SEC = 10;
ConcurrentMap<uint32_t, std::map<int32_t, KvStoreClientDeathObserverImpl>> clients_;

View File

@ -87,57 +87,4 @@ bool UpgradeManager::InitLocalCapability()
ZLOGI("put capability meta data ret %{public}d", status);
return status;
}
void UpgradeManager::GetIdentifierParams(std::vector<std::string> &devices,
const std::vector<std::string> &uuids, int32_t authType)
{
for (const auto &devId : uuids) {
if (DmAdapter::GetInstance().IsOHOSType(devId)) {
continue;
}
if (DmAdapter::GetInstance().GetAuthType(devId) != authType) {
continue;
}
devices.push_back(devId);
}
}
void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate,
const KvStoreTuple &tuple)
{
if (storeDelegate == nullptr) {
ZLOGE("null store delegate");
return;
}
auto uuids = DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices());
if (uuids.empty()) {
ZLOGI("no remote devs");
return;
}
std::vector<std::string> sameAccountDevs {};
std::vector<std::string> defaultAccountDevs {};
GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT);
GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT);
if (!sameAccountDevs.empty()) {
auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, tuple.userId);
auto identifier =
DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second,
convertedIds.first, tuple.storeId);
ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s",
Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(convertedIds.second).c_str(),
DistributedData::Serializable::Marshall(sameAccountDevs).c_str(), convertedIds.first.c_str());
storeDelegate->SetEqualIdentifier(identifier, sameAccountDevs);
}
if (!defaultAccountDevs.empty()) {
auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, defaultAccountId);
auto identifier =
DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second,
convertedIds.first, tuple.storeId);
ZLOGI("no account identifier, store:%{public}s, device:%{public}.10s, appId:%{public}s",
Anonymous::Change(tuple.storeId).c_str(),
DistributedData::Serializable::Marshall(defaultAccountDevs).c_str(), convertedIds.first.c_str());
storeDelegate->SetEqualIdentifier(identifier, defaultAccountDevs);
}
}
} // namespace OHOS::DistributedData

View File

@ -32,11 +32,6 @@ public:
static UpgradeManager &GetInstance();
void Init(std::shared_ptr<ExecutorPool> executors);
CapMetaData GetCapability(const std::string &deviceId, bool &status);
static std::string GetIdentifierByType(int32_t groupType, bool &isSuccess);
static void SetCompatibleIdentifyByType(
KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple);
static void GetIdentifierParams(std::vector<std::string> &devices,
const std::vector<std::string> &uuids, int32_t authType);
private:
static constexpr int RETRY_INTERVAL = 500; // milliseconds

View File

@ -178,56 +178,3 @@ HWTEST_F(KvStoreDataServiceTest, AppExit001, TestSize.Level1)
Status status = kvStoreDataServiceTest.AppExit(uid, pid, token, appId);
EXPECT_EQ(status, SUCCESS);
}
/**
* @tc.name: ResolveAutoLaunchParamByIdentifier001
* @tc.desc:
* @tc.type: FUNC
* @tc.require:
* @tc.author: wangbin
*/
HWTEST_F(KvStoreDataServiceTest, ResolveAutoLaunchParamByIdentifier001, TestSize.Level1)
{
KvStoreDataService kvStoreDataServiceTest;
std::string identifier = "kvstoredataservicetest";
DistributedDB::AutoLaunchParam param;
auto status = kvStoreDataServiceTest.ResolveAutoLaunchParamByIdentifier(identifier, param);
EXPECT_EQ(status, SUCCESS);
}
/**
* @tc.name: ConvertSecurity001
* @tc.desc:
* @tc.type: FUNC
* @tc.require:
* @tc.author: wangbin
*/
HWTEST_F(KvStoreDataServiceTest, ConvertSecurity001, TestSize.Level1)
{
KvStoreDataService kvStoreDataServiceTest;
auto object = kvStoreDataServiceTest.ConvertSecurity(0);
ASSERT_NE(&object, nullptr);
}
/**
* @tc.name: InitNbDbOption001
* @tc.desc:
* @tc.type: FUNC
* @tc.require:
* @tc.author: wangbin
*/
HWTEST_F(KvStoreDataServiceTest, InitNbDbOption001, TestSize.Level1)
{
KvStoreDataService kvStoreDataServiceTest;
DistributedDB::KvStoreNbDelegate::Option dbOption;
Options options = {
.createIfMissing = false,
.encrypt = true,
.autoSync = false,
.securityLevel = 1,
};
std::vector<uint8_t> decryptKey;
DistributedDB::KvStoreNbDelegate::Option dbOptions;
auto status = kvStoreDataServiceTest.InitNbDbOption(options, decryptKey, dbOptions);
EXPECT_EQ(status, SUCCESS);
}

View File

@ -176,7 +176,7 @@ public:
virtual std::vector<std::string> GetWaterVersion(const std::string &deviceId) = 0;
virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId) {};
virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account = "") {};
virtual void SetConfig(const StoreConfig &storeConfig) {};

View File

@ -423,7 +423,7 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs
return ConvertStatus(dbStatus);
}
void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId)
void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account)
{
std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
if (delegate_ == nullptr) {
@ -434,10 +434,14 @@ void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::s
std::vector<std::string> sameAccountDevs{};
std::vector<std::string> defaultAccountDevs{};
auto uuids = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices());
if (uuids.empty()) {
ZLOGI("no remote device to sync.appId:%{public}s", appId.c_str());
return;
}
GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT);
GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT);
if (!sameAccountDevs.empty()) {
auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId();
auto accountId = account.empty() ? AccountDelegate::GetInstance()->GetUnencryptedAccountId() : account;
auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, accountId);
auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId);
ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s",

View File

@ -73,7 +73,7 @@ public:
int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override;
int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) override;
std::vector<std::string> GetWaterVersion(const std::string &deviceId) override;
void SetEqualIdentifier(const std::string &appId, const std::string &storeId) override;
void SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account = "") override;
void SetConfig(const StoreConfig &storeConfig) override;
void SetExecutor(std::shared_ptr<Executor> executor) override;
static DBPassword GetDBPassword(const StoreMetaData &data);

View File

@ -49,6 +49,7 @@
#include "utils/constant.h"
#include "utils/converter.h"
#include "water_version_manager.h"
#include "app_id_mapping/app_id_mapping_config_manager.h"
namespace OHOS::DistributedKv {
using namespace OHOS::DistributedData;
@ -58,6 +59,7 @@ using system_clock = std::chrono::system_clock;
using DMAdapter = DistributedData::DeviceManagerAdapter;
using DumpManager = OHOS::DistributedData::DumpManager;
using CommContext = OHOS::DistributedData::CommunicatorContext;
using SecretKeyMeta = DistributedData::SecretKeyMetaData;
static constexpr const char *DEFAULT_USER_ID = "0";
__attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_;
KVDBServiceImpl::Factory::Factory()
@ -753,31 +755,57 @@ int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const
return SUCCESS;
}
bool KVDBServiceImpl::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier,
const StoreMetaData &storeMeta)
{
std::vector<std::string> accountIds { accountId, "ohosAnonymousUid", "default" };
for (auto &id : accountIds) {
auto convertedIds =
AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user);
const std::string &tempTripleIdentifier =
DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first,
storeMeta.storeId, false);
if (tempTripleIdentifier == identifier) {
ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s",
Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str());
return true;
}
}
return false;
}
int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam &param)
{
ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(identifier).c_str());
std::vector<StoreMetaData> metaData;
auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid, param.userId });
auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid });
if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
ZLOGE("no store in user:%{public}s", param.userId.c_str());
ZLOGE("no meta data appId:%{public}s", param.appId.c_str());
return STORE_NOT_FOUND;
}
auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId();
for (const auto &storeMeta : metaData) {
if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END) {
storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END ||
(!param.userId.empty() && (param.userId != storeMeta.user))) {
continue;
}
auto identifierTag = DBManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
if (identifier != identifierTag) {
bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta);
if (identifier != identifierTag && !isTripleIdentifierEqual) {
continue;
}
auto watchers = GetWatchers(storeMeta.tokenId, storeMeta.storeId);
AutoCache::GetInstance().GetStore(storeMeta, watchers);
ZLOGD("user:%{public}s appId:%{public}s storeId:%{public}s", storeMeta.user.c_str(),
storeMeta.bundleName.c_str(), Anonymous::Change(storeMeta.storeId).c_str());
auto store = AutoCache::GetInstance().GetStore(storeMeta, watchers);
if (isTripleIdentifierEqual && store != nullptr) {
store->SetEqualIdentifier(storeMeta.appId, storeMeta.storeId, accountId);
}
ZLOGI("isTriple:%{public}d,storeId:%{public}s,appId:%{public}s,size:%{public}zu,user:%{public}s",
isTripleIdentifierEqual, Anonymous::Change(storeMeta.storeId).c_str(), storeMeta.storeId.c_str(),
watchers.size(), storeMeta.user.c_str());
}
return SUCCESS;
}

View File

@ -39,6 +39,7 @@ public:
using DBLaunchParam = DistributedDB::AutoLaunchParam;
using Handler = std::function<void(int, std::map<std::string, std::vector<std::string>> &)>;
using RefCount = DistributedData::RefCount;
using StoreMetaData = OHOS::DistributedData::StoreMetaData;
API_EXPORT KVDBServiceImpl();
virtual ~KVDBServiceImpl();
Status GetStoreIds(const AppId &appId, std::vector<StoreId> &storeIds) override;
@ -77,7 +78,6 @@ public:
Status RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) override;
private:
using StoreMetaData = OHOS::DistributedData::StoreMetaData;
using StrategyMeta = OHOS::DistributedData::StrategyMeta;
using StoreMetaDataLocal = OHOS::DistributedData::StoreMetaDataLocal;
using ChangeType = OHOS::DistributedData::DeviceMatrix::ChangeType;
@ -151,6 +151,8 @@ private:
bool IsRemoteChange(const StoreMetaData &metaData, const std::string &device);
bool IsOHOSType(const std::vector<std::string> &ids);
Status ConvertDbStatusNative(DBStatus status);
bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier,
const StoreMetaData &storeMeta);
static Factory factory_;
ConcurrentMap<uint32_t, SyncAgent> syncAgents_;
std::shared_ptr<ExecutorPool> executors_;