diff --git a/services/distributeddataservice/libs/distributeddb/BUILD.gn b/services/distributeddataservice/libs/distributeddb/BUILD.gn index 48d81beae207700d4ff664b86b2401035824a9ac..c363fd7c787f6819bbb3797fcf5cd8b6de4b3f02 100755 --- a/services/distributeddataservice/libs/distributeddb/BUILD.gn +++ b/services/distributeddataservice/libs/distributeddb/BUILD.gn @@ -101,6 +101,7 @@ ohos_shared_library("distributeddb") { "common/src/task_queue.cpp", "common/src/time_tick_monitor.cpp", "common/src/types_export.cpp", + "common/src/user_change_monitor.cpp", "common/src/value_object.cpp", "common/src/zlib_compression.cpp", "communicator/src/combine_status.cpp", @@ -219,6 +220,7 @@ ohos_shared_library("distributeddb") { "syncer/src/single_ver_data_message_schedule.cpp", "syncer/src/single_ver_data_packet.cpp", "syncer/src/single_ver_data_sync.cpp", + "syncer/src/single_ver_data_sync_utils.cpp", "syncer/src/single_ver_kv_sync_task_context.cpp", "syncer/src/single_ver_kv_syncer.cpp", "syncer/src/single_ver_relational_sync_task_context.cpp", @@ -230,6 +232,7 @@ ohos_shared_library("distributeddb") { "syncer/src/single_ver_sync_task_context.cpp", "syncer/src/single_ver_syncer.cpp", "syncer/src/subscribe_manager.cpp", + "syncer/src/sync_config.cpp", "syncer/src/sync_engine.cpp", "syncer/src/sync_operation.cpp", "syncer/src/sync_state_machine.cpp", diff --git a/services/distributeddataservice/libs/distributeddb/common/include/auto_launch.h b/services/distributeddataservice/libs/distributeddb/common/include/auto_launch.h index 320a77080e22c512d7d13f2ad0e121e674ccd5cf..3db633e5758ae36e36c3bb71c63c81c59e834d6c 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/auto_launch.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/auto_launch.h @@ -75,7 +75,8 @@ public: int EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier, const AutoLaunchOption &option); - int DisableKvStoreAutoLaunch(const std::string &identifier); + int DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier, + const std::string &userId); void GetAutoLaunchSyncDevices(const std::string &identifier, std::vector &devices) const; @@ -86,7 +87,8 @@ public: protected: - int EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &identifier); + int EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &normalIdentifier, + const std::string &dualTupleIdentifier, bool isDualTupleMode); int GetKVConnectionInEnable(AutoLaunchItem &autoLaunchItem, const std::string &identifier); @@ -103,37 +105,39 @@ protected: int RegisterObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt); - void ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier); + void ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier, + const std::string &userId); - void ConnectionLifeCycleCallbackTask(const std::string &identifier); + void ConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId); void OnlineCallBackTask(); - void GetDoOpenMap(std::map &doOpenMap); + void GetDoOpenMap(std::map> &doOpenMap); - void GetConnInDoOpenMap(std::map &doOpenMap); + void GetConnInDoOpenMap(std::map> &doOpenMap); - void UpdateGlobalMap(std::map &doOpenMap); + void UpdateGlobalMap(std::map> &doOpenMap); - void ReceiveUnknownIdentifierCallBackTask(const std::string &identifier); + void ReceiveUnknownIdentifierCallBackTask(const std::string &identifier, const std::string userId); static void CloseNotifier(const AutoLaunchItem &autoLaunchItem); - void ConnectionLifeCycleCallback(const std::string &identifier); + void ConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId); void OnlineCallBack(const std::string &device, bool isConnect); - int ReceiveUnknownIdentifierCallBack(const LabelType &label); + int ReceiveUnknownIdentifierCallBack(const LabelType &label, const std::string &originalUserId); - int AutoLaunchExt(const std::string &identifier); + int AutoLaunchExt(const std::string &identifier, const std::string &userId); - void AutoLaunchExtTask(const std::string identifier, AutoLaunchItem autoLaunchItem); + void AutoLaunchExtTask(const std::string identifier, const std::string userId, AutoLaunchItem autoLaunchItem); - void ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier); + void ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier, + const std::string &userId); - void ExtConnectionLifeCycleCallback(const std::string &identifier); + void ExtConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId); - void ExtConnectionLifeCycleCallbackTask(const std::string &identifier); + void ExtConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId); static int SetConflictNotifier(AutoLaunchItem &autoLaunchItem); @@ -161,13 +165,15 @@ protected: mutable std::mutex dataLock_; mutable std::mutex communicatorLock_; std::set onlineDevices_; - std::map autoLaunchItemMap_; + // key: label, value: + std::map> autoLaunchItemMap_; ICommunicatorAggregator *communicatorAggregator_ = nullptr; std::condition_variable cv_; std::mutex extLock_; std::map autoLaunchRequestCallbackMap_; - std::map extItemMap_; + // key: label, value: + std::map> extItemMap_; }; } // namespace DistributedDB #endif // AUTO_LAUNCH_H diff --git a/services/distributeddataservice/libs/distributeddb/common/include/db_common.h b/services/distributeddataservice/libs/distributeddb/common/include/db_common.h index e9faf72cd587d2e3152833fac4cd62c591d426b2..338475c67eb538a1e4538f15bb2df055e3df9254 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/db_common.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/db_common.h @@ -50,6 +50,8 @@ public: static std::string GenerateIdentifierId(const std::string &storeId, const std::string &appId, const std::string &userId); + static std::string GenerateDualTupleIdentifierId(const std::string &storeId, const std::string &appId); + static void SetDatabaseIds(KvDBProperties &properties, const std::string &appId, const std::string &userId, const std::string &storeId); @@ -63,6 +65,7 @@ public: // Define short macro substitute for original long expression for convenience of using #define VEC_TO_STR(x) DBCommon::VectorToHexString(x).c_str() #define STR_MASK(x) DBCommon::StringMasking(x).c_str() +#define STR_TO_HEX(x) DBCommon::TransferStringToHex(x).c_str() } // namespace DistributedDB #endif // DISTRIBUTEDDB_COMMON_H diff --git a/services/distributeddataservice/libs/distributeddb/common/include/db_errno.h b/services/distributeddataservice/libs/distributeddb/common/include/db_errno.h index c2bfadeda849b609ef30d8be5ad6698f081ddb6a..63a1974827fbf30c92265d7fc0ac032e14509d95 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/db_errno.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/db_errno.h @@ -120,6 +120,8 @@ constexpr int E_FORBID_CACHEDB = (E_BASE + 96); // such after rekey can not chec constexpr int E_INTERCEPT_DATA_FAIL = (E_BASE + 97); // Intercept push data failed. constexpr int E_INVALID_COMPRESS_ALGO = (E_BASE + 98); // The algo is defined, but there's no implement for the algo. constexpr int E_LOG_OVER_LIMITS = (E_BASE + 99); // The log file size is over the limits. +constexpr int E_MODE_MISMATCH = (E_BASE + 100); // dual sync mode mismatch +constexpr int E_NO_NEED_ACTIVE = (E_BASE + 101); // no need to active sync mode // Num 150+ is reserved for schema related errno, since it may be added regularly constexpr int E_JSON_PARSE_FAIL = (E_BASE + 150); // Parse json fail in grammatical level constexpr int E_JSON_INSERT_PATH_EXIST = (E_BASE + 151); // Path already exist before insert diff --git a/services/distributeddataservice/libs/distributeddb/common/include/db_types.h b/services/distributeddataservice/libs/distributeddb/common/include/db_types.h index 94f6cbd1c86d8c8a435f09842a3b9f22fafbcf77..c413fcdadade3ba4b541dba5cccc60a5935d4a47 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/db_types.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/db_types.h @@ -33,7 +33,7 @@ using ErrorCode = int; using SyncId = uint64_t; using WaterMark = uint64_t; using DatabaseCorruptHandler = std::function; -using DatabaseLifeCycleNotifier = std::function; +using DatabaseLifeCycleNotifier = std::function; const uint32_t MTU_SIZE = 5 * 1024 * 1024; // 5 M, 1024 is scale struct DataItem { diff --git a/services/distributeddataservice/libs/distributeddb/common/include/param_check_utils.h b/services/distributeddataservice/libs/distributeddb/common/include/param_check_utils.h index ce07d65e1221028e0ebf35c1b134c264fab6e9ac..2c522e9cb103f226e9d3ed3988dcbff3961cfe08 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/param_check_utils.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/param_check_utils.h @@ -32,7 +32,8 @@ public: static bool IsStoreIdSafe(const std::string &storeId); // check appId, userId, storeId. - static bool CheckStoreParameter(const std::string &storeId, const std::string &appId, const std::string &userId); + static bool CheckStoreParameter(const std::string &storeId, const std::string &appId, const std::string &userId, + bool isIgnoreUserIdCheck = false); // check encrypted args for KvStore. static bool CheckEncryptedParameter(CipherType cipher, const CipherPassword &passwd); diff --git a/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h b/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h index 6c540c3a237f4895cb9e9f8a3340b4a1a7fa810e..fa8a5d18268fdc5f1b39a09bebf26786ed3a335a 100644 --- a/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h @@ -84,7 +84,7 @@ public: int CompareWithTable(const TableInfo &inTableInfo) const; std::map GetSchemaDefine() const; std::string GetFieldName(uint32_t cid) const; // cid begin with 0 - const std::vector &GetFieldNames() const; // Sort by cid + const std::vector &GetFieldInfos() const; // Sort by cid bool IsValid() const; private: @@ -105,7 +105,7 @@ private: std::map indexDefines_; std::vector triggers_; JsonObject ToJsonObject() const; - mutable std::vector fieldNames_; + mutable std::vector fieldInfos_; }; class RelationalSyncOpinion { diff --git a/services/distributeddataservice/libs/distributeddb/common/include/runtime_context.h b/services/distributeddataservice/libs/distributeddb/common/include/runtime_context.h index cb20a79510b2d6d59940049e09b9192fe9c17805..9ac95d753677001b629db4005b27f26740a31004 100755 --- a/services/distributeddataservice/libs/distributeddb/common/include/runtime_context.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/runtime_context.h @@ -37,6 +37,7 @@ using TimerFinalizer = std::function; using TaskAction = std::function; using TimeChangedAction = std::function; using LockStatusNotifier = std::function; +using UserChangedAction = std::function; class RuntimeContext { public: @@ -51,6 +52,7 @@ public: virtual int SetCommunicatorAdapter(IAdapter *adapter) = 0; virtual int GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator) = 0; virtual void SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator) = 0; + virtual int GetLocalIdentity(std::string &outTarget) = 0; // Timer interfaces. virtual int SetTimer(int milliSeconds, const TimerAction &action, @@ -82,7 +84,8 @@ public: virtual int EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier, const AutoLaunchOption &option) = 0; - virtual int DisableKvStoreAutoLaunch(const std::string &identifier) = 0; + virtual int DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier, + const std::string &userId) = 0; virtual void GetAutoLaunchSyncDevices(const std::string &identifier, std::vector &devices) const = 0; @@ -109,8 +112,17 @@ public: virtual void SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier) = 0; - virtual void NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId, const std::string &storeId, - const std::string &deviceId, bool onlineStatus) = 0; + virtual void NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId, + const std::string &storeId, const std::string &deviceId, bool onlineStatus) = 0; + + virtual int SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback) = 0; + + virtual bool IsSyncerNeedActive(std::string &userId, std::string &appId, std::string &storeId) const = 0; + + virtual NotificationChain::Listener *RegisterUserChangedListerner(const UserChangedAction &action, + EventType event) = 0; + + virtual int NotifyUserChanged() const = 0; protected: RuntimeContext() = default; virtual ~RuntimeContext() {} diff --git a/services/distributeddataservice/libs/distributeddb/common/include/user_change_monitor.h b/services/distributeddataservice/libs/distributeddb/common/include/user_change_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..6591a40c4014d81d9f1a47efc85ac76eec990c15 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/common/include/user_change_monitor.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef USER_CHANGE_MONITOR_H +#define USER_CHANGE_MONITOR_H + +#include +#include "platform_specific.h" +#include "macro_utils.h" +#include "notification_chain.h" +#include "runtime_context.h" + +namespace DistributedDB { +class UserChangeMonitor final { +public: + UserChangeMonitor(); + ~UserChangeMonitor(); + + DISABLE_COPY_ASSIGN_MOVE(UserChangeMonitor); + + // Start the UserChangeMonitor + int Start(); + + // Stop the UserChangeMonitor + void Stop(); + + // Register a user changed lister, it will be callback when user changed. + NotificationChain::Listener *RegisterUserChangedListerner(const UserChangedAction &action, EventType event, + int &errCode); + + // Notify USER_CHANGE_EVENT. + void NotifyUserChanged() const; + static constexpr EventType USER_ACTIVE_EVENT = 3; + static constexpr EventType USER_NON_ACTIVE_EVENT = 4; + static constexpr EventType USER_ACTIVE_TO_NON_ACTIVE_EVENT = 5; +private: + // prepare notifier chain + int PrepareNotifierChain(); + + mutable std::shared_mutex userChangeMonitorLock_; + NotificationChain *userNotifier_; + bool isStarted_ = false; +}; +} // namespace DistributedDB + +#endif // USER_CHANGE_MONITOR_H \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/common/src/auto_launch.cpp b/services/distributeddataservice/libs/distributeddb/common/src/auto_launch.cpp index 999f82293de13d9eac453d42361690fc41d4d2f7..a2de998919cc3b7c96017f372ef8b029dcba6838 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/auto_launch.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/auto_launch.cpp @@ -64,7 +64,8 @@ void AutoLaunch::SetCommunicatorAggregator(ICommunicatorAggregator *aggregator) LOGW("[AutoLaunch] aggregator->RegOnConnectCallback errCode:%d", errCode); } errCode = aggregator->RegCommunicatorLackCallback( - std::bind(&AutoLaunch::ReceiveUnknownIdentifierCallBack, this, std::placeholders::_1), nullptr); + std::bind(&AutoLaunch::ReceiveUnknownIdentifierCallBack, this, std::placeholders::_1, std::placeholders::_2), + nullptr); if (errCode != E_OK) { LOGW("[AutoLaunch] aggregator->RegCommunicatorLackCallback errCode:%d", errCode); } @@ -81,55 +82,78 @@ AutoLaunch::~AutoLaunch() communicatorAggregator_ = nullptr; } } - - std::set inDisableSet; - std::set inWaitIdleSet; + // {identifier, userId} + std::set> inDisableSet; + std::set> inWaitIdleSet; std::unique_lock autoLock(dataLock_); - for (auto &iter : autoLaunchItemMap_) { - if (iter.second.isDisable) { - inDisableSet.insert(iter.first); - } else if (iter.second.state == AutoLaunchItemState::IDLE && (!iter.second.inObserver)) { - TryCloseConnection(iter.second); - } else { - inWaitIdleSet.insert(iter.first); - iter.second.isDisable = true; + for (auto &items : autoLaunchItemMap_) { + for (auto &iter : items.second) { + if (iter.second.isDisable) { + inDisableSet.insert({items.first, iter.first}); + } else if (iter.second.state == AutoLaunchItemState::IDLE && (!iter.second.inObserver)) { + TryCloseConnection(iter.second); + } else { + inWaitIdleSet.insert({items.first, iter.first}); + iter.second.isDisable = true; + } } } - for (const auto &identifier : inDisableSet) { - cv_.wait(autoLock, [identifier, this] { - return autoLaunchItemMap_.count(identifier) == 0 || (!autoLaunchItemMap_[identifier].isDisable); + for (const auto &identifierInfo : inDisableSet) { + cv_.wait(autoLock, [identifierInfo, this] { + return autoLaunchItemMap_.count(identifierInfo.first) == 0 || + autoLaunchItemMap_[identifierInfo.first].count(identifierInfo.second) == 0 || + (!autoLaunchItemMap_[identifierInfo.first][identifierInfo.second].isDisable); }); - if (autoLaunchItemMap_.count(identifier) != 0) { - TryCloseConnection(autoLaunchItemMap_[identifier]); + if (autoLaunchItemMap_.count(identifierInfo.first) != 0 && + autoLaunchItemMap_[identifierInfo.first].count(identifierInfo.second)) { + TryCloseConnection(autoLaunchItemMap_[identifierInfo.first][identifierInfo.second]); } } - for (const auto &identifier : inWaitIdleSet) { - cv_.wait(autoLock, [identifier, this] { - return (autoLaunchItemMap_[identifier].state == AutoLaunchItemState::IDLE) && - (!autoLaunchItemMap_[identifier].inObserver); + for (const auto &info : inWaitIdleSet) { + cv_.wait(autoLock, [info, this] { + return (autoLaunchItemMap_[info.first][info.second].state == AutoLaunchItemState::IDLE) && + (!autoLaunchItemMap_[info.first][info.second].inObserver); }); - TryCloseConnection(autoLaunchItemMap_[identifier]); + TryCloseConnection(autoLaunchItemMap_[info.first][info.second]); } } -int AutoLaunch::EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &identifier) +int AutoLaunch::EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &normalIdentifier, + const std::string &dualTupleIdentifier, bool isDualTupleMode) { + std::lock_guard autoLock(dataLock_); + std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, ""); + if (isDualTupleMode && autoLaunchItemMap_.count(normalIdentifier) != 0 && + autoLaunchItemMap_[normalIdentifier].count(userId) != 0) { + LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled in normal tuple mode"); + return -E_ALREADY_SET; + } + if (!isDualTupleMode && autoLaunchItemMap_.count(dualTupleIdentifier) != 0 && + autoLaunchItemMap_[dualTupleIdentifier].count(userId) != 0) { + LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled in dual tuple mode"); + return -E_ALREADY_SET; + } + std::string identifier = isDualTupleMode ? dualTupleIdentifier : normalIdentifier; if (identifier.empty()) { LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is invalid"); return -E_INVALID_ARGS; } - std::lock_guard autoLock(dataLock_); - if (autoLaunchItemMap_.count(identifier) != 0) { + if (autoLaunchItemMap_.count(identifier) != 0 && autoLaunchItemMap_[identifier].count(userId) != 0) { LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck identifier is already enabled!"); return -E_ALREADY_SET; } - if (autoLaunchItemMap_.size() == MAX_AUTO_LAUNCH_ITEM_NUM) { + uint32_t autoLaunchItemSize = 0; + for (const auto item : autoLaunchItemMap_) { + autoLaunchItemSize += item.second.size(); + } + if (autoLaunchItemSize == MAX_AUTO_LAUNCH_ITEM_NUM) { LOGE("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck size is max(8) now"); return -E_MAX_LIMITS; } autoLaunchItem.state = AutoLaunchItemState::IN_ENABLE; - autoLaunchItemMap_[identifier] = autoLaunchItem; - LOGI("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck insert map first"); + autoLaunchItemMap_[identifier][userId] = autoLaunchItem; + LOGI("[AutoLaunch] EnableKvStoreAutoLaunchParmCheck ok identifier=%.6s, isDual=%d", + STR_TO_HEX(identifier), isDualTupleMode); return E_OK; } @@ -137,17 +161,29 @@ int AutoLaunch::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLa const AutoLaunchOption &option) { LOGI("[AutoLaunch] EnableKvStoreAutoLaunch"); + bool isDualTupleMode = properties.GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false); + std::string dualTupleIdentifier = properties.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); std::string identifier = properties.GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); + std::string userId = properties.GetStringProp(KvDBProperties::USER_ID, ""); + std::string appId = properties.GetStringProp(DBProperties::APP_ID, ""); + std::string storeId = properties.GetStringProp(DBProperties::STORE_ID, ""); std::shared_ptr ptr = std::make_shared(properties); AutoLaunchItem autoLaunchItem { ptr, notifier, option.observer, option.conflictType, option.notifier }; autoLaunchItem.isAutoSync = option.isAutoSync; autoLaunchItem.type = DBType::DB_KV; - int errCode = EnableKvStoreAutoLaunchParmCheck(autoLaunchItem, identifier); + int errCode = EnableKvStoreAutoLaunchParmCheck(autoLaunchItem, identifier, dualTupleIdentifier, isDualTupleMode); if (errCode != E_OK) { LOGE("[AutoLaunch] EnableKvStoreAutoLaunch failed errCode:%d", errCode); return errCode; } - errCode = GetKVConnectionInEnable(autoLaunchItem, identifier); + if (isDualTupleMode && !RuntimeContext::GetInstance()->IsSyncerNeedActive(userId, appId, storeId)) { + std::lock_guard autoLock(dataLock_); + std::string tmpIdentifier = isDualTupleMode ? dualTupleIdentifier : identifier; + LOGI("[AutoLaunch] GetDoOpenMap identifier=%0.6s no need to open", STR_TO_HEX(tmpIdentifier)); + autoLaunchItemMap_[tmpIdentifier][userId].state = AutoLaunchItemState::IDLE; + return errCode; + } + errCode = GetKVConnectionInEnable(autoLaunchItem, isDualTupleMode ? dualTupleIdentifier : identifier); if (errCode == E_OK) { LOGI("[AutoLaunch] EnableKvStoreAutoLaunch ok"); } else { @@ -162,17 +198,21 @@ int AutoLaunch::GetKVConnectionInEnable(AutoLaunchItem &autoLaunchItem, const st int errCode; std::shared_ptr properties = std::static_pointer_cast(autoLaunchItem.propertiesPtr); + std::string userId = properties->GetStringProp(KvDBProperties::USER_ID, ""); autoLaunchItem.conn = KvDBManager::GetDatabaseConnection(*properties, errCode, false); if (errCode == -E_ALREADY_OPENED) { LOGI("[AutoLaunch] GetKVConnectionInEnable user already getkvstore by self"); std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; return E_OK; } if (autoLaunchItem.conn == nullptr) { LOGE("[AutoLaunch] GetKVConnectionInEnable GetDatabaseConnection errCode:%d", errCode); std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_.erase(identifier); + autoLaunchItemMap_[identifier].erase(userId); + if (autoLaunchItemMap_[identifier].size() == 0) { + autoLaunchItemMap_.erase(identifier); + } return errCode; } bool isEmpty = false; @@ -182,30 +222,36 @@ int AutoLaunch::GetKVConnectionInEnable(AutoLaunchItem &autoLaunchItem, const st } if (isEmpty) { LOGI("[AutoLaunch] GetKVConnectionInEnable no online device, ReleaseDatabaseConnection"); - IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); + IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); errCode = KvDBManager::ReleaseDatabaseConnection(kvConn); if (errCode != E_OK) { LOGE("[AutoLaunch] GetKVConnectionInEnable ReleaseDatabaseConnection failed errCode:%d", errCode); std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_.erase(identifier); + autoLaunchItemMap_[identifier].erase(userId); + if (autoLaunchItemMap_[identifier].size() == 0) { + autoLaunchItemMap_.erase(identifier); + } return errCode; } std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; return E_OK; } errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, false); if (errCode == E_OK) { std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; - autoLaunchItemMap_[identifier].conn = autoLaunchItem.conn; - autoLaunchItemMap_[identifier].observerHandle = autoLaunchItem.observerHandle; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].conn = autoLaunchItem.conn; + autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle; LOGI("[AutoLaunch] GetKVConnectionInEnable RegisterObserverAndLifeCycleCallback ok"); } else { LOGE("[AutoLaunch] GetKVConnectionInEnable RegisterObserverAndLifeCycleCallback err, do CloseConnection"); TryCloseConnection(autoLaunchItem); // do nothing if failed std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_.erase(identifier); + autoLaunchItemMap_[identifier].erase(userId); + if (autoLaunchItemMap_[identifier].size() == 0) { + autoLaunchItemMap_.erase(identifier); + } } return errCode; } @@ -218,7 +264,7 @@ int AutoLaunch::CloseConnectionStrict(AutoLaunchItem &autoLaunchItem) LOGI("[AutoLaunch] CloseConnectionStrict conn is nullptr, do nothing"); return E_OK; } - IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); + IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); int errCode = kvConn->RegisterLifeCycleCallback(nullptr); if (errCode != E_OK) { LOGE("[AutoLaunch] CloseConnectionStrict RegisterLifeCycleCallback failed errCode:%d", errCode); @@ -306,16 +352,19 @@ int AutoLaunch::RegisterObserver(AutoLaunchItem &autoLaunchItem, const std::stri }); return E_OK; } + std::shared_ptr properties = + std::static_pointer_cast(autoLaunchItem.propertiesPtr); + std::string userId = properties->GetStringProp(KvDBProperties::USER_ID, ""); int errCode; Key key; KvDBObserverHandle *observerHandle = nullptr; - IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); + IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); if (isExt) { observerHandle = kvConn->RegisterObserver(OBSERVER_CHANGES_FOREIGN, key, - std::bind(&AutoLaunch::ExtObserverFunc, this, std::placeholders::_1, identifier), errCode); + std::bind(&AutoLaunch::ExtObserverFunc, this, std::placeholders::_1, identifier, userId), errCode); } else { observerHandle = kvConn->RegisterObserver(OBSERVER_CHANGES_FOREIGN, key, - std::bind(&AutoLaunch::ObserverFunc, this, std::placeholders::_1, identifier), errCode); + std::bind(&AutoLaunch::ObserverFunc, this, std::placeholders::_1, identifier, userId), errCode); } if (errCode != E_OK) { @@ -326,31 +375,30 @@ int AutoLaunch::RegisterObserver(AutoLaunchItem &autoLaunchItem, const std::stri return E_OK; } -void AutoLaunch::ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier) +void AutoLaunch::ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier, + const std::string &userId) { - LOGD("[AutoLaunch] ObserverFunc"); + LOGD("[AutoLaunch] ObserverFunc identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; - std::string userId; std::string appId; std::string storeId; { std::lock_guard autoLock(dataLock_); - if (autoLaunchItemMap_.count(identifier) == 0) { + if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) { LOGE("[AutoLaunch] ObserverFunc err no this identifier in map"); return; } - if (autoLaunchItemMap_[identifier].isDisable) { + if (autoLaunchItemMap_[identifier][userId].isDisable) { LOGI("[AutoLaunch] ObserverFunc isDisable, do nothing"); return; } - autoLaunchItemMap_[identifier].inObserver = true; - autoLaunchItem.observer = autoLaunchItemMap_[identifier].observer; - autoLaunchItem.isWriteOpenNotifiered = autoLaunchItemMap_[identifier].isWriteOpenNotifiered; - autoLaunchItem.notifier = autoLaunchItemMap_[identifier].notifier; - + autoLaunchItemMap_[identifier][userId].inObserver = true; + autoLaunchItem.observer = autoLaunchItemMap_[identifier][userId].observer; + autoLaunchItem.isWriteOpenNotifiered = autoLaunchItemMap_[identifier][userId].isWriteOpenNotifiered; + autoLaunchItem.notifier = autoLaunchItemMap_[identifier][userId].notifier; + std::shared_ptr properties = - std::static_pointer_cast(autoLaunchItemMap_[identifier].propertiesPtr); - userId = properties->GetStringProp(KvDBProperties::USER_ID, ""); + std::static_pointer_cast(autoLaunchItemMap_[identifier][userId].propertiesPtr); appId = properties->GetStringProp(KvDBProperties::APP_ID, ""); storeId = properties->GetStringProp(KvDBProperties::STORE_ID, ""); } @@ -364,7 +412,7 @@ void AutoLaunch::ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std: if (!autoLaunchItem.isWriteOpenNotifiered && autoLaunchItem.notifier != nullptr) { { std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].isWriteOpenNotifiered = true; + autoLaunchItemMap_[identifier][userId].isWriteOpenNotifiered = true; } AutoLaunchNotifier notifier = autoLaunchItem.notifier; int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] { @@ -376,52 +424,61 @@ void AutoLaunch::ObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std: } } std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].inObserver = false; + autoLaunchItemMap_[identifier][userId].inObserver = false; cv_.notify_all(); - LOGI("[AutoLaunch] ObserverFunc finished"); } -int AutoLaunch::DisableKvStoreAutoLaunch(const std::string &identifier) +int AutoLaunch::DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier, + const std::string &userId) { - LOGI("[AutoLaunch] DisableKvStoreAutoLaunch"); + std::string identifier; + if (autoLaunchItemMap_.count(normalIdentifier) == 0) { + identifier = dualTupleIdentifier; + } else { + identifier = normalIdentifier; + } + LOGI("[AutoLaunch] DisableKvStoreAutoLaunch identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; { std::unique_lock autoLock(dataLock_); - if (autoLaunchItemMap_.count(identifier) == 0) { + if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) { LOGE("[AutoLaunch] DisableKvStoreAutoLaunch identifier is not exist!"); return -E_NOT_FOUND; } - if (autoLaunchItemMap_[identifier].isDisable == true) { + if (autoLaunchItemMap_[identifier][userId].isDisable == true) { LOGI("[AutoLaunch] DisableKvStoreAutoLaunch already disabling in another thread, do nothing here"); return -E_BUSY; } - if (autoLaunchItemMap_[identifier].state == AutoLaunchItemState::IN_ENABLE) { + if (autoLaunchItemMap_[identifier][userId].state == AutoLaunchItemState::IN_ENABLE) { LOGE("[AutoLaunch] DisableKvStoreAutoLaunch enable not return, do not disable!"); return -E_BUSY; } - autoLaunchItemMap_[identifier].isDisable = true; - if (autoLaunchItemMap_[identifier].state != AutoLaunchItemState::IDLE) { + autoLaunchItemMap_[identifier][userId].isDisable = true; + if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) { LOGI("[AutoLaunch] DisableKvStoreAutoLaunch wait idle"); - cv_.wait(autoLock, [identifier, this] { - return (autoLaunchItemMap_[identifier].state == AutoLaunchItemState::IDLE) && - (!autoLaunchItemMap_[identifier].inObserver); + cv_.wait(autoLock, [identifier, userId, this] { + return (autoLaunchItemMap_[identifier][userId].state == AutoLaunchItemState::IDLE) && + (!autoLaunchItemMap_[identifier][userId].inObserver); }); LOGI("[AutoLaunch] DisableKvStoreAutoLaunch wait idle ok"); } - autoLaunchItem = autoLaunchItemMap_[identifier]; + autoLaunchItem = autoLaunchItemMap_[identifier][userId]; } int errCode = CloseConnectionStrict(autoLaunchItem); if (errCode == E_OK) { std::unique_lock autoLock(dataLock_); - autoLaunchItemMap_.erase(identifier); + autoLaunchItemMap_[identifier].erase(userId); + if (autoLaunchItemMap_[identifier].size() == 0) { + autoLaunchItemMap_.erase(identifier); + } cv_.notify_all(); LOGI("[AutoLaunch] DisableKvStoreAutoLaunch CloseConnection ok"); } else { LOGE("[AutoLaunch] DisableKvStoreAutoLaunch CloseConnection failed errCode:%d", errCode); std::unique_lock autoLock(dataLock_); - autoLaunchItemMap_[identifier].isDisable = false; - autoLaunchItemMap_[identifier].observerHandle = autoLaunchItem.observerHandle; + autoLaunchItemMap_[identifier][userId].isDisable = false; + autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle; cv_.notify_all(); return errCode; } @@ -460,36 +517,36 @@ void AutoLaunch::CloseNotifier(const AutoLaunchItem &autoLaunchItem) } } -void AutoLaunch::ConnectionLifeCycleCallbackTask(const std::string &identifier) +void AutoLaunch::ConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId) { - LOGI("[AutoLaunch] ConnectionLifeCycleCallbackTask"); + LOGI("[AutoLaunch] ConnectionLifeCycleCallbackTask identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; { std::lock_guard autoLock(dataLock_); - if (autoLaunchItemMap_.count(identifier) == 0) { + if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) { LOGE("[AutoLaunch] ConnectionLifeCycleCallback identifier is not exist!"); return; } - if (autoLaunchItemMap_[identifier].isDisable) { + if (autoLaunchItemMap_[identifier][userId].isDisable) { LOGI("[AutoLaunch] ConnectionLifeCycleCallback isDisable, do nothing"); return; } - if (autoLaunchItemMap_[identifier].state != AutoLaunchItemState::IDLE) { + if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) { LOGI("[AutoLaunch] ConnectionLifeCycleCallback state:%d is not idle, do nothing", - autoLaunchItemMap_[identifier].state); + autoLaunchItemMap_[identifier][userId].state); return; } - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IN_LIFE_CYCLE_CALL_BACK; - autoLaunchItem = autoLaunchItemMap_[identifier]; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IN_LIFE_CYCLE_CALL_BACK; + autoLaunchItem = autoLaunchItemMap_[identifier][userId]; } LOGI("[AutoLaunch] ConnectionLifeCycleCallbackTask do CloseConnection"); TryCloseConnection(autoLaunchItem); // do onthing if failed LOGI("[AutoLaunch] ConnectionLifeCycleCallback do CloseConnection finished"); { std::lock_guard lock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; - autoLaunchItemMap_[identifier].conn = nullptr; - autoLaunchItemMap_[identifier].isWriteOpenNotifiered = false; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].conn = nullptr; + autoLaunchItemMap_[identifier][userId].isWriteOpenNotifiered = false; cv_.notify_all(); LOGI("[AutoLaunch] ConnectionLifeCycleCallback notify_all"); } @@ -498,11 +555,11 @@ void AutoLaunch::ConnectionLifeCycleCallbackTask(const std::string &identifier) } } -void AutoLaunch::ConnectionLifeCycleCallback(const std::string &identifier) +void AutoLaunch::ConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId) { - LOGI("[AutoLaunch] ConnectionLifeCycleCallback"); + LOGI("[AutoLaunch] ConnectionLifeCycleCallback identifier=%0.6s", STR_TO_HEX(identifier)); int errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(&AutoLaunch::ConnectionLifeCycleCallbackTask, - this, identifier)); + this, identifier, userId)); if (errCode != E_OK) { LOGE("[AutoLaunch] ConnectionLifeCycleCallback ScheduleTask failed"); } @@ -543,62 +600,74 @@ void AutoLaunch::OnlineCallBack(const std::string &device, bool isConnect) void AutoLaunch::OnlineCallBackTask() { LOGI("[AutoLaunch] OnlineCallBackTask"); - std::map doOpenMap; + // > + std::map> doOpenMap; GetDoOpenMap(doOpenMap); GetConnInDoOpenMap(doOpenMap); UpdateGlobalMap(doOpenMap); } -void AutoLaunch::GetDoOpenMap(std::map &doOpenMap) +void AutoLaunch::GetDoOpenMap(std::map> &doOpenMap) { std::lock_guard autoLock(dataLock_); LOGI("[AutoLaunch] GetDoOpenMap"); - for (auto &iter : autoLaunchItemMap_) { - if (iter.second.isDisable) { - LOGI("[AutoLaunch] GetDoOpenMap this item isDisable do nothing"); - continue; - } else if (iter.second.state != AutoLaunchItemState::IDLE) { - LOGI("[AutoLaunch] GetDoOpenMap this item state:%d is not idle do nothing", iter.second.state); - continue; - } else if (iter.second.conn != nullptr) { - LOGI("[AutoLaunch] GetDoOpenMap this item is opened"); - continue; - } else { - doOpenMap[iter.first] = iter.second; - iter.second.state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK; - LOGI("[AutoLaunch] GetDoOpenMap set state IN_COMMUNICATOR_CALL_BACK"); + for (auto &items : autoLaunchItemMap_) { + for (auto &iter : items.second) { + std::string userId = iter.second.propertiesPtr->GetStringProp(DBProperties::USER_ID, ""); + std::string appId = iter.second.propertiesPtr->GetStringProp(DBProperties::APP_ID, ""); + std::string storeId = iter.second.propertiesPtr->GetStringProp(DBProperties::STORE_ID, ""); + bool isDualTupleMode = iter.second.propertiesPtr->GetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, false); + if (iter.second.isDisable) { + LOGI("[AutoLaunch] GetDoOpenMap this item isDisable do nothing"); + continue; + } else if (iter.second.state != AutoLaunchItemState::IDLE) { + LOGI("[AutoLaunch] GetDoOpenMap this item state:%d is not idle do nothing", iter.second.state); + continue; + } else if (iter.second.conn != nullptr) { + LOGI("[AutoLaunch] GetDoOpenMap this item is opened"); + continue; + } else if (isDualTupleMode && !RuntimeContext::GetInstance()->IsSyncerNeedActive(userId, appId, storeId)) { + LOGI("[AutoLaunch] GetDoOpenMap this item no need to open"); + continue; + } else { + doOpenMap[items.first][iter.first] = iter.second; + iter.second.state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK; + LOGI("[AutoLaunch] GetDoOpenMap this item in IN_COMMUNICATOR_CALL_BACK"); + } } } } -void AutoLaunch::GetConnInDoOpenMap(std::map &doOpenMap) +void AutoLaunch::GetConnInDoOpenMap(std::map> &doOpenMap) { LOGI("[AutoLaunch] GetConnInDoOpenMap doOpenMap.size():%llu", doOpenMap.size()); if (doOpenMap.empty()) { return; } SemaphoreUtils sema(1 - doOpenMap.size()); - for (auto &iter : doOpenMap) { - int errCode = RuntimeContext::GetInstance()->ScheduleTask([&sema, &iter, this] { - int ret = OpenOneConnection(iter.second); - LOGI("[AutoLaunch] GetConnInDoOpenMap GetOneConnection errCode:%d\n", ret); - if (iter.second.conn == nullptr) { + for (auto &items : doOpenMap) { + for (auto &iter : items.second) { + int errCode = RuntimeContext::GetInstance()->ScheduleTask([&sema, &iter, &items, this] { + int ret = OpenOneConnection(iter.second); + LOGI("[AutoLaunch] GetConnInDoOpenMap GetOneConnection errCode:%d\n", ret); + if (iter.second.conn == nullptr) { + sema.SendSemaphore(); + LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); + return; + } + ret = RegisterObserverAndLifeCycleCallback(iter.second, items.first, false); + if (ret != E_OK) { + LOGE("[AutoLaunch] GetConnInDoOpenMap failed, we do CloseConnection"); + TryCloseConnection(iter.second); // if here failed, do nothing + iter.second.conn = nullptr; + } sema.SendSemaphore(); LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); - return; - } - ret = RegisterObserverAndLifeCycleCallback(iter.second, iter.first, false); - if (ret != E_OK) { - LOGE("[AutoLaunch] GetConnInDoOpenMap failed, we do CloseConnection"); - TryCloseConnection(iter.second); // if here failed, do nothing - iter.second.conn = nullptr; + }); + if (errCode != E_OK) { + LOGE("[AutoLaunch] GetConnInDoOpenMap ScheduleTask failed, SendSemaphore"); + sema.SendSemaphore(); } - sema.SendSemaphore(); - LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); - }); - if (errCode != E_OK) { - LOGE("[AutoLaunch] GetConnInDoOpenMap ScheduleTask failed, SendSemaphore"); - sema.SendSemaphore(); } } LOGI("[AutoLaunch] GetConnInDoOpenMap WaitSemaphore"); @@ -606,37 +675,39 @@ void AutoLaunch::GetConnInDoOpenMap(std::map &doOpe LOGI("[AutoLaunch] GetConnInDoOpenMap WaitSemaphore ok"); } -void AutoLaunch::UpdateGlobalMap(std::map &doOpenMap) +void AutoLaunch::UpdateGlobalMap(std::map> &doOpenMap) { std::lock_guard autoLock(dataLock_); LOGI("[AutoLaunch] UpdateGlobalMap"); - for (auto &iter : doOpenMap) { - if (iter.second.conn != nullptr) { - autoLaunchItemMap_[iter.first].conn = iter.second.conn; - autoLaunchItemMap_[iter.first].observerHandle = iter.second.observerHandle; - autoLaunchItemMap_[iter.first].isWriteOpenNotifiered = false; - LOGI("[AutoLaunch] UpdateGlobalMap opened conn update map"); + for (auto &items : doOpenMap) { + for (auto &iter : items.second) { + if (iter.second.conn != nullptr) { + autoLaunchItemMap_[items.first][iter.first].conn = iter.second.conn; + autoLaunchItemMap_[items.first][iter.first].observerHandle = iter.second.observerHandle; + autoLaunchItemMap_[items.first][iter.first].isWriteOpenNotifiered = false; + LOGI("[AutoLaunch] UpdateGlobalMap opened conn update map"); + } + autoLaunchItemMap_[items.first][iter.first].state = AutoLaunchItemState::IDLE; + LOGI("[AutoLaunch] UpdateGlobalMap opened conn set state IDLE"); } - autoLaunchItemMap_[iter.first].state = AutoLaunchItemState::IDLE; - LOGI("[AutoLaunch] UpdateGlobalMap opened conn set state IDLE"); } cv_.notify_all(); LOGI("[AutoLaunch] UpdateGlobalMap finish notify_all"); } -void AutoLaunch::ReceiveUnknownIdentifierCallBackTask(const std::string &identifier) +void AutoLaunch::ReceiveUnknownIdentifierCallBackTask(const std::string &identifier, const std::string userId) { - LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask"); + LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; { std::lock_guard autoLock(dataLock_); - autoLaunchItem = autoLaunchItemMap_[identifier]; + autoLaunchItem = autoLaunchItemMap_[identifier][userId]; } int errCode = OpenOneConnection(autoLaunchItem); LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack GetOneConnection errCode:%d\n", errCode); if (autoLaunchItem.conn == nullptr) { std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; cv_.notify_all(); LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask set state IDLE"); return; @@ -647,56 +718,68 @@ void AutoLaunch::ReceiveUnknownIdentifierCallBackTask(const std::string &identif LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask do CloseConnection"); TryCloseConnection(autoLaunchItem); // if here failed, do nothing std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; cv_.notify_all(); LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask set state IDLE"); return; } std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].conn = autoLaunchItem.conn; - autoLaunchItemMap_[identifier].observerHandle = autoLaunchItem.observerHandle; - autoLaunchItemMap_[identifier].isWriteOpenNotifiered = false; - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].conn = autoLaunchItem.conn; + autoLaunchItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle; + autoLaunchItemMap_[identifier][userId].isWriteOpenNotifiered = false; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; cv_.notify_all(); LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBackTask conn opened set state IDLE"); } -int AutoLaunch::ReceiveUnknownIdentifierCallBack(const LabelType &label) +int AutoLaunch::ReceiveUnknownIdentifierCallBack(const LabelType &label, const std::string &originalUserId) { const std::string identifier(label.begin(), label.end()); - LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack"); + // originalUserId size maybe 0 + std::string userId = originalUserId; + if (originalUserId.size() == 0 && autoLaunchItemMap_.count(identifier) != 0 && + autoLaunchItemMap_[identifier].size() > 1) { + LOGE("[AutoLaunch] normal tuple mode userId larger than one userId"); + goto EXT; + } + if (originalUserId.size() == 0 && autoLaunchItemMap_.count(identifier) != 0 && + autoLaunchItemMap_[identifier].size() == 1) { + // normal tuple mode + userId = autoLaunchItemMap_[identifier].begin()->first; + } + LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack identifier=%0.6s", STR_TO_HEX(identifier)); int errCode; { std::lock_guard autoLock(dataLock_); - if (autoLaunchItemMap_.count(identifier) == 0) { + if (autoLaunchItemMap_.count(identifier) == 0 || autoLaunchItemMap_[identifier].count(userId) == 0) { LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack not find identifier"); goto EXT; - } else if (autoLaunchItemMap_[identifier].isDisable) { + } else if (autoLaunchItemMap_[identifier][userId].isDisable) { LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack isDisable ,do nothing"); return -E_NOT_FOUND; // not E_OK is ok for communicator - } else if (autoLaunchItemMap_[identifier].conn != nullptr) { + } else if (autoLaunchItemMap_[identifier][userId].conn != nullptr) { LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack conn is not nullptr"); return E_OK; - } else if (autoLaunchItemMap_[identifier].state != AutoLaunchItemState::IDLE) { + } else if (autoLaunchItemMap_[identifier][userId].state != AutoLaunchItemState::IDLE) { LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack state:%d is not idle, do nothing", - autoLaunchItemMap_[identifier].state); + autoLaunchItemMap_[identifier][userId].state); return E_OK; } - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IN_COMMUNICATOR_CALL_BACK; LOGI("[AutoLaunch] ReceiveUnknownIdentifierCallBack set state IN_COMMUNICATOR_CALL_BACK"); } errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind( - &AutoLaunch::ReceiveUnknownIdentifierCallBackTask, this, identifier)); + &AutoLaunch::ReceiveUnknownIdentifierCallBackTask, this, identifier, userId)); if (errCode != E_OK) { LOGE("[AutoLaunch] ReceiveUnknownIdentifierCallBack ScheduleTask failed"); std::lock_guard autoLock(dataLock_); - autoLaunchItemMap_[identifier].state = AutoLaunchItemState::IDLE; + autoLaunchItemMap_[identifier][userId].state = AutoLaunchItemState::IDLE; } return errCode; EXT: - return AutoLaunchExt(identifier); + return AutoLaunchExt(identifier, userId); } void AutoLaunch::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBType type) @@ -710,9 +793,11 @@ void AutoLaunch::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &c } } -int AutoLaunch::AutoLaunchExt(const std::string &identifier) +int AutoLaunch::AutoLaunchExt(const std::string &identifier, const std::string &userId) { AutoLaunchParam param; + // for non dual tuple mode, userId is "" + param.userId = userId; DBType openType = DBType::DB_INVALID; int errCode = ExtAutoLaunchRequestCallBack(identifier, param, openType); if (errCode != E_OK) { @@ -740,28 +825,32 @@ int AutoLaunch::AutoLaunchExt(const std::string &identifier) autoLaunchItem.type = openType; autoLaunchItem.storeObserver = param.option.storeObserver; errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind(&AutoLaunch::AutoLaunchExtTask, this, - identifier, autoLaunchItem)); + identifier, param.userId, autoLaunchItem)); if (errCode != E_OK) { LOGE("[AutoLaunch] AutoLaunchExt ScheduleTask errCode:%d", errCode); } return errCode; } -void AutoLaunch::AutoLaunchExtTask(const std::string identifier, AutoLaunchItem autoLaunchItem) +void AutoLaunch::AutoLaunchExtTask(const std::string identifier, const std::string userId, + AutoLaunchItem autoLaunchItem) { { std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) != 0) { - LOGE("[AutoLaunch] extItemMap_ has this identifier"); + if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0) { + LOGE("[AutoLaunch] extItemMap has this identifier"); return; } - extItemMap_[identifier] = autoLaunchItem; + extItemMap_[identifier][userId] = autoLaunchItem; } int errCode = OpenOneConnection(autoLaunchItem); LOGI("[AutoLaunch] AutoLaunchExtTask GetOneConnection errCode:%d", errCode); if (autoLaunchItem.conn == nullptr) { std::lock_guard autoLock(extLock_); - extItemMap_.erase(identifier); + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } return; } @@ -770,28 +859,32 @@ void AutoLaunch::AutoLaunchExtTask(const std::string identifier, AutoLaunchItem LOGE("[AutoLaunch] AutoLaunchExtTask RegisterObserverAndLifeCycleCallback failed"); TryCloseConnection(autoLaunchItem); // if here failed, do nothing std::lock_guard autoLock(extLock_); - extItemMap_.erase(identifier); + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } return; } std::lock_guard autoLock(extLock_); - extItemMap_[identifier].conn = autoLaunchItem.conn; - extItemMap_[identifier].observerHandle = autoLaunchItem.observerHandle; - extItemMap_[identifier].isWriteOpenNotifiered = false; + extItemMap_[identifier][userId].conn = autoLaunchItem.conn; + extItemMap_[identifier][userId].observerHandle = autoLaunchItem.observerHandle; + extItemMap_[identifier][userId].isWriteOpenNotifiered = false; LOGI("[AutoLaunch] AutoLaunchExtTask ok"); } -void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier) +void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier, + const std::string &userId) { - LOGD("[AutoLaunch] ExtObserverFunc"); + LOGD("[AutoLaunch] ExtObserverFunc identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; AutoLaunchNotifier notifier; { std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) == 0) { + if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map"); return; } - autoLaunchItem = extItemMap_[identifier]; + autoLaunchItem = extItemMap_[identifier][userId]; } if (autoLaunchItem.observer != nullptr) { LOGD("[AutoLaunch] do user observer"); @@ -801,16 +894,16 @@ void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const s { std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) != 0 && !extItemMap_[identifier].isWriteOpenNotifiered && + if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0 && + !extItemMap_[identifier][userId].isWriteOpenNotifiered && autoLaunchItem.notifier != nullptr) { - extItemMap_[identifier].isWriteOpenNotifiered = true; + extItemMap_[identifier][userId].isWriteOpenNotifiered = true; notifier = autoLaunchItem.notifier; } else { return; } } - std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::USER_ID, ""); std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::APP_ID, ""); std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::STORE_ID, ""); int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] { @@ -822,28 +915,31 @@ void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const s } } -void AutoLaunch::ExtConnectionLifeCycleCallback(const std::string &identifier) +void AutoLaunch::ExtConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId) { - LOGI("[AutoLaunch] ExtConnectionLifeCycleCallback"); + LOGI("[AutoLaunch] ExtConnectionLifeCycleCallback identifier=%0.6s", STR_TO_HEX(identifier)); int errCode = RuntimeContext::GetInstance()->ScheduleTask(std::bind( - &AutoLaunch::ExtConnectionLifeCycleCallbackTask, this, identifier)); + &AutoLaunch::ExtConnectionLifeCycleCallbackTask, this, identifier, userId)); if (errCode != E_OK) { LOGE("[AutoLaunch] ExtConnectionLifeCycleCallback ScheduleTask failed"); } } -void AutoLaunch::ExtConnectionLifeCycleCallbackTask(const std::string &identifier) +void AutoLaunch::ExtConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId) { - LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask"); + LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier=%0.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; { std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) == 0) { + if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { LOGE("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier is not exist!"); return; } - autoLaunchItem = extItemMap_[identifier]; - extItemMap_.erase(identifier); + autoLaunchItem = extItemMap_[identifier][userId]; + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } } LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask do CloseConnection"); TryCloseConnection(autoLaunchItem); // do nothing if failed @@ -859,7 +955,7 @@ int AutoLaunch::SetConflictNotifier(AutoLaunchItem &autoLaunchItem) return E_OK; } - IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); + IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); int conflictType = autoLaunchItem.conflictType; const KvStoreNbConflictNotifier ¬ifier = autoLaunchItem.conflictNotifier; if (conflictType == 0) { @@ -948,6 +1044,7 @@ int AutoLaunch::GetAutoLaunchKVProperties(const AutoLaunchParam ¶m, propertiesPtr->SetIntProp(KvDBProperties::COMPRESSION_RATE, ParamCheckUtils::GetValidCompressionRate(param.option.compressionRate)); } + propertiesPtr->SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, param.option.syncDualTupleMode); DBCommon::SetDatabaseIds(*propertiesPtr, param.appId, param.userId, param.storeId); return E_OK; } @@ -1030,18 +1127,18 @@ int AutoLaunch::RegisterLifeCycleCallback(AutoLaunchItem &autoLaunchItem, const DatabaseLifeCycleNotifier notifier; if (isExt) { notifier = std::bind( - &AutoLaunch::ExtConnectionLifeCycleCallback, this, std::placeholders::_1); + &AutoLaunch::ExtConnectionLifeCycleCallback, this, std::placeholders::_1, std::placeholders::_2); } else { notifier = std::bind(&AutoLaunch::ConnectionLifeCycleCallback, - this, std::placeholders::_1); + this, std::placeholders::_1, std::placeholders::_2); } switch (autoLaunchItem.type) { case DBType::DB_KV: - errCode = static_cast(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier); + errCode = static_cast(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier); break; case DBType::DB_RELATION: errCode = - static_cast(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier); + static_cast(autoLaunchItem.conn)->RegisterLifeCycleCallback(notifier); break; default: LOGD("[AutoLaunch] Unknown Type[%d]", autoLaunchItem.type); @@ -1076,7 +1173,7 @@ void AutoLaunch::TryCloseKvConnection(AutoLaunchItem &autoLaunchItem) LOGI("[AutoLaunch] TryCloseKvConnection conn is nullptr, do nothing"); return; } - IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); + IKvDBConnection *kvConn = static_cast(autoLaunchItem.conn); int errCode = kvConn->RegisterLifeCycleCallback(nullptr); if (errCode != E_OK) { LOGE("[AutoLaunch] TryCloseKvConnection RegisterLifeCycleCallback failed errCode:%d", errCode); @@ -1101,7 +1198,7 @@ void AutoLaunch::TryCloseRelationConnection(AutoLaunchItem &autoLaunchItem) LOGI("[AutoLaunch] TryCloseRelationConnection conn is nullptr, do nothing"); return; } - RelationalStoreConnection *rdbConn = static_cast(autoLaunchItem.conn); + RelationalStoreConnection *rdbConn = static_cast(autoLaunchItem.conn); int errCode = rdbConn->RegisterLifeCycleCallback(nullptr); if (errCode != E_OK) { LOGE("[AutoLaunch] TryCloseRelationConnection RegisterLifeCycleCallback failed errCode:%d", errCode); diff --git a/services/distributeddataservice/libs/distributeddb/common/src/db_ability.cpp b/services/distributeddataservice/libs/distributeddb/common/src/db_ability.cpp index 6473420fddc3313edb0cf532c40d4aa55f8933fd..673191fdcca0753ec532cc1e350894d961959cd0 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/db_ability.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/db_ability.cpp @@ -22,10 +22,10 @@ namespace DistributedDB { DbAbility::DbAbility() { - for (const auto &item : ABILITYBITS) { + for (const auto &item : SyncConfig::ABILITYBITS) { dbAbilityItemSet_.insert(item); } - dbAbility_.resize(ABILITYBITS.back().first + ABILITYBITS.back().second); + dbAbility_.resize(SyncConfig::ABILITYBITS.back().first + SyncConfig::ABILITYBITS.back().second); } DbAbility::DbAbility(const DbAbility &other) @@ -88,7 +88,7 @@ int DbAbility::DeSerialize(Parcel &parcel, DbAbility &curAbility) LOGE("[DbAbility][DeSerialize] buf length get failed."); return -E_LENGTH_ERROR; } - std::vector targetBuff(ABILITYBITS.back().first + ABILITYBITS.back().second); + std::vector targetBuff(SyncConfig::ABILITYBITS.back().first + SyncConfig::ABILITYBITS.back().second); uint32_t buffOffset = 0; uint32_t innerBuffOffset = 0; for (uint32_t pos = 0; pos < targetBuff.size() && pos < SERIALIZE_BIT_SIZE * dstBuf.size(); pos++) { diff --git a/services/distributeddataservice/libs/distributeddb/common/src/db_common.cpp b/services/distributeddataservice/libs/distributeddb/common/src/db_common.cpp index 80847f13bd16132bd92ee49f51d2f78a26717267..3e94f5ae2990e3e92fcad830d76b1655926ca20f 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/db_common.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/db_common.cpp @@ -287,6 +287,11 @@ std::string DBCommon::GenerateIdentifierId(const std::string &storeId, return userId + "-" + appId + "-" + storeId; } +std::string DBCommon::GenerateDualTupleIdentifierId(const std::string &storeId, const std::string &appId) +{ + return appId + "-" + storeId; +} + void DBCommon::SetDatabaseIds(KvDBProperties &properties, const std::string &appId, const std::string &userId, const std::string &storeId) { diff --git a/services/distributeddataservice/libs/distributeddb/common/src/lock_status_observer.cpp b/services/distributeddataservice/libs/distributeddb/common/src/lock_status_observer.cpp index dc707d71f9b80b3f7ce4652587e08a20bed1b751..81cf0c66feb30b3e97905818f94d7439848b5c7c 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/lock_status_observer.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/lock_status_observer.cpp @@ -95,7 +95,6 @@ NotificationChain::Listener *LockStatusObserver::RegisterLockStatusChangedLister errCode = -E_INVALID_ARGS; return nullptr; } - return lockStatusChangedNotifier_->RegisterListener(LOCK_STATUS_CHANGE_EVENT, action, nullptr, errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/common/src/param_check_utils.cpp b/services/distributeddataservice/libs/distributeddb/common/src/param_check_utils.cpp index 98024f3bb83622223975b271ca9bfaa16355991e..e9ad559b0cb222cbc927461ae24e849a6008c338 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/param_check_utils.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/param_check_utils.cpp @@ -53,19 +53,27 @@ bool ParamCheckUtils::IsStoreIdSafe(const std::string &storeId) } bool ParamCheckUtils::CheckStoreParameter(const std::string &storeId, const std::string &appId, - const std::string &userId) + const std::string &userId, bool isIgnoreUserIdCheck) { if (!IsStoreIdSafe(storeId)) { return false; } - if (userId.empty() || userId.length() > DBConstant::MAX_USER_ID_LENGTH || - appId.empty() || appId.length() > DBConstant::MAX_APP_ID_LENGTH) { - LOGE("Invalid user or app info[%zu][%zu]", userId.length(), appId.length()); + if (!isIgnoreUserIdCheck) { + if (userId.empty() || userId.length() > DBConstant::MAX_USER_ID_LENGTH) { + LOGE("Invalid user info[%zu][%zu]", userId.length(), appId.length()); + return false; + } + if (userId.find(DBConstant::ID_CONNECTOR) != std::string::npos) { + LOGE("Invalid userId character in the store para info."); + return false; + } + } + if (appId.empty() || appId.length() > DBConstant::MAX_APP_ID_LENGTH) { + LOGE("Invalid app info[%zu][%zu]", userId.length(), appId.length()); return false; } - if ((userId.find(DBConstant::ID_CONNECTOR) != std::string::npos) || - (appId.find(DBConstant::ID_CONNECTOR) != std::string::npos) || + if ((appId.find(DBConstant::ID_CONNECTOR) != std::string::npos) || (storeId.find(DBConstant::ID_CONNECTOR) != std::string::npos)) { LOGE("Invalid character in the store para info."); return false; diff --git a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp index c98e3ebc0b364acc3b2c2cad75139006d2225aa1..7f4db0870ba378159a3bbbc472d2b202632fb2cd 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp @@ -163,33 +163,33 @@ const std::map &TableInfo::GetFields() const return fields_; } -const std::vector &TableInfo::GetFieldNames() const +const std::vector &TableInfo::GetFieldInfos() const { - if (!fieldNames_.empty() && fieldNames_.size() == fields_.size()) { - return fieldNames_; + if (!fieldInfos_.empty() && fieldInfos_.size() == fields_.size()) { + return fieldInfos_; } - fieldNames_.resize(fields_.size()); - if (fieldNames_.size() != fields_.size()) { + fieldInfos_.resize(fields_.size()); + if (fieldInfos_.size() != fields_.size()) { LOGE("GetField error, alloc memory failed."); - return fieldNames_; + return fieldInfos_; } - for (const auto &[fieldName, fieldInfo] : fields_) { - if (fieldInfo.GetColumnId() >= fieldNames_.size()) { + for (const auto &entry : fields_) { + if (static_cast(entry.second.GetColumnId()) >= fieldInfos_.size()) { LOGE("Cid is over field size."); - fieldNames_.clear(); - return fieldNames_; + fieldInfos_.clear(); + return fieldInfos_; } - fieldNames_.at(fieldInfo.GetColumnId()) = fieldName; + fieldInfos_.at(entry.second.GetColumnId()) = entry.second; } - return fieldNames_; + return fieldInfos_; } std::string TableInfo::GetFieldName(uint32_t cid) const { - if (cid >= fields_.size() || GetFieldNames().empty()) { + if (cid >= fields_.size() || GetFieldInfos().empty()) { return {}; } - return GetFieldNames().at(cid); + return GetFieldInfos().at(cid).GetFieldName(); } bool TableInfo::IsValid() const diff --git a/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.cpp b/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.cpp index 10ab3e063a2f92b3e24b3e037e0a5b2f4d6c4e32..492b09cf56573771dd8fca4878f3c1b9c80a36fb 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -54,6 +54,7 @@ RuntimeContextImpl::~RuntimeContextImpl() systemApiAdapter_ = nullptr; delete lockStatusObserver_; lockStatusObserver_ = nullptr; + userChangeMonitor_ = nullptr; } // Set the label of this process. @@ -129,6 +130,15 @@ void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAg autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_); } +int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget) +{ + std::lock_guard autoLock(communicatorLock_); + if (communicatorAggregator_ != nullptr) { + return communicatorAggregator_->GetLocalIdentity(outTarget); + } + return -E_NOT_INIT; +} + // Add and start a timer. int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action, const TimerFinalizer &finalizer, TimerId &timerId) @@ -387,9 +397,10 @@ int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option); } -int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &identifier) +int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier, + const std::string &dualTupleIdentifier, const std::string &userId) { - return autoLaunch_.DisableKvStoreAutoLaunch(identifier); + return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId); } void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier, @@ -594,4 +605,53 @@ void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, c } }); } + +int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback) +{ + std::unique_lock writeLock(syncActivationCheckCallbackMutex_); + syncActivationCheckCallback_ = callback; + LOGI("SetSyncActivationCheckCallback ok"); + return E_OK; +} + +bool RuntimeContextImpl::IsSyncerNeedActive(std::string &userId, std::string &appId, std::string &storeId) const +{ + std::shared_lock autoLock(syncActivationCheckCallbackMutex_); + if (syncActivationCheckCallback_) { + return syncActivationCheckCallback_(userId, appId, storeId); + } + return true; +} + +NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListerner(const UserChangedAction &action, + EventType event) +{ + int errCode; + std::lock_guard autoLock(userChangeMonitorLock_); + if (userChangeMonitor_ == nullptr) { + userChangeMonitor_ = std::make_unique(); + errCode = userChangeMonitor_->Start(); + if (errCode != E_OK) { + LOGE("UserChangeMonitor start failed!"); + userChangeMonitor_ = nullptr; + return nullptr; + } + } + NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListerner(action, event, errCode); + if ((listener == nullptr) || (errCode != E_OK)) { + LOGE("Register user status changed listener failed, err = %d", errCode); + return nullptr; + } + return listener; +} + +int RuntimeContextImpl::NotifyUserChanged() const +{ + if (userChangeMonitor_ == nullptr) { + LOGD("userChangeMonitor is null, all db is in normal synd mode"); + return E_OK; + } + userChangeMonitor_->NotifyUserChanged(); + return E_OK; +} } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.h b/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.h index ac645528d3f1abf3d5c59d35cbc88f8bb6f3115f..4bc90b2dacccb669bf9f16867f1127767b64b805 100755 --- a/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.h +++ b/services/distributeddataservice/libs/distributeddb/common/src/runtime_context_impl.h @@ -28,6 +28,7 @@ #include "time_tick_monitor.h" #include "icommunicator_aggregator.h" #include "auto_launch.h" +#include "user_change_monitor.h" namespace DistributedDB { class RuntimeContextImpl final : public RuntimeContext { @@ -41,7 +42,7 @@ public: int SetCommunicatorAdapter(IAdapter *adapter) override; int GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator) override; void SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator) override; - + int GetLocalIdentity(std::string &outTarget) override; // Add and start a timer. int SetTimer(int milliSeconds, const TimerAction &action, const TimerFinalizer &finalizer, TimerId &timerId) override; @@ -72,7 +73,8 @@ public: int EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier, const AutoLaunchOption &option) override; - int DisableKvStoreAutoLaunch(const std::string &identifier) override; + int DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier, + const std::string &userId) override; void GetAutoLaunchSyncDevices(const std::string &identifier, std::vector &devices) const override; @@ -102,6 +104,15 @@ public: void NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, bool onlineStatus) override; + int SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback) override; + + bool IsSyncerNeedActive(std::string &userId, std::string &appId, std::string &storeId) const override; + + // Register a user changed lister, it will be callback when user change. + NotificationChain::Listener *RegisterUserChangedListerner(const UserChangedAction &action, + EventType event) override; + // Notify TIME_CHANGE_EVENT. + int NotifyUserChanged() const override; private: static constexpr int MAX_TP_THREADS = 10; // max threads of the task pool. static constexpr int MIN_TP_THREADS = 1; // min threads of the task pool. @@ -150,6 +161,12 @@ private: mutable std::shared_mutex databaseStatusCallbackMutex_{}; StoreStatusNotifier databaseStatusNotifyCallback_; + + mutable std::shared_mutex syncActivationCheckCallbackMutex_{}; + SyncActivationCheckCallback syncActivationCheckCallback_; + + mutable std::mutex userChangeMonitorLock_; + std::unique_ptr userChangeMonitor_; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/common/src/user_change_monitor.cpp b/services/distributeddataservice/libs/distributeddb/common/src/user_change_monitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6add9c4d487da452396156e8ab20fcf72e4f4491 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/common/src/user_change_monitor.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "user_change_monitor.h" + +#include "db_errno.h" +#include "log_print.h" + +namespace DistributedDB { +UserChangeMonitor::UserChangeMonitor() + : userNotifier_(nullptr), + isStarted_(false) +{ +} + +UserChangeMonitor::~UserChangeMonitor() +{ + Stop(); +} + +int UserChangeMonitor::Start() +{ + if (isStarted_) { + return E_OK; + } + + int errCode = PrepareNotifierChain(); + if (errCode != E_OK) { + return errCode; + } + isStarted_ = true; + return E_OK; +} + +void UserChangeMonitor::Stop() +{ + if (!isStarted_) { + return; + } + if (userNotifier_ == nullptr) { + userNotifier_->UnRegisterEventType(USER_ACTIVE_EVENT); + userNotifier_->UnRegisterEventType(USER_NON_ACTIVE_EVENT); + userNotifier_->UnRegisterEventType(USER_ACTIVE_TO_NON_ACTIVE_EVENT); + RefObject::KillAndDecObjRef(userNotifier_); + userNotifier_ = nullptr; + } + isStarted_ = false; +} + +NotificationChain::Listener *UserChangeMonitor::RegisterUserChangedListerner(const UserChangedAction &action, + EventType event, int &errCode) +{ + std::shared_lock lockGuard(userChangeMonitorLock_); + if (action == nullptr) { + errCode = -E_INVALID_ARGS; + return nullptr; + } + if (userNotifier_ == nullptr) { + errCode = -E_NOT_INIT; + return nullptr; + } + LOGI("[UserChangeMonitor] RegisterUserChangedListerner event=%d", event); + return userNotifier_->RegisterListener(event, action, nullptr, errCode); +} + +int UserChangeMonitor::PrepareNotifierChain() +{ + int errCode = E_OK; + std::unique_lock lockGuard(userChangeMonitorLock_); + if (userNotifier_ != nullptr) { + return E_OK; + } + if (userNotifier_ == nullptr) { + userNotifier_ = new (std::nothrow) NotificationChain(); + if (userNotifier_ == nullptr) { + return -E_OUT_OF_MEMORY; + } + errCode = userNotifier_->RegisterEventType(USER_ACTIVE_EVENT); + if (errCode != E_OK) { + RefObject::KillAndDecObjRef(userNotifier_); + userNotifier_ = nullptr; + return errCode; + } + errCode = userNotifier_->RegisterEventType(USER_NON_ACTIVE_EVENT); + if (errCode != E_OK) { + RefObject::KillAndDecObjRef(userNotifier_); + userNotifier_ = nullptr; + return errCode; + } + errCode = userNotifier_->RegisterEventType(USER_ACTIVE_TO_NON_ACTIVE_EVENT); + if (errCode != E_OK) { + RefObject::KillAndDecObjRef(userNotifier_); + userNotifier_ = nullptr; + return errCode; + } + } + return errCode; +} + +void UserChangeMonitor::NotifyUserChanged() const +{ + std::shared_lock lockGuard(userChangeMonitorLock_); + if (userNotifier_ == nullptr) { + LOGD("NotifyUNotifyUserChangedserChange fail, userChangedNotifier is null."); + return; + } + LOGI("[UserChangeMonitor] begin to notify event"); + userNotifier_->NotifyEvent(USER_ACTIVE_EVENT, nullptr); + userNotifier_->NotifyEvent(USER_NON_ACTIVE_EVENT, nullptr); + userNotifier_->NotifyEvent(USER_ACTIVE_TO_NON_ACTIVE_EVENT, nullptr); +} +} // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/communicator/include/communicator_aggregator.h b/services/distributeddataservice/libs/distributeddb/communicator/include/communicator_aggregator.h index ae308a7b6d5037b282748d4d10bc6be6f0ecde7f..30ca55f93cf29aecb48df41b115b33eca8e391ac 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/include/communicator_aggregator.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/include/communicator_aggregator.h @@ -75,7 +75,7 @@ public: uint32_t GetCommunicatorAggregatorTimeout() const; uint32_t GetCommunicatorAggregatorTimeout(const std::string &target) const; bool IsDeviceOnline(const std::string &device) const; - int GetLocalIdentity(std::string &outTarget) const; + int GetLocalIdentity(std::string &outTarget) const override; // Get the protocol version of remote target. Return -E_NOT_FOUND if no record. int GetRemoteCommunicatorVersion(const std::string &target, uint16_t &outVersion) const; @@ -89,28 +89,32 @@ public: static void EnableCommunicatorNotFoundFeedback(bool isEnable); + std::shared_ptr GetExtendHeaderHandle(const ExtendInfo ¶mInfo); + private: // Working in a dedicated thread void SendDataRoutine(); void SendPacketsAndDisposeTask(const SendTask &inTask, - const std::vector> &eachPacket); + const std::vector>> &eachPacket); int RetryUntilTimeout(SendTask &inTask, uint32_t timeout, Priority inPrio); void TaskFinalizer(const SendTask &inTask, int result); void NotifySendableToAllCommunicator(); // Call from Adapter by register these function - void OnBytesReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length); + void OnBytesReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length, + const std::string &userId); void OnTargetChange(const std::string &target, bool isConnect); void OnSendable(const std::string &target); void OnFragmentReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length, - const ParseResult &inResult); + const ParseResult &inResult, const std::string &userId); int OnCommLayerFrameReceive(const std::string &srcTarget, const ParseResult &inResult); int OnAppLayerFrameReceive(const std::string &srcTarget, const uint8_t *bytes, - uint32_t length, const ParseResult &inResult); - int OnAppLayerFrameReceive(const std::string &srcTarget, SerialBuffer *&inFrameBuffer, const ParseResult &inResult); + uint32_t length, const ParseResult &inResult, const std::string &userId); + int OnAppLayerFrameReceive(const std::string &srcTarget, SerialBuffer *&inFrameBuffer, + const ParseResult &inResult, const std::string &userId); // Function with suffix NoMutex should be called with mutex in the caller int TryDeliverAppLayerFrameToCommunicatorNoMutex(const std::string &srcTarget, SerialBuffer *&inFrameBuffer, diff --git a/services/distributeddataservice/libs/distributeddb/communicator/include/iadapter.h b/services/distributeddataservice/libs/distributeddb/communicator/include/iadapter.h index c6d3b0078850501dd94b0134ec44ad7026b2225c..f238114ca4b16f8c80e900dfa7e09465bfe47c02 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/include/iadapter.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/include/iadapter.h @@ -19,11 +19,14 @@ #include #include #include +#include #include "communicator_type_define.h" +#include "iprocess_communicator.h" namespace DistributedDB { // SendableCallback only notify when status changed from unsendable to sendable -using BytesReceiveCallback = std::function; +using BytesReceiveCallback = std::function; using TargetChangeCallback = std::function; using SendableCallback = std::function; @@ -67,6 +70,8 @@ public: virtual bool IsDeviceOnline(const std::string &device) = 0; + virtual std::shared_ptr GetExtendHeaderHandle(const ExtendInfo ¶mInfo) = 0; + virtual ~IAdapter() {}; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator.h b/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator.h index a7e0500622ab9fae7f5f67f6a67d3ad047a3cdf1..9d23e31c15802a88a3b9428fce89a92e2014523c 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator.h @@ -21,10 +21,17 @@ #include "message.h" #include "ref_object.h" #include "communicator_type_define.h" +#include "iprocess_communicator.h" namespace DistributedDB { // inMsg is heap memory, its ownership transfers by calling OnMessageCallback using OnMessageCallback = std::function; +struct SendConfig { + bool nonBlock; + uint32_t timeout; + ExtendInfo paramInfo; + bool isNeedExtendHead = false; +}; class ICommunicator : public virtual RefObject { public: @@ -56,8 +63,8 @@ public: // If send fail in SendMessage, nonBlock true will return, nonBlock false will block and retry // timeout is ignore if nonBlock true. OnSendEnd won't always be called such as when in finalize stage. // Return 0 as success. Return negative as error - virtual int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) = 0; - virtual int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, + virtual int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) = 0; + virtual int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) = 0; // HW Code Regulation do not allow to use default parameters on virtual function virtual ~ICommunicator() {}; diff --git a/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator_aggregator.h b/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator_aggregator.h index 26c5a08dea2fbcec28e395bb248b72f0455ea4c1..ee5c59dfda2febf2acba05f9bc6a86cf63eaf89b 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator_aggregator.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/include/icommunicator_aggregator.h @@ -24,7 +24,7 @@ namespace DistributedDB { class ICommunicator; // Forward Declaration // Return E_OK to indicate to retain received frame. Do not block during callback. -using CommunicatorLackCallback = std::function; +using CommunicatorLackCallback = std::function; class ICommunicatorAggregator : public virtual RefObject { public: @@ -43,12 +43,10 @@ public: // If not success, return nullptr and set outErrorNo virtual ICommunicator *AllocCommunicator(uint64_t commLabel, int &outErrorNo) = 0; virtual ICommunicator *AllocCommunicator(const LabelType &commLabel, int &outErrorNo) = 0; - virtual void ReleaseCommunicator(ICommunicator *inCommunicator) = 0; - virtual int RegCommunicatorLackCallback(const CommunicatorLackCallback &onCommLack, const Finalizer &inOper) = 0; virtual int RegOnConnectCallback(const OnConnectCallback &onConnect, const Finalizer &inOper) = 0; - + virtual int GetLocalIdentity(std::string &outTarget) const = 0; virtual ~ICommunicatorAggregator() {}; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/communicator/include/network_adapter.h b/services/distributeddataservice/libs/distributeddb/communicator/include/network_adapter.h index 9954b651f153e88e65bd9ceb8bdc70a0a667a5c6..620814acb02c9c17d7ef4f4ea09cc8a00696014e 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/include/network_adapter.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/include/network_adapter.h @@ -51,6 +51,7 @@ public: int RegSendableCallback(const SendableCallback &onSendable, const Finalizer &inOper) override; bool IsDeviceOnline(const std::string &device) override; + std::shared_ptr GetExtendHeaderHandle(const ExtendInfo ¶mInfo) override; private: void OnDataReceiveHandler(const DeviceInfos &srcDevInfo, const uint8_t *data, uint32_t length); diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.cpp b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.cpp index b1b4e50090dc7d87fb1f5155aecc30cedd382364..0937ecb35da69b73e89342e4d05aff7f67b87aaa 100755 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.cpp +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.cpp @@ -95,21 +95,29 @@ bool Communicator::IsDeviceOnline(const std::string &device) const return commAggrHandle_->IsDeviceOnline(device); } -int Communicator::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) +int Communicator::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) { - return SendMessage(dstTarget, inMsg, nonBlock, timeout, nullptr); + return SendMessage(dstTarget, inMsg, config, nullptr); } -int Communicator::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, +int Communicator::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) { if (dstTarget.size() == 0 || inMsg == nullptr) { return -E_INVALID_ARGS; } - + std::shared_ptr extendHandle = nullptr; + if (config.isNeedExtendHead) { + extendHandle = commAggrHandle_->GetExtendHeaderHandle(config.paramInfo); + if (extendHandle == nullptr) { + LOGE("[Comm][Send] get extendHandle failed"); + return -E_FEEDBACK_COMMUNICATOR_NOT_FOUND; + } + } int error = E_OK; // if error is not E_OK , null pointer will be returned - SerialBuffer *buffer = ProtocolProto::ToSerialBuffer(inMsg, error); + SerialBuffer *buffer = ProtocolProto::ToSerialBuffer(inMsg, error, extendHandle, false); + extendHandle = nullptr; if (error != E_OK) { LOGE("[Comm][Send] Serial fail, label=%s, error=%d.", VEC_TO_STR(commLabel_), error); return error; @@ -122,8 +130,8 @@ int Communicator::SendMessage(const std::string &dstTarget, const Message *inMsg return errCode; } - TaskConfig config{nonBlock, timeout, inMsg->GetPriority()}; - errCode = commAggrHandle_->CreateSendTask(dstTarget, buffer, FrameType::APPLICATION_MESSAGE, config, onEnd); + TaskConfig taskConfig {config.nonBlock, config.timeout, inMsg->GetPriority()}; + errCode = commAggrHandle_->CreateSendTask(dstTarget, buffer, FrameType::APPLICATION_MESSAGE, taskConfig, onEnd); if (errCode == E_OK) { // if ok, free inMsg, otherwise the caller should take over inMsg delete inMsg; diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.h b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.h index f0e929e6f750d3adfcb77aea29d358245e912b49..17c8604e29c17e125f46ed416616cfa964510608 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator.h @@ -51,8 +51,8 @@ public: // Get the protocol version of remote target. Return -E_NOT_FOUND if no record. int GetRemoteCommunicatorVersion(const std::string &target, uint16_t &outVersion) const override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) override; + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) override; // Call by CommunicatorAggregator directly diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator_aggregator.cpp index cbd976f7c18ea36c146b4b6d4282e9748f7b75be..019153c6a824a7aca70f9ea2cf11daf5b0848f53 100755 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -356,8 +356,8 @@ void CommunicatorAggregator::SendDataRoutine() if (errCode != E_OK) { continue; // Not possible to happen } - - std::vector> piecePackets; + // + std::vector, uint32_t>> piecePackets; errCode = ProtocolProto::SplitFrameIntoPacketsIfNeed(taskToSend.buffer, adapterHandle_->GetMtuSize(taskToSend.dstTarget), piecePackets); if (errCode != E_OK) { @@ -365,14 +365,21 @@ void CommunicatorAggregator::SendDataRoutine() TaskFinalizer(taskToSend, errCode); continue; } - - std::vector> eachPacket; + // > + std::vector>> eachPacket; if (piecePackets.size() == 0) { // Case that no need to split a frame, just use original buffer as a packet - eachPacket.push_back(taskToSend.buffer->GetReadOnlyBytesForEntireBuffer()); + std::pair tmpEntry = taskToSend.buffer->GetReadOnlyBytesForEntireBuffer(); + std::pair> entry; + entry.first = tmpEntry.first - taskToSend.buffer->GetExtendHeadLength(); + entry.second.first = taskToSend.buffer->GetExtendHeadLength(); + entry.second.second = tmpEntry.second + entry.second.first; + eachPacket.push_back(entry); } else { for (auto &entry : piecePackets) { - eachPacket.push_back(std::make_pair(&(entry[0]), entry.size())); + std::pair> tmpEntry = {&(entry.first[0]), + {entry.second, entry.first.size()}}; + eachPacket.push_back(tmpEntry); } } @@ -381,15 +388,15 @@ void CommunicatorAggregator::SendDataRoutine() } void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, - const std::vector> &eachPacket) + const std::vector>> &eachPacket) { bool taskNeedFinalize = true; int errCode = E_OK; for (auto &entry : eachPacket) { - LOGI("[CommAggr][SendPackets] DoSendBytes, dstTarget=%s{private}, length=%u.", inTask.dstTarget.c_str(), - entry.second); - ProtocolProto::DisplayPacketInformation(entry.first, entry.second); // For debug, delete in the future - errCode = adapterHandle_->SendBytes(inTask.dstTarget, entry.first, entry.second); + LOGI("[CommAggr][SendPackets] DoSendBytes, dstTarget=%s{private}, extendHeadLength=%u, totalLength=%u.", + inTask.dstTarget.c_str(), entry.second.first, entry.second.second); + ProtocolProto::DisplayPacketInformation(entry.first + entry.second.first, entry.second.second); + errCode = adapterHandle_->SendBytes(inTask.dstTarget, entry.first, entry.second.second); if (errCode == -E_WAIT_RETRY) { LOGE("[CommAggr][SendPackets] SendBytes temporally fail."); scheduler_.DelayTaskByTarget(inTask.dstTarget); @@ -470,7 +477,8 @@ void CommunicatorAggregator::NotifySendableToAllCommunicator() } } -void CommunicatorAggregator::OnBytesReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length) +void CommunicatorAggregator::OnBytesReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length, + const std::string &userId) { ProtocolProto::DisplayPacketInformation(bytes, length); // For debug, delete in the future ParseResult packetResult; @@ -491,14 +499,14 @@ void CommunicatorAggregator::OnBytesReceive(const std::string &srcTarget, const } if (packetResult.IsFragment()) { - OnFragmentReceive(srcTarget, bytes, length, packetResult); + OnFragmentReceive(srcTarget, bytes, length, packetResult, userId); } else if (packetResult.GetFrameTypeInfo() != FrameType::APPLICATION_MESSAGE) { errCode = OnCommLayerFrameReceive(srcTarget, packetResult); if (errCode != E_OK) { LOGE("[CommAggr][Receive] CommLayer receive fail, errCode=%d.", errCode); } } else { - errCode = OnAppLayerFrameReceive(srcTarget, bytes, length, packetResult); + errCode = OnAppLayerFrameReceive(srcTarget, bytes, length, packetResult, userId); if (errCode != E_OK) { LOGE("[CommAggr][Receive] AppLayer receive fail, errCode=%d.", errCode); } @@ -557,7 +565,7 @@ void CommunicatorAggregator::OnSendable(const std::string &target) } void CommunicatorAggregator::OnFragmentReceive(const std::string &srcTarget, const uint8_t *bytes, uint32_t length, - const ParseResult &inResult) + const ParseResult &inResult, const std::string &userId) { int errorNo = E_OK; ParseResult frameResult; @@ -590,7 +598,7 @@ void CommunicatorAggregator::OnFragmentReceive(const std::string &srcTarget, con delete frameBuffer; frameBuffer = nullptr; } else { - errCode = OnAppLayerFrameReceive(srcTarget, frameBuffer, frameResult); + errCode = OnAppLayerFrameReceive(srcTarget, frameBuffer, frameResult, userId); if (errCode != E_OK) { LOGE("[CommAggr][Receive] AppLayer receive fail after combination, errCode=%d.", errCode); } @@ -636,7 +644,7 @@ int CommunicatorAggregator::OnCommLayerFrameReceive(const std::string &srcTarget } int CommunicatorAggregator::OnAppLayerFrameReceive(const std::string &srcTarget, const uint8_t *bytes, - uint32_t length, const ParseResult &inResult) + uint32_t length, const ParseResult &inResult, const std::string &userId) { SerialBuffer *buffer = new (std::nothrow) SerialBuffer(); if (buffer == nullptr) { @@ -651,7 +659,7 @@ int CommunicatorAggregator::OnAppLayerFrameReceive(const std::string &srcTarget, buffer = nullptr; return -E_INTERNAL_ERROR; } - return OnAppLayerFrameReceive(srcTarget, buffer, inResult); + return OnAppLayerFrameReceive(srcTarget, buffer, inResult, userId); } // In early time, we cover "OnAppLayerFrameReceive" totally by commMapMutex_, then search communicator, if not found, @@ -673,7 +681,7 @@ int CommunicatorAggregator::OnAppLayerFrameReceive(const std::string &srcTarget, // 3:Search communicator under commMapMutex_ again, if found then deliver frame to that communicator and end. // 4:If still not found, retain this frame if need or otherwise send CommunicatorNotFound feedback. int CommunicatorAggregator::OnAppLayerFrameReceive(const std::string &srcTarget, SerialBuffer *&inFrameBuffer, - const ParseResult &inResult) + const ParseResult &inResult, const std::string &userId) { LabelType toLabel = inResult.GetCommLabel(); { @@ -688,7 +696,7 @@ int CommunicatorAggregator::OnAppLayerFrameReceive(const std::string &srcTarget, { std::lock_guard onCommLackLockGuard(onCommLackMutex_); if (onCommLackHandle_) { - errCode = onCommLackHandle_(toLabel); + errCode = onCommLackHandle_(toLabel, userId); LOGI("[CommAggr][AppReceive] On CommLack End."); // Log in case callback block this thread } else { LOGI("[CommAggr][AppReceive] CommLackHandle invalid currently."); @@ -732,7 +740,7 @@ int CommunicatorAggregator::RegCallbackToAdapter() RefObject::IncObjRef(this); // Reference to be hold by adapter int errCode = adapterHandle_->RegBytesReceiveCallback( std::bind(&CommunicatorAggregator::OnBytesReceive, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), + std::placeholders::_3, std::placeholders::_4), [this]() { RefObject::DecObjRef(this); }); if (errCode != E_OK) { RefObject::DecObjRef(this); // Rollback in case reg failed @@ -868,5 +876,13 @@ void CommunicatorAggregator::SetRemoteCommunicatorVersion(const std::string &tar versionMap_[target] = version; } +std::shared_ptr CommunicatorAggregator::GetExtendHeaderHandle(const ExtendInfo ¶mInfo) +{ + if (adapterHandle_ == nullptr) { + return nullptr; + } + return adapterHandle_->GetExtendHeaderHandle(paramInfo); +} + DEFINE_OBJECT_TAG_FACILITIES(CommunicatorAggregator) } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/network_adapter.cpp b/services/distributeddataservice/libs/distributeddb/communicator/src/network_adapter.cpp index efb297927e176527daed2e5acfed15097cbf1e44..7862b8cdc4c771cac22543c602e7b9315e2f9dbc 100755 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/network_adapter.cpp @@ -250,14 +250,26 @@ void NetworkAdapter::OnDataReceiveHandler(const DeviceInfos &srcDevInfo, const u LOGE("[NAdapt][OnDataRecv] data nullptr or length = %u.", length); return; } - LOGI("[NAdapt][OnDataRecv] Enter, from=%s{private}, length=%u", srcDevInfo.identifier.c_str(), length); + uint32_t headLength = 0; + std::vector userId; + std::string currentUserId; + DBStatus errCode = processCommunicator_->CheckAndGetDataHeadInfo(data, length, headLength, userId); + LOGI("[NAdapt][OnDataRecv] Enter, from=%s{private}, extendHeadLength=%u, totalLength=%u", + srcDevInfo.identifier.c_str(), headLength, length); + if (errCode == NO_PERMISSION) { + LOGI("[NAdapt][OnDataRecv] userId dismatched, drop packet"); + return; + } { std::lock_guard onReceiveLockGard(onReceiveMutex_); if (!onReceiveHandle_) { LOGE("[NAdapt][OnDataRecv] onReceiveHandle invalid."); return; } - onReceiveHandle_(srcDevInfo.identifier, data, length); + if (userId.size() >= 1) { + currentUserId = userId[0]; + } + onReceiveHandle_(srcDevInfo.identifier, data + headLength, length - headLength, currentUserId); } // These code is compensation for the probable defect of IProcessCommunicator implementation. // As described in the agreement, for the missed online situation, we check the source dev when received. @@ -389,4 +401,9 @@ bool NetworkAdapter::IsDeviceOnline(const std::string &device) } return false; } + +std::shared_ptr NetworkAdapter::GetExtendHeaderHandle(const ExtendInfo ¶mInfo) +{ + return processCommunicator_->GetExtendHeaderHandle(paramInfo); +} } diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.cpp b/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.cpp index 73c99c0c1feb88a892fbdf6c1175ebb99e4f4842..e26ae3022a40566830a0727ef9e5111af19cf6e1 100755 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.cpp +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.cpp @@ -79,7 +79,8 @@ uint32_t ProtocolProto::GetCommLayerFrameHeaderLength() return length; } -SerialBuffer *ProtocolProto::ToSerialBuffer(const Message *inMsg, int &outErrorNo, bool onlyMsgHeader) +SerialBuffer *ProtocolProto::ToSerialBuffer(const Message *inMsg, int &outErrorNo, + std::shared_ptr &extendHandle, bool onlyMsgHeader) { if (inMsg == nullptr) { outErrorNo = -E_INVALID_ARGS; @@ -94,12 +95,29 @@ SerialBuffer *ProtocolProto::ToSerialBuffer(const Message *inMsg, int &outErrorN return nullptr; } } + uint32_t headSize = 0; + if (extendHandle != nullptr) { + DBStatus status = extendHandle->GetHeadDataSize(headSize); + if (status != DBStatus::OK) { + LOGI("[Proto][ToSerial] get head data size failed,not permit to send"); + outErrorNo = -E_FEEDBACK_COMMUNICATOR_NOT_FOUND; + return nullptr; + } + if (headSize > SerialBuffer::MAX_EXTEND_HEAD_LENGTH || headSize != BYTE_8_ALIGN(headSize)) { + LOGI("[Proto][ToSerial] head data size is larger than 512 or not 8 byte align"); + outErrorNo = -E_FEEDBACK_COMMUNICATOR_NOT_FOUND; + return nullptr; + } + } SerialBuffer *buffer = new (std::nothrow) SerialBuffer(); if (buffer == nullptr) { outErrorNo = -E_OUT_OF_MEMORY; return nullptr; } + if (headSize > 0) { + buffer->SetExtendHeadLength(headSize); + } // serializeLen maybe not 8-bytes aligned, let SerialBuffer deal with the padding. uint32_t payLoadLength = serializeLen + sizeof(MessageHeader); int errCode = buffer->AllocBufferByPayloadLength(payLoadLength, GetAppLayerFrameHeaderLength()); @@ -110,6 +128,15 @@ SerialBuffer *ProtocolProto::ToSerialBuffer(const Message *inMsg, int &outErrorN buffer = nullptr; return nullptr; } + if (extendHandle != nullptr && headSize > 0) { + DBStatus status = extendHandle->FillHeadData(buffer->GetOringinalAddr(), headSize, + buffer->GetSize() + headSize); + if (status != DBStatus::OK) { + LOGI("[Proto][ToSerial] fill head data failed"); + outErrorNo = -E_FEEDBACK_COMMUNICATOR_NOT_FOUND; + return nullptr; + } + } // Serialize the MessageHeader and data if need errCode = SerializeMessage(buffer, inMsg); @@ -172,7 +199,8 @@ SerialBuffer *ProtocolProto::BuildEmptyFrameForVersionNegotiate(int &outErrorNo) SerialBuffer *ProtocolProto::BuildFeedbackMessageFrame(const Message *inMsg, const LabelType &inLabel, int &outErrorNo) { - SerialBuffer *buffer = ToSerialBuffer(inMsg, outErrorNo, true); + std::shared_ptr extendHandle = nullptr; + SerialBuffer *buffer = ToSerialBuffer(inMsg, outErrorNo, extendHandle, true); if (buffer == nullptr) { // outErrorNo had already been set in ToSerialBuffer return nullptr; @@ -254,17 +282,18 @@ SerialBuffer *ProtocolProto::BuildLabelExchangeAck(uint64_t inDistinctValue, uin } int ProtocolProto::SplitFrameIntoPacketsIfNeed(const SerialBuffer *inBuff, uint32_t inMtuSize, - std::vector> &outPieces) + std::vector, uint32_t>> &outPieces) { auto bufferBytesLen = inBuff->GetReadOnlyBytesForEntireBuffer(); - if (bufferBytesLen.second <= inMtuSize) { + if ((bufferBytesLen.second + inBuff->GetExtendHeadLength()) <= inMtuSize) { return E_OK; } + uint32_t modifyMtuSize = inMtuSize - inBuff->GetExtendHeadLength(); // Do Fragmentaion! This function aims at calculate how many fragments to be split into. auto frameBytesLen = inBuff->GetReadOnlyBytesForEntireFrame(); // Padding not in the range of fragmentation. uint32_t lengthToSplit = frameBytesLen.second - sizeof(CommPhyHeader); // The former is always larger than latter. // The inMtuSize pass from CommunicatorAggregator is large enough to be subtract by the latter two. - uint32_t maxFragmentLen = inMtuSize - sizeof(CommPhyHeader) - sizeof(CommPhyOptHeader); + uint32_t maxFragmentLen = modifyMtuSize - sizeof(CommPhyHeader) - sizeof(CommPhyOptHeader); // It can be proved that lengthToSplit is always larger than maxFragmentLen, so quotient won't be zero. // The maxFragmentLen won't be zero and in fact large enough to make sure no precision loss during division uint16_t quotient = lengthToSplit / maxFragmentLen; @@ -273,9 +302,8 @@ int ProtocolProto::SplitFrameIntoPacketsIfNeed(const SerialBuffer *inBuff, uint3 uint16_t fragCount = ((remainder == 0) ? quotient : (quotient + 1)); // Get CommPhyHeader of this frame to be modified for each packets (Header in network endian) auto oriPhyHeader = reinterpret_cast(frameBytesLen.first); - int errCode = FrameFragmentation(frameBytesLen.first + sizeof(CommPhyHeader), lengthToSplit, - fragCount, *oriPhyHeader, outPieces); - return errCode; + FrameFragmentInfo fragInfo = {inBuff->GetOringinalAddr(), inBuff->GetExtendHeadLength(), lengthToSplit, fragCount}; + return FrameFragmentation(frameBytesLen.first + sizeof(CommPhyHeader), fragInfo, *oriPhyHeader, outPieces); } int ProtocolProto::AnalyzeSplitStructure(const ParseResult &inResult, uint32_t &outFragLen, uint32_t &outLastFragLen) @@ -349,6 +377,13 @@ int ProtocolProto::RegTransformFunction(uint32_t msgId, const TransformFunc &inF return E_OK; } +void ProtocolProto::UnRegTransformFunction(uint32_t msgId) +{ + if (msgIdMapFunc_.count(msgId) != 0) { + msgIdMapFunc_.erase(msgId); + } +} + int ProtocolProto::SetDivergeHeader(SerialBuffer *inBuff, const LabelType &inCommLabel) { if (inBuff == nullptr) { @@ -693,7 +728,7 @@ int ProtocolProto::ParseCommPhyHeaderCheckField(const std::string &srcTarget, co return -E_PARSE_FAIL; } if (phyHeader.packetLen != length) { - LOGE("[Proto][ParsePhyCheck] PacketLen=%u Mismatch.", phyHeader.packetLen); + LOGE("[Proto][ParsePhyCheck] PacketLen=%u Mismatch length=%u.", phyHeader.packetLen, length); return -E_PARSE_FAIL; } if (phyHeader.paddingLen > MAX_PADDING_LEN) { @@ -897,9 +932,11 @@ int ProtocolProto::ParseLabelExchangeAck(const uint8_t *bytes, uint32_t length, // Note: framePhyHeader is in network endian // This function aims at calculating and preparing each part of each packets -int ProtocolProto::FrameFragmentation(const uint8_t *splitStartBytes, uint32_t splitLength, uint16_t fragCount, - const CommPhyHeader &framePhyHeader, std::vector> &outPieces) +int ProtocolProto::FrameFragmentation(const uint8_t *splitStartBytes, const FrameFragmentInfo &fragmentInfo, + const CommPhyHeader &framePhyHeader, std::vector, uint32_t>> &outPieces) { + uint32_t splitLength = fragmentInfo.splitLength; + uint16_t fragCount = fragmentInfo.fragCount; // It can be guaranteed that fragCount >= 2 and also won't be too large if (fragCount < 2) { return -E_INVALID_ARGS; @@ -916,8 +953,8 @@ int ProtocolProto::FrameFragmentation(const uint8_t *splitStartBytes, uint32_t s uint32_t pieceTotalLen = alignedPieceFragLen + sizeof(CommPhyHeader) + sizeof(CommPhyOptHeader); // Since exception is disabled, we have to check the vector size to assure that memory is truly allocated - entry.resize(pieceTotalLen); // Note: should use resize other than reserve - if (entry.size() != pieceTotalLen) { + entry.first.resize(pieceTotalLen + fragmentInfo.extendHeadSize); // Note: should use resize other than reserve + if (entry.first.size() != (pieceTotalLen + fragmentInfo.extendHeadSize)) { LOGE("[Proto][FrameFrag] Resize failed for length=%u", pieceTotalLen); return -E_OUT_OF_MEMORY; } @@ -935,12 +972,25 @@ int ProtocolProto::FrameFragmentation(const uint8_t *splitStartBytes, uint32_t s pktPhyOptHeader.fragCount = fragCount; pktPhyOptHeader.fragNo = fragNo; HeaderConverter::ConvertHostToNet(pktPhyOptHeader, pktPhyOptHeader); - - int errCode = FillFragmentPacket(pktPhyHeader, pktPhyOptHeader, splitStartBytes + byteOffset, - pieceFragLen, entry); - if (errCode != E_OK) { + int err; + FragmentPacket packet; + uint8_t *ptrPacket = &(entry.first[0]); + if (fragmentInfo.extendHeadSize > 0) { + packet = {ptrPacket, fragmentInfo.extendHeadSize}; + err = FillFragmentPacketExtendHead(fragmentInfo.oringinalBytesAddr, fragmentInfo.extendHeadSize, packet); + if (err != E_OK) { + LOGE("[Proto][FrameFrag] Fill extend head packet fail, fragCount=%u, fragNo=%u", fragCount, fragNo); + return err; + } + ptrPacket += fragmentInfo.extendHeadSize; + } + packet = {ptrPacket, static_cast(entry.first.size()) - fragmentInfo.extendHeadSize}; + err = FillFragmentPacket(pktPhyHeader, pktPhyOptHeader, splitStartBytes + byteOffset, + pieceFragLen, packet); + entry.second = fragmentInfo.extendHeadSize; + if (err != E_OK) { LOGE("[Proto][FrameFrag] Fill packet fail, fragCount=%u, fragNo=%u", fragCount, fragNo); - return errCode; + return err; } fragNo++; @@ -950,15 +1000,28 @@ int ProtocolProto::FrameFragmentation(const uint8_t *splitStartBytes, uint32_t s return E_OK; } +int ProtocolProto::FillFragmentPacketExtendHead(uint8_t *headBytesAddr, uint32_t headLen, FragmentPacket &outPacket) +{ + if (headLen > outPacket.leftLength) { + LOGE("[Proto][FrameFrag] headLen less than leftLength"); + return -E_INVALID_ARGS; + } + errno_t retCode = memcpy_s(outPacket.ptrPacket, outPacket.leftLength, headBytesAddr, headLen); + if (retCode != EOK) { + return -E_SECUREC_ERROR; + } + return E_OK; +} + // Note: phyHeader and phyOptHeader is in network endian int ProtocolProto::FillFragmentPacket(const CommPhyHeader &phyHeader, const CommPhyOptHeader &phyOptHeader, - const uint8_t *fragBytes, uint32_t fragLen, std::vector &outPacket) + const uint8_t *fragBytes, uint32_t fragLen, FragmentPacket &outPacket) { - if (outPacket.empty()) { + if (outPacket.leftLength == 0) { return -E_INVALID_ARGS; } - uint8_t *ptrPacket = &(outPacket[0]); - uint32_t leftLength = outPacket.size(); + uint8_t *ptrPacket = outPacket.ptrPacket; + uint32_t leftLength = outPacket.leftLength; // leftLength is guaranteed to be no smaller than the sum of phyHeaderLen + phyOptHeaderLen + fragLen // So, there will be no redundant check during subtraction @@ -983,12 +1046,12 @@ int ProtocolProto::FillFragmentPacket(const CommPhyHeader &phyHeader, const Comm // Calculate sum and set sum field uint64_t sumResult = 0; - int errCode = CalculateXorSum(&(outPacket[0]) + LENGTH_BEFORE_SUM_RANGE, - outPacket.size() - LENGTH_BEFORE_SUM_RANGE, sumResult); + int errCode = CalculateXorSum(outPacket.ptrPacket + LENGTH_BEFORE_SUM_RANGE, + outPacket.leftLength - LENGTH_BEFORE_SUM_RANGE, sumResult); if (errCode != E_OK) { return -E_SUM_CALCULATE_FAIL; } - auto ptrPhyHeader = reinterpret_cast(&(outPacket[0])); + auto ptrPhyHeader = reinterpret_cast(outPacket.ptrPacket); ptrPhyHeader->checkSum = HostToNet(sumResult); return E_OK; diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.h b/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.h index 0a1e6211b88b9c4a3e224e3f5ce82d94fd43ff0d..cb2ee6a0e7885e2ce697a2bd3484297defbccb8d 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/protocol_proto.h @@ -17,12 +17,14 @@ #define PROTOCOLPROTO_H #include +#include #include "message.h" #include "frame_header.h" #include "parse_result.h" #include "serial_buffer.h" #include "message_transform.h" #include "communicator_type_define.h" +#include "iprocess_communicator.h" namespace DistributedDB { struct PhyHeaderInfo { @@ -31,6 +33,18 @@ struct PhyHeaderInfo { FrameType frameType; }; +struct FrameFragmentInfo { + uint8_t *oringinalBytesAddr; + uint32_t extendHeadSize; + uint32_t splitLength; + uint16_t fragCount; +}; + +struct FragmentPacket { + uint8_t *ptrPacket; + uint32_t leftLength; +}; + class ProtocolProto { public: // For application layer frame @@ -41,7 +55,8 @@ public: static uint32_t GetCommLayerFrameHeaderLength(); // For handling application layer message. Return a heap object. - static SerialBuffer *ToSerialBuffer(const Message *inMsg, int &outErrorNo, bool onlyMsgHeader = false); + static SerialBuffer *ToSerialBuffer(const Message *inMsg, int &outErrorNo, + std::shared_ptr &extendHandle, bool onlyMsgHeader = false); static Message *ToMessage(const SerialBuffer *inBuff, int &outErrorNo, bool onlyMsgHeader = false); // For handling communication layer frame. Return a heap object. @@ -53,7 +68,7 @@ public: // Return E_OK if no error happened. outPieces.size equal zero means not split, in this case, use ori buff. static int SplitFrameIntoPacketsIfNeed(const SerialBuffer *inBuff, uint32_t inMtuSize, - std::vector> &outPieces); + std::vector, uint32_t>> &outPieces); static int AnalyzeSplitStructure(const ParseResult &inResult, uint32_t &outFragLen, uint32_t &outLastFragLen); // inFrame is the destination, pktBytes and pktLength are the source, fragOffset and fragLength give the boundary @@ -65,6 +80,8 @@ public: // Return E_INVALID_ARGS if member of inFunc not all valid static int RegTransformFunction(uint32_t msgId, const TransformFunc &inFunc); + static void UnRegTransformFunction(uint32_t msgId); + // For application layer frame. In send case. Focus on frame. static int SetDivergeHeader(SerialBuffer *inBuff, const LabelType &inCommLabel); @@ -104,10 +121,11 @@ private: static int ParseLabelExchange(const uint8_t *bytes, uint32_t length, ParseResult &inResult); static int ParseLabelExchangeAck(const uint8_t *bytes, uint32_t length, ParseResult &inResult); - static int FrameFragmentation(const uint8_t *splitStartBytes, uint32_t splitLength, uint16_t fragCount, - const CommPhyHeader &framePhyHeader, std::vector> &outPieces); + static int FrameFragmentation(const uint8_t *splitStartBytes, const FrameFragmentInfo &fragmentInfo, + const CommPhyHeader &framePhyHeader, std::vector, uint32_t>> &outPieces); static int FillFragmentPacket(const CommPhyHeader &phyHeader, const CommPhyOptHeader &phyOptHeader, - const uint8_t *fragBytes, uint32_t fragLen, std::vector &outPacket); + const uint8_t *fragBytes, uint32_t fragLen, FragmentPacket &outPacket); + static int FillFragmentPacketExtendHead(uint8_t *headBytesAddr, uint32_t headLen, FragmentPacket &outPacket); static std::map msgIdMapFunc_; }; diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.cpp b/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.cpp index 92cce786abb28a04a0f37d3ce2a98f1b8b825844..934ea3ec54d326b49a2b89c38a9bb417fb72fc48 100755 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.cpp +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.cpp @@ -18,21 +18,33 @@ #include "securec.h" #include "db_errno.h" #include "communicator_type_define.h" +#include "log_print.h" namespace DistributedDB { SerialBuffer::~SerialBuffer() { - if (!isExternalStackMemory_ && bytes_ != nullptr) { - delete[] bytes_; + if (!isExternalStackMemory_ && oringinalBytes_ != nullptr) { + delete[] oringinalBytes_; } + oringinalBytes_ = nullptr; bytes_ = nullptr; externalBytes_ = nullptr; } +void SerialBuffer::SetExtendHeadLength(uint32_t extendHeaderLen) +{ + extendHeadLen_ = extendHeaderLen; +} + +uint32_t SerialBuffer::GetExtendHeadLength() const +{ + return extendHeadLen_; +} + // In case buffer be directly send out, so padding is needed int SerialBuffer::AllocBufferByPayloadLength(uint32_t inPayloadLen, uint32_t inHeaderLen) { - if (bytes_ != nullptr || externalBytes_ != nullptr) { + if (oringinalBytes_ != nullptr || bytes_ != nullptr || externalBytes_ != nullptr) { return -E_NOT_PERMIT; } @@ -43,10 +55,11 @@ int SerialBuffer::AllocBufferByPayloadLength(uint32_t inPayloadLen, uint32_t inH if (totalLen_ == 0 || totalLen_ > MAX_TOTAL_LEN) { return -E_INVALID_ARGS; } - bytes_ = new (std::nothrow) uint8_t[totalLen_]; - if (bytes_ == nullptr) { + oringinalBytes_ = new (std::nothrow) uint8_t[totalLen_ + extendHeadLen_]; + if (oringinalBytes_ == nullptr) { return -E_OUT_OF_MEMORY; } + bytes_ = oringinalBytes_ + extendHeadLen_; return E_OK; } @@ -68,6 +81,7 @@ int SerialBuffer::AllocBufferByTotalLength(uint32_t inTotalLen, uint32_t inHeade if (bytes_ == nullptr) { return -E_OUT_OF_MEMORY; } + oringinalBytes_ = bytes_; return E_OK; } @@ -115,13 +129,14 @@ SerialBuffer *SerialBuffer::Clone(int &outErrorNo) return nullptr; } } - + twinBuffer->oringinalBytes_ = twinBuffer->bytes_; twinBuffer->externalBytes_ = externalBytes_; twinBuffer->totalLen_ = totalLen_; twinBuffer->headerLen_ = headerLen_; twinBuffer->payloadLen_ = payloadLen_; twinBuffer->paddingLen_ = paddingLen_; twinBuffer->isExternalStackMemory_ = isExternalStackMemory_; + twinBuffer->extendHeadLen_ = extendHeadLen_; outErrorNo = E_OK; return twinBuffer; } @@ -146,6 +161,8 @@ int SerialBuffer::ConvertForCrossThread() // Reset external related info externalBytes_ = nullptr; isExternalStackMemory_ = false; + oringinalBytes_ = bytes_; + extendHeadLen_ = 0; return E_OK; } @@ -157,6 +174,11 @@ uint32_t SerialBuffer::GetSize() const return totalLen_; } +uint8_t *SerialBuffer::GetOringinalAddr() const +{ + return oringinalBytes_; +} + std::pair SerialBuffer::GetWritableBytesForEntireBuffer() { if (bytes_ == nullptr) { diff --git a/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.h b/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.h index f343053dcdad22b7b6834ce633cc186bc42cbb19..01fb39a62dcb1115fe8b1261cdb6cf16dcfad64b 100644 --- a/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.h +++ b/services/distributeddataservice/libs/distributeddb/communicator/src/serial_buffer.h @@ -29,6 +29,9 @@ public: DISABLE_COPY_ASSIGN_MOVE(SerialBuffer); + // will call the func before alloc buff, calculate the head len which is used for data service + void SetExtendHeadLength(uint32_t extendHeaderLen); + uint32_t GetExtendHeadLength() const; // May be directly send out, so padding is needed int AllocBufferByPayloadLength(uint32_t inPayloadLen, uint32_t inHeaderLen); @@ -46,6 +49,8 @@ public: uint32_t GetSize() const; + uint8_t *GetOringinalAddr() const; + std::pair GetWritableBytesForEntireBuffer(); std::pair GetWritableBytesForEntireFrame(); std::pair GetWritableBytesForHeader(); @@ -55,13 +60,18 @@ public: std::pair GetReadOnlyBytesForEntireFrame() const; std::pair GetReadOnlyBytesForHeader() const; std::pair GetReadOnlyBytesForPayload() const; + + static const uint32_t MAX_EXTEND_HEAD_LENGTH = 512; private: - uint8_t *bytes_ = nullptr; + uint8_t *oringinalBytes_ = nullptr; // all beytes start addr + uint8_t *bytes_ = nullptr; // distributeddb start addr const uint8_t *externalBytes_ = nullptr; uint32_t totalLen_ = 0; uint32_t headerLen_ = 0; uint32_t payloadLen_ = 0; uint32_t paddingLen_ = 0; + // only apply message will use extend header + uint32_t extendHeadLen_ = 0; bool isExternalStackMemory_ = false; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/include/auto_launch_export.h b/services/distributeddataservice/libs/distributeddb/include/auto_launch_export.h index 5001a858678125864fe8422433c777518f6c5667..7a1b86ce760258ec9ab21b483dcc178a64ab9fc6 100755 --- a/services/distributeddataservice/libs/distributeddb/include/auto_launch_export.h +++ b/services/distributeddataservice/libs/distributeddb/include/auto_launch_export.h @@ -40,6 +40,7 @@ struct AutoLaunchOption { uint8_t compressionRate = 100; // valid in [1, 100]. bool isAutoSync = true; StoreObserver *storeObserver = nullptr; + bool syncDualTupleMode = false; // communicator label use dualTuple hash or not }; struct AutoLaunchParam { diff --git a/services/distributeddataservice/libs/distributeddb/include/types_export.h b/services/distributeddataservice/libs/distributeddb/include/types_export.h index 97687358a762008594a89e0f05923dc63b9a6a05..b084156c10698f787cf943a95423a6404e7edf62 100755 --- a/services/distributeddataservice/libs/distributeddb/include/types_export.h +++ b/services/distributeddataservice/libs/distributeddb/include/types_export.h @@ -122,6 +122,9 @@ using PermissionCheckCallbackV2 = std::function; // status, 1: online, 0: offline +using SyncActivationCheckCallback = std::function; + enum AutoLaunchStatus { WRITE_OPENED = 1, WRITE_CLOSED = 2, diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/include/iprocess_communicator.h b/services/distributeddataservice/libs/distributeddb/interfaces/include/iprocess_communicator.h index f2dd6163c216e8a519232042999869237fa1b228..3c7017fca4643cf4437019550012e030210f33db 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/include/iprocess_communicator.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/include/iprocess_communicator.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "store_types.h" namespace DistributedDB { @@ -28,6 +29,34 @@ struct DeviceInfos { std::string identifier; // An unique and fixed identifier representing a device, such as UUID. }; +struct ExtendInfo { + std::string appId; + std::string storeId; + std::string userId; + std::string dstTarget; +}; + +class ExtendHeaderHandle { +public: + ExtendHeaderHandle() {}; + virtual ~ExtendHeaderHandle() {}; + // headSize should be 8 byte align + // return OK and headSize = 0 if no need to fill Head Data + // return OK and headSize > 0 if permit sync and will call FillHeadData + // return NO_PERMISSION if not permit sync + virtual DBStatus GetHeadDataSize(uint32_t &headSize) + { + headSize = 0; + return OK; + }; + // return OK if fill data ok + // return not OK if fill data failed + virtual DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) + { + return OK; + }; +}; + // In OnDeviceChange, all field of devInfo should be valid, isOnline true for online and false for offline. // The concept of online or offline: // 1: Can be at the physical device level, which means the remote device can be visible and communicable by local device @@ -113,6 +142,21 @@ public: } return GetTimeout(); } + + virtual std::shared_ptr GetExtendHeaderHandle(const ExtendInfo ¶mInfo) + { + return nullptr; + } + // called after OnDataReceive + // return NO_PERMISSION while no need to handle the dataBuff if remote device userId is not mate with local userId + // return INVALID_FORMAT and headLength = 0 if data service can not deSerialize the buff + // return OK if deSerialize ok and get HeadLength/localUserId successfully + virtual DBStatus CheckAndGetDataHeadInfo(const uint8_t *data, uint32_t totalLen, uint32_t &headLength, + std::vector &userId) + { + headLength = 0; + return OK; + } }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h b/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h index 16c5e1f095664ed112558757e6649a7688874c84..6615d08eed9c61b3684fefc4dc3b2de769d3b01a 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h @@ -98,12 +98,15 @@ public: DB_API static void SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback); DB_API static std::string GetKvStoreIdentifier(const std::string &userId, const std::string &appId, - const std::string &storeId); + const std::string &storeId, bool syncDualTupleMode = false); DB_API static DBStatus SetProcessSystemAPIAdapter(const std::shared_ptr &adapter); DB_API static void SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier); + DB_API static DBStatus SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback); + + DB_API static DBStatus NotifyUserChanged(); private: // Check if the dataDir is safe arg. diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h b/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h index 2215b370d4474b2ee3a507d143ceae1726c81ea8..5a15e46680c5aab25d838043d0a654fc3f07196b 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h @@ -53,6 +53,7 @@ public: bool isNeedRmCorruptedDb = false; bool isNeedCompressOnSync = false; uint8_t compressionRate = 100; // Valid in [1, 100]. + bool syncDualTupleMode = false; // communicator label use dualTuple hash or not }; DB_API virtual ~KvStoreNbDelegate() {} diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/include/store_types.h b/services/distributeddataservice/libs/distributeddb/interfaces/include/store_types.h index 2a121192a5bd3891555539f93ee07ac711acbf6c..1633151772f24a12c72e7c4c5da859b8a0152bb3 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/include/store_types.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/include/store_types.h @@ -57,8 +57,10 @@ enum DBStatus { SCHEMA_VIOLATE_VALUE, // Values already exist in dbFile do not match new schema INTERCEPT_DATA_FAIL, // Interceptor push data failed. LOG_OVER_LIMITS, // Log size is over the limits. - DISTRIBUTED_SCHEMA_NOT_FOUND, // the sync table is not a distributed table + DISTRIBUTED_SCHEMA_NOT_FOUND, // the sync table is not a relational table DISTRIBUTED_SCHEMA_CHANGED, // the schema was changed + MODE_MISMATCH, + NOT_ACTIVE, }; struct KvStoreConfig { diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp b/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp index 55ac9ad31e9c2f056903cd44d261fa068d8af9bb..6dff4d5e7ec2abd8483b4953a7e5ab1a676ff1b9 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp @@ -107,6 +107,7 @@ namespace { properties.SetIntProp(KvDBProperties::COMPRESSION_RATE, ParamCheckUtils::GetValidCompressionRate(option.compressionRate)); } + properties.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode); } bool CheckObserverConflictParam(const KvStoreNbDelegate::Option &option) @@ -552,7 +553,8 @@ DBStatus KvStoreDelegateManager::DisableKvStoreAutoLaunch(const std::string &use std::string syncIdentifier = DBCommon::GenerateIdentifierId(storeId, appId, userId); std::string hashIdentifier = DBCommon::TransferHashString(syncIdentifier); - int errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(hashIdentifier); + std::string dualIdentifier = DBCommon::TransferHashString(DBCommon::GenerateDualTupleIdentifierId(storeId, appId)); + int errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(hashIdentifier, dualIdentifier, userId); if (errCode != E_OK) { LOGE("[KvStoreManager] Disable auto launch failed:%d", errCode); return TransferDBErrno(errCode); @@ -567,11 +569,14 @@ void KvStoreDelegateManager::SetAutoLaunchRequestCallback(const AutoLaunchReques } std::string KvStoreDelegateManager::GetKvStoreIdentifier(const std::string &userId, const std::string &appId, - const std::string &storeId) + const std::string &storeId, bool syncDualTupleMode) { - if (!ParamCheckUtils::CheckStoreParameter(storeId, appId, userId)) { + if (!ParamCheckUtils::CheckStoreParameter(storeId, appId, userId, syncDualTupleMode)) { return ""; } + if (syncDualTupleMode) { + return DBCommon::TransferHashString(appId + "-" + storeId); + } return DBCommon::TransferHashString(userId + "-" + appId + "-" + storeId); } @@ -584,4 +589,16 @@ void KvStoreDelegateManager::SetStoreStatusNotifier(const StoreStatusNotifier &n { RuntimeContext::GetInstance()->SetStoreStatusNotifier(notifier); } + +DBStatus KvStoreDelegateManager::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback) +{ + int errCode = RuntimeContext::GetInstance()->SetSyncActivationCheckCallback(callback); + return TransferDBErrno(errCode); +} + +DBStatus KvStoreDelegateManager::NotifyUserChanged() +{ + int errCode = RuntimeContext::GetInstance()->NotifyUserChanged(); + return TransferDBErrno(errCode); +} } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_errno.cpp b/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_errno.cpp index 27ce5fb42ad7b670d17eeb27c6d194acfcaf6c31..a8aa97a481d107fa2adb05eaf4da4f8722ca245c 100755 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_errno.cpp +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/kv_store_errno.cpp @@ -55,6 +55,8 @@ namespace { { -E_LOG_OVER_LIMITS, LOG_OVER_LIMITS }, { -E_DISTRIBUTED_SCHEMA_NOT_FOUND, DISTRIBUTED_SCHEMA_NOT_FOUND}, { -E_DISTRIBUTED_SCHEMA_CHANGED, DISTRIBUTED_SCHEMA_CHANGED}, + { -E_MODE_MISMATCH, MODE_MISMATCH}, + { -E_NOT_INIT, NOT_ACTIVE}, }; } diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index 1d1aed7457860a3f00ccb8192240823a5d96f28d..cc526ccd9d5ced5c1b3cc6936023bc0d4115c702 100644 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -19,6 +19,7 @@ #include "kv_store_errno.h" #include "log_print.h" #include "param_check_utils.h" +#include "relational_store_instance.h" #include "sync_operation.h" namespace DistributedDB { @@ -107,7 +108,7 @@ DBStatus RelationalStoreDelegateImpl::Close() return OK; } - int errCode = conn_->Close(); + int errCode = RelationalStoreInstance::ReleaseDataBaseConnection(conn_); if (errCode == -E_BUSY) { LOGW("[RelationalStore Delegate] busy for close"); return BUSY; diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_instance.h b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_instance.h index 5c24c1f2cf1b0824b39352380a113e18b2721bfa..0bdc2aa93c1f0c9bec8163b136f871c4d1728a1c 100644 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_instance.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_instance.h @@ -31,6 +31,8 @@ public: static RelationalStoreConnection *GetDatabaseConnection(const RelationalDBProperties &properties, int &errCode); static RelationalStoreInstance *GetInstance(); + static int ReleaseDataBaseConnection(RelationalStoreConnection *connection); + int CheckDatabaseFileStatus(const std::string &id); // public for test mock @@ -42,11 +44,18 @@ private: void RemoveKvDBFromCache(const RelationalDBProperties &properties); void SaveKvDBToCache(IRelationalStore *store, const RelationalDBProperties &properties); + void EnterDBOpenCloseProcess(const std::string &identifier); + void ExitDBOpenCloseProcess(const std::string &identifier); + static RelationalStoreInstance *instance_; static std::mutex instanceLock_; std::string appId_; std::string userId_; + + std::mutex relationalDBOpenMutex_; + std::condition_variable relationalDBOpenCondition_; + std::set relationalDBOpenSet_; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index 2b207ebb881dc1c625790b2cf4cbfa333cbc8a52..408cf336a2decc0615c59f44d1f21ed65872c585 100644 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -98,7 +98,7 @@ DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const RelationalStoreChangedDataImpl data(changedDevice); data.SetStoreProperty({userId_, appId_, storeId}); if (option.observer) { - LOGD("begin to observer onchange, changedDevice=%s", STR_MASK(changedDevice)); + LOGD("begin to observer on changed, changedDevice=%s", STR_MASK(changedDevice)); option.observer->OnChange(data); } }); diff --git a/services/distributeddataservice/libs/distributeddb/storage/include/db_properties.h b/services/distributeddataservice/libs/distributeddb/storage/include/db_properties.h index 215745a8eda24467da1c35cb9622fc367753dce9..32b4d57724673415cf4500459ea7f0ffc029401b 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/include/db_properties.h +++ b/services/distributeddataservice/libs/distributeddb/storage/include/db_properties.h @@ -51,6 +51,8 @@ public: static const std::string STORE_ID; static const std::string IDENTIFIER_DATA; static const std::string IDENTIFIER_DIR; + static const std::string DUAL_TUPLE_IDENTIFIER_DATA; + static const std::string SYNC_DUAL_TUPLE_MODE; protected: DBProperties() = default; diff --git a/services/distributeddataservice/libs/distributeddb/storage/include/isync_interface.h b/services/distributeddataservice/libs/distributeddb/storage/include/isync_interface.h index a6925c11d8662d22abbf9ea7e98951fd1318b1f3..4b45ec91922e20079a596b61e7926a1ee67c6ffa 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/include/isync_interface.h +++ b/services/distributeddataservice/libs/distributeddb/storage/include/isync_interface.h @@ -45,6 +45,8 @@ public: // Get the identifier of this kvdb. virtual std::vector GetIdentifier() const = 0; + // Get the dual tuple identifier of this kvdb. + virtual std::vector GetDualTupleIdentifier() const = 0; // Get the max timestamp of all entries in database. virtual void GetMaxTimeStamp(TimeStamp &stamp) const = 0; diff --git a/services/distributeddataservice/libs/distributeddb/storage/include/sync_generic_interface.h b/services/distributeddataservice/libs/distributeddb/storage/include/sync_generic_interface.h index 600e1c3a84ff5b0e3dd87492d375279d22cc4c34..63ef884f3e139b5138c569724790c85606e29e9b 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/include/sync_generic_interface.h +++ b/services/distributeddataservice/libs/distributeddb/storage/include/sync_generic_interface.h @@ -139,6 +139,11 @@ public: { return false; } + + std::vector GetDualTupleIdentifier() const override + { + return {}; + } }; } #endif // SYNC_GENERIC_INTERFACE_H diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/data_transformer.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/data_transformer.cpp index b7336cc4274c504834615d2536928803807e44a4..657d5a8b4e605951afa1315765783c3b1d7289b8 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/data_transformer.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/data_transformer.cpp @@ -278,19 +278,36 @@ int DeSerializeTextValue(DataValue &dataValue, Parcel &parcel) return DeSerializeBlobByType(dataValue, parcel, StorageType::STORAGE_TYPE_TEXT); } -struct FunctionEntry { - std::function serializeFunc; - std::function deSerializeFunc; -}; +int SerializeDataValue(const DataValue &dataValue, Parcel &parcel) +{ + static const std::function funcs[] = { + SerializeNullValue, SerializeBoolValue, SerializeIntValue, + SerializeDoubleValue, SerializeTextValue, SerializeBlobValue, + }; + StorageType type = dataValue.GetType(); + parcel.WriteUInt32(static_cast(type)); + if (type < StorageType::STORAGE_TYPE_NULL || type > StorageType::STORAGE_TYPE_BLOB) { + LOGE("Cannot serialize %u", type); + return -E_NOT_SUPPORT; + } + return funcs[static_cast(type) - 1](dataValue, parcel); +} -std::map typeFuncMap = { - { StorageType::STORAGE_TYPE_NULL, {SerializeNullValue, DeSerializeNullValue}}, - { StorageType::STORAGE_TYPE_BOOL, {SerializeBoolValue, DeSerializeBoolValue}}, - { StorageType::STORAGE_TYPE_INTEGER, {SerializeIntValue, DeSerializeIntValue}}, - { StorageType::STORAGE_TYPE_REAL, {SerializeDoubleValue, DeSerializeDoubleValue}}, - { StorageType::STORAGE_TYPE_TEXT, {SerializeTextValue, DeSerializeTextValue}}, - { StorageType::STORAGE_TYPE_BLOB, {SerializeBlobValue, DeSerializeBlobValue}}, -}; +int DeserializeDataValue(DataValue &dataValue, Parcel &parcel) +{ + static const std::function funcs[] = { + DeSerializeNullValue, DeSerializeBoolValue, DeSerializeIntValue, + DeSerializeDoubleValue, DeSerializeTextValue, DeSerializeBlobValue, + }; + uint32_t type = 0; + parcel.ReadUInt32(type); + if (type < static_cast(StorageType::STORAGE_TYPE_NULL) || + type > static_cast(StorageType::STORAGE_TYPE_BLOB)) { + LOGE("Cannot deserialize %u", type); + return -E_PARSE_FAIL; + } + return funcs[type - 1](dataValue, parcel); +} } int DataTransformer::SerializeValue(Value &value, const RowData &rowData, const std::vector &fieldInfoList) @@ -303,9 +320,6 @@ int DataTransformer::SerializeValue(Value &value, const RowData &rowData, const uint32_t totalLength = Parcel::GetUInt64Len(); // first record field count for (uint32_t i = 0; i < rowData.size(); ++i) { const auto &dataValue = rowData[i]; - if (typeFuncMap.find(dataValue.GetType()) == typeFuncMap.end()) { - return -E_NOT_SUPPORT; - } totalLength += Parcel::GetUInt32Len(); // For save the dataValue's type. uint32_t dataLength = CalDataValueLength(dataValue); totalLength += dataLength; @@ -317,9 +331,7 @@ int DataTransformer::SerializeValue(Value &value, const RowData &rowData, const Parcel parcel(value.data(), value.size()); (void)parcel.WriteUInt64(rowData.size()); for (const auto &dataValue : rowData) { - StorageType type = dataValue.GetType(); - parcel.WriteUInt32(static_cast(type)); - int errCode = typeFuncMap[type].serializeFunc(dataValue, parcel); + int errCode = SerializeDataValue(dataValue, parcel); if (errCode != E_OK) { value.clear(); return errCode; @@ -340,13 +352,7 @@ int DataTransformer::DeSerializeValue(const Value &value, OptRowData &optionalDa } for (size_t i = 0; i < fieldCount; ++i) { DataValue dataValue; - uint32_t type = 0; - parcel.ReadUInt32(type); - auto iter = typeFuncMap.find(static_cast(type)); - if (iter == typeFuncMap.end()) { - return -E_PARSE_FAIL; - } - int errCode = iter->second.deSerializeFunc(dataValue, parcel); + int errCode = DeserializeDataValue(dataValue, parcel); if (errCode != E_OK) { LOGD("[DataTransformer][DeSerializeValue] deSerialize failed"); return errCode; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/db_properties.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/db_properties.cpp index d6920dcc8cd16aa64f907a0f63f55e4626acfe58..86fd161bd81a96391195ee8c172817bea6c7e422 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/db_properties.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/db_properties.cpp @@ -25,6 +25,8 @@ const std::string DBProperties::APP_ID = "appId"; const std::string DBProperties::STORE_ID = "storeId"; const std::string DBProperties::IDENTIFIER_DATA = "identifier"; const std::string DBProperties::IDENTIFIER_DIR = "identifierDir"; +const std::string DBProperties::DUAL_TUPLE_IDENTIFIER_DATA = "dualTupleIdentifier"; +const std::string DBProperties::SYNC_DUAL_TUPLE_MODE = "syncDualTuple"; std::string DBProperties::GetStringProp(const std::string &name, const std::string &defaultValue) const { @@ -75,5 +77,7 @@ void DBProperties::SetIdentifier(const std::string &userId, const std::string &a SetStringProp(DBProperties::STORE_ID, storeId); std::string hashIdentifier = DBCommon::TransferHashString(DBCommon::GenerateIdentifierId(storeId, appId, userId)); SetStringProp(DBProperties::IDENTIFIER_DATA, hashIdentifier); + std::string dualIdentifier = DBCommon::TransferHashString(DBCommon::GenerateDualTupleIdentifierId(storeId, appId)); + SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, dualIdentifier); } } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/irelational_store.h b/services/distributeddataservice/libs/distributeddb/storage/src/irelational_store.h index 1340ca6d7833de3e15f5cb8ddb792c0d2863a79d..0d9fb968b70440dbaa86d5b1fb6d5418f5e398be 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/irelational_store.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/irelational_store.h @@ -39,6 +39,8 @@ public: virtual RelationalStoreConnection *GetDBConnection(int &errCode) = 0; virtual std::string GetStorePath() const = 0; + + virtual RelationalDBProperties GetProperties() const = 0; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/kvdb_manager.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/kvdb_manager.cpp index aeff440e5759025da83689a50f5a75df84fef33a..0814b865d96366f2e86e7aaef593d5fe3645fe33 100755 --- a/services/distributeddataservice/libs/distributeddb/storage/src/kvdb_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/kvdb_manager.cpp @@ -923,6 +923,12 @@ int KvDBManager::CheckKvDBProperties(const IKvDB *kvDB, const KvDBProperties &pr return -E_INVALID_ARGS; } + if (kvDB->GetMyProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false) != + properties.GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false)) { + LOGE("Different dual tuple sync mode"); + return -E_MODE_MISMATCH; + } + if (!CheckSecOptions(properties, kvDB->GetMyProperties())) { return -E_INVALID_ARGS; } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/relational_store_instance.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/relational_store_instance.cpp index 1f08bdb3d96114e7e50a19d9034a28462604563a..de1dedeb30c131803cd291375531860b72f434d5 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/relational_store_instance.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/relational_store_instance.cpp @@ -46,6 +46,26 @@ RelationalStoreInstance *RelationalStoreInstance::GetInstance() return instance_; } +int RelationalStoreInstance::ReleaseDataBaseConnection(RelationalStoreConnection *connection) +{ + if (connection == nullptr) { + return -E_INVALID_DB; + } + auto manager = RelationalStoreInstance::GetInstance(); + if (manager == nullptr) { + return -E_OUT_OF_MEMORY; + } + std::string identifier = connection->GetIdentifier(); + manager->EnterDBOpenCloseProcess(identifier); + int errCode = connection->Close(); + manager->ExitDBOpenCloseProcess(identifier); + + if (errCode != E_OK) { + LOGE("Release db connection failed. %d", errCode); + } + return errCode; +} + int RelationalStoreInstance::CheckDatabaseFileStatus(const std::string &id) { std::lock_guard lockGuard(storeLock_); @@ -150,27 +170,48 @@ RelationalStoreConnection *RelationalStoreInstance::GetDatabaseConnection(const { std::string identifier = properties.GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); LOGD("Begin to get [%s] database connection.", STR_MASK(DBCommon::TransferStringToHex(identifier))); + RelationalStoreInstance *manager = RelationalStoreInstance::GetInstance(); + manager->EnterDBOpenCloseProcess(properties.GetStringProp(DBProperties::IDENTIFIER_DATA, "")); + RelationalStoreConnection *connection = nullptr; + std::string canonicalDir; IRelationalStore *db = GetDataBase(properties, errCode); if (db == nullptr) { LOGE("Failed to open the db:%d", errCode); - return nullptr; + goto END; } - std::string canonicalDir = properties.GetStringProp(KvDBProperties::DATA_DIR, ""); + canonicalDir = properties.GetStringProp(KvDBProperties::DATA_DIR, ""); if (canonicalDir.empty() || canonicalDir != db->GetStorePath()) { LOGE("Failed to check store path, the input path does not match with cached store."); errCode = -E_INVALID_ARGS; - RefObject::DecObjRef(db); - return nullptr; + goto END; } - auto connection = db->GetDBConnection(errCode); + connection = db->GetDBConnection(errCode); if (connection == nullptr) { // not kill db, Other operations like import may be used concurrently LOGE("Failed to get the db connect for delegate:%d", errCode); } +END: RefObject::DecObjRef(db); // restore the reference increased by the cache. + manager->ExitDBOpenCloseProcess(properties.GetStringProp(DBProperties::IDENTIFIER_DATA, "")); return connection; } + +void RelationalStoreInstance::EnterDBOpenCloseProcess(const std::string &identifier) +{ + std::unique_lock lock(relationalDBOpenMutex_); + relationalDBOpenCondition_.wait(lock, [this, &identifier]() { + return this->relationalDBOpenSet_.count(identifier) == 0; + }); + (void)relationalDBOpenSet_.insert(identifier); +} + +void RelationalStoreInstance::ExitDBOpenCloseProcess(const std::string &identifier) +{ + std::unique_lock lock(relationalDBOpenMutex_); + (void)relationalDBOpenSet_.erase(identifier); + relationalDBOpenCondition_.notify_all(); +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 0fa7cdc93df70faa327e83e8cbcb7a2a9db04758..a96a60b07b4d5a720991dc2685b53d2aeae51e96 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -35,7 +35,7 @@ RelationalSyncAbleStorage::RelationalSyncAbleStorage(StorageEngine *engine) RelationalSyncAbleStorage::~RelationalSyncAbleStorage() {} -// Get interface type of this kvdb. +// Get interface type of this relational db. int RelationalSyncAbleStorage::GetInterfaceType() const { return SYNC_RELATION; @@ -335,7 +335,12 @@ int RelationalSyncAbleStorage::GetSyncDataNext(std::vector & if (!token->CheckValid()) { return -E_INVALID_ARGS; } - token->SetFieldNames(storageEngine_->GetSchemaRef().GetTable(token->GetQuery().GetTableName()).GetFieldNames()); + const auto fieldInfos = storageEngine_->GetSchemaRef().GetTable(token->GetQuery().GetTableName()).GetFieldInfos(); + std::vector fieldNames; + for (const auto &fieldInfo : fieldInfos) { + fieldNames.push_back(fieldInfo.GetFieldName()); + } + token->SetFieldNames(fieldNames); std::vector dataItems; int errCode = GetSyncDataForQuerySync(dataItems, token, dataSizeInfo); diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 779684d61ca9113128a712f00e88d675fee0cfbc..b50bc6bcc7ed7b10533224598c6ec577ce9a58dd 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -377,7 +377,7 @@ void SQLiteRelationalStore::RegisterObserverAction(const RelationalObserverActio storageEngine_->RegisterObserverAction(action); } -int SQLiteRelationalStore::StopLifeCycleTimer() const +int SQLiteRelationalStore::StopLifeCycleTimer() { auto runtimeCxt = RuntimeContext::GetInstance(); if (runtimeCxt == nullptr) { @@ -391,7 +391,7 @@ int SQLiteRelationalStore::StopLifeCycleTimer() const return E_OK; } -int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier ¬ifier) const +int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier ¬ifier) { auto runtimeCxt = RuntimeContext::GetInstance(); if (runtimeCxt == nullptr) { @@ -403,8 +403,10 @@ int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier & [this](TimerId id) -> int { std::lock_guard lock(lifeCycleMutex_); if (lifeCycleNotifier_) { + // normal identifier mode auto identifier = properties_.GetStringProp(DBProperties::IDENTIFIER_DATA, ""); - lifeCycleNotifier_(identifier); + auto userId = properties_.GetStringProp(DBProperties::USER_ID, ""); + lifeCycleNotifier_(identifier, userId); } return 0; }, @@ -456,7 +458,7 @@ int SQLiteRelationalStore::RegisterLifeCycleCallback(const DatabaseLifeCycleNoti return errCode; } -void SQLiteRelationalStore::HeartBeat() const +void SQLiteRelationalStore::HeartBeat() { std::lock_guard lock(lifeCycleMutex_); int errCode = ResetLifeCycleTimer(); @@ -465,7 +467,7 @@ void SQLiteRelationalStore::HeartBeat() const } } -int SQLiteRelationalStore::ResetLifeCycleTimer() const +int SQLiteRelationalStore::ResetLifeCycleTimer() { if (lifeTimerId_ == 0) { return E_OK; @@ -483,5 +485,10 @@ std::string SQLiteRelationalStore::GetStorePath() const { return properties_.GetStringProp(DBProperties::DATA_DIR, ""); } + +RelationalDBProperties SQLiteRelationalStore::GetProperties() const +{ + return properties_; +} } #endif \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h index 86245108531389da48e5377cd1cdbd19797ad92d..15933421ee93caa07a6380d6f15bccf0ab30996b 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h @@ -62,6 +62,8 @@ public: std::string GetStorePath() const override; + RelationalDBProperties GetProperties() const override; + private: void ReleaseResources(); @@ -75,10 +77,10 @@ private: int CleanDistributedDeviceTable(); - int StopLifeCycleTimer() const; - int StartLifeCycleTimer(const DatabaseLifeCycleNotifier ¬ifier) const; - void HeartBeat() const; - int ResetLifeCycleTimer() const; + int StopLifeCycleTimer(); + int StartLifeCycleTimer(const DatabaseLifeCycleNotifier ¬ifier); + void HeartBeat(); + int ResetLifeCycleTimer(); // use for sync Interactive std::unique_ptr syncAbleEngine_ = nullptr; // For storage operate sync function @@ -99,9 +101,9 @@ private: bool isInitialized_ = false; // lifeCycle - mutable std::mutex lifeCycleMutex_; - mutable DatabaseLifeCycleNotifier lifeCycleNotifier_; - mutable TimerId lifeTimerId_; + std::mutex lifeCycleMutex_; + DatabaseLifeCycleNotifier lifeCycleNotifier_; + TimerId lifeTimerId_; }; } // namespace DistributedDB #endif diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp index fe95c589ed94fa3cde9df6d194cd41dde42afe78..ff9965c3996b6570e432f4f0da2381a254ddc23f 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp @@ -50,7 +50,7 @@ int SQLiteRelationalStoreConnection::Close() std::string SQLiteRelationalStoreConnection::GetIdentifier() { - return std::string(); + return store_->GetProperties().GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, ""); } SQLiteSingleVerRelationalStorageExecutor *SQLiteRelationalStoreConnection::GetExecutor(bool isWrite, int &errCode) const diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp index 895434732a1e29e769d7cdeafa28962159adcf78..1b2427073f65194962853c86d6461119bcf833aa 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp @@ -754,7 +754,7 @@ std::string SqliteQueryHelper::GetFieldShape(const QueryObjNode &queryNode, cons { if (isRelationalQuery_) { // For relational query, $. prefix is not permitted, so need not extract json. Return directly will be OK. - return queryNode.fieldName + " "; + return "a." + queryNode.fieldName + " "; } return MapCastFuncSql(queryNode, accessStr); } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp index 797e9a93e1c22f4c1f79e3c0ab9e49e406cea350..257df72096bed198b832ab2636d02086045243db 100755 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp @@ -530,6 +530,13 @@ std::vector SQLiteSingleVerNaturalStore::GetIdentifier() const return identifierVect; } +std::vector SQLiteSingleVerNaturalStore::GetDualTupleIdentifier() const +{ + std::string identifier = MyProp().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + std::vector identifierVect(identifier.begin(), identifier.end()); + return identifierVect; +} + // Get interface for syncer. IKvDBSyncInterface *SQLiteSingleVerNaturalStore::GetSyncInterface() { @@ -1743,8 +1750,14 @@ int SQLiteSingleVerNaturalStore::StartLifeCycleTimer(const DatabaseLifeCycleNoti [this](TimerId id) -> int { std::lock_guard lock(lifeCycleMutex_); if (lifeCycleNotifier_) { - auto identifier = GetMyProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); - lifeCycleNotifier_(identifier); + std::string identifier; + if (GetMyProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false)) { + identifier = GetMyProperties().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + } else { + identifier = GetMyProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); + } + auto userId = GetMyProperties().GetStringProp(DBProperties::USER_ID, ""); + lifeCycleNotifier_(identifier, userId); } return 0; }, diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h index 8e02212b2a4d0f4d8ee670ba3067574e6fe4eada..3c6361408e331407f861dda634df37b651cf2bf1 100755 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h @@ -55,6 +55,8 @@ public: // Get the identifier of this kvdb. std::vector GetIdentifier() const override; + // Get the dual tuple identifier of this kvdb. + std::vector GetDualTupleIdentifier() const override; // Get interface for syncer. IKvDBSyncInterface *GetSyncInterface() override; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index c10ad103c495481b45bf6406f91849965f60a5c5..1764282d0b63ef2c5505e27d5bd9c5897664881a 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -14,10 +14,20 @@ */ #ifdef RELATIONAL_STORE #include "sqlite_single_ver_relational_storage_executor.h" +#include #include "data_transformer.h" #include "db_common.h" namespace DistributedDB { +namespace { + void ResetAllStatements(std::initializer_list stmts, bool finalize, int &errCode) + { + for (sqlite3_stmt *stmt : stmts) { + SQLiteUtils::ResetStatement(stmt, finalize, errCode); + } + } +} + SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecutor(sqlite3 *dbHandle, bool writable) : SQLiteStorageExecutor(dbHandle, writable, false) {} @@ -161,12 +171,15 @@ std::vector GetUpgradeFields(const TableInfo &oldTableInfo, const Tab return fields; } -int UpgradeFields(sqlite3 *db, const std::vector &tables, const std::vector &fields) +int UpgradeFields(sqlite3 *db, const std::vector &tables, std::vector &fields) { if (db == nullptr) { return -E_INVALID_ARGS; } + std::sort(fields.begin(), fields.end(), [] (const FieldInfo &a, const FieldInfo &b) { + return a.GetColumnId()< b.GetColumnId(); + }); int errCode = E_OK; for (auto table : tables) { for (auto field : fields) { @@ -614,17 +627,24 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAllMetaKeys(std::vector &k } int SQLiteSingleVerRelationalStorageExecutor::PrepareForSavingLog(const QueryObject &object, - const std::string &deviceName, sqlite3_stmt *&logStmt) const + const std::string &deviceName, sqlite3_stmt *&logStmt, sqlite3_stmt *&queryStmt) const { std::string devName = DBCommon::TransferHashString(deviceName); const std::string tableName = DBConstant::RELATIONAL_PREFIX + object.GetTableName() + "_log"; std::string dataFormat = "?, '" + deviceName + "', ?, ?, ?, ?, ?"; - + std::string columnList = "data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key"; std::string sql = "INSERT OR REPLACE INTO " + tableName + - " (data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key) VALUES (" + dataFormat + ");"; + " (" + columnList + ") VALUES (" + dataFormat + ");"; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, logStmt); if (errCode != E_OK) { - LOGE("[info statement] Get statement fail!"); + LOGE("[info statement] Get log statement fail! errCode:%d", errCode); + return -E_INVALID_QUERY_FORMAT; + } + std::string selectSql = "select " + columnList + " from " + tableName + " where hash_key = ? and device = ?;"; + errCode = SQLiteUtils::GetStatement(dbHandle_, selectSql, queryStmt); + if (errCode != E_OK) { + SQLiteUtils::ResetStatement(logStmt, true, errCode); + LOGE("[info statement] Get query statement fail! errCode:%d", errCode); return -E_INVALID_QUERY_FORMAT; } return errCode; @@ -646,25 +666,21 @@ int SQLiteSingleVerRelationalStorageExecutor::PrepareForSavingData(const QueryOb " (" + colName + ") VALUES (" + dataFormat + ");"; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); if (errCode != E_OK) { - LOGE("[info statement] Get statement fail!"); + LOGE("[info statement] Get saving data statement fail! errCode:%d", errCode); errCode = -E_INVALID_QUERY_FORMAT; } return errCode; } -int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statement, const DataItem &dataItem, - TimeStamp &maxTimestamp, int64_t rowid) +int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statement, sqlite3_stmt *queryStmt, + const DataItem &dataItem, TimeStamp &maxTimestamp, int64_t rowid) { - std::string sql = "select * from " + DBConstant::RELATIONAL_PREFIX + baseTblName_ + "_log where hash_key = ?;"; - sqlite3_stmt *queryStmt = nullptr; - int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, queryStmt); + int errCode = SQLiteUtils::BindBlobToStatement(queryStmt, 1, dataItem.hashKey); if (errCode != E_OK) { - LOGE("[info statement] Get statement fail!"); - return -E_INVALID_QUERY_FORMAT; + return errCode; } - errCode = SQLiteUtils::BindBlobToStatement(queryStmt, 1, dataItem.hashKey); + errCode = SQLiteUtils::BindTextToStatement(queryStmt, 2, dataItem.dev); if (errCode != E_OK) { - SQLiteUtils::ResetStatement(queryStmt, true, errCode); return errCode; } @@ -675,7 +691,6 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statemen } else { errCode = GetLogData(queryStmt, logInfoGet); } - SQLiteUtils::ResetStatement(queryStmt, true, errCode); LogInfo logInfoBind; logInfoBind.hashKey = dataItem.hashKey; @@ -740,20 +755,13 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncDataItem(const DataItem } int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(const DataItem &dataItem, sqlite3_stmt *&saveDataStmt, - sqlite3_stmt *&rmDataStmt, int64_t &rowid) + sqlite3_stmt *&rmDataStmt, const std::vector &fieldInfos, int64_t &rowid) { if ((dataItem.flag & DataItem::DELETE_FLAG) != 0) { return DeleteSyncDataItem(dataItem, rmDataStmt); } - std::map colInfos = table_.GetFields(); - std::vector fieldInfos; - for (const auto &col: colInfos) { - fieldInfos.push_back(col.second); - } - std::vector indexMapping; - OptRowDataWithLog data; int errCode = DataTransformer::DeSerializeDataItem(dataItem, data, fieldInfos, indexMapping); if (errCode != E_OK) { @@ -830,18 +838,20 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItems(const QueryObjec sqlite3_stmt *saveDataStmt = nullptr; int errCode = PrepareForSavingData(object, saveDataStmt); if (errCode != E_OK) { - LOGE("[RelationalStorage] Get saveDataStmt fail!"); return errCode; } - sqlite3_stmt *saveLogStmt = nullptr; - errCode = PrepareForSavingLog(object, deviceName, saveLogStmt); + sqlite3_stmt *queryStmt = nullptr; + errCode = PrepareForSavingLog(object, deviceName, saveLogStmt, queryStmt); if (errCode != E_OK) { SQLiteUtils::ResetStatement(saveDataStmt, true, errCode); - LOGE("[RelationalStorage] Get saveLogStmt fail!"); return errCode; } - + std::map colInfos = table_.GetFields(); + std::vector fieldInfos; + for (const auto &col: colInfos) { + fieldInfos.push_back(col.second); + } sqlite3_stmt *rmDataStmt = nullptr; sqlite3_stmt *rmLogStmt = nullptr; for (auto &item : dataItems) { @@ -849,7 +859,6 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItems(const QueryObjec continue; } item.dev = deviceName; - if ((item.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) != 0) { errCode = ProcessMissQueryData(item, rmDataStmt, rmLogStmt); if (errCode != E_OK) { @@ -858,30 +867,24 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItems(const QueryObjec continue; } int64_t rowid = -1; - errCode = SaveSyncDataItem(item, saveDataStmt, rmDataStmt, rowid); + errCode = SaveSyncDataItem(item, saveDataStmt, rmDataStmt, fieldInfos, rowid); if (errCode != E_OK && errCode != -E_NOT_FOUND) { LOGE("Save sync dataitem failed:%d.", errCode); break; } - - errCode = SaveSyncLog(saveLogStmt, item, maxTimestamp, rowid); + errCode = SaveSyncLog(saveLogStmt, queryStmt, item, maxTimestamp, rowid); if (errCode != E_OK) { LOGE("Save sync log failed:%d.", errCode); break; } maxTimestamp = std::max(item.timeStamp, maxTimestamp); // Need not reset rmDataStmt and rmLogStmt here. - SQLiteUtils::ResetStatement(saveDataStmt, false, errCode); - SQLiteUtils::ResetStatement(saveLogStmt, false, errCode); + ResetAllStatements({saveDataStmt, saveLogStmt, queryStmt}, false, errCode); } - if (errCode == -E_NOT_FOUND) { errCode = E_OK; } - SQLiteUtils::ResetStatement(rmDataStmt, true, errCode); - SQLiteUtils::ResetStatement(rmLogStmt, true, errCode); - SQLiteUtils::ResetStatement(saveLogStmt, true, errCode); - SQLiteUtils::ResetStatement(saveDataStmt, true, errCode); + ResetAllStatements({saveDataStmt, saveLogStmt, queryStmt, rmDataStmt, rmLogStmt}, true, errCode); return errCode; } @@ -915,7 +918,6 @@ int SQLiteSingleVerRelationalStorageExecutor::GetDataItemForSync(sqlite3_stmt *s return errCode; } - std::vector fieldInfos; if (!isGettingDeletedData) { for (size_t cid = 0; cid < table_.GetFields().size(); ++cid) { DataValue value; @@ -923,17 +925,11 @@ int SQLiteSingleVerRelationalStorageExecutor::GetDataItemForSync(sqlite3_stmt *s if (errCode != E_OK) { return errCode; } - auto iter = table_.GetFields().find(table_.GetFieldName(cid)); - if (iter == table_.GetFields().end()) { - LOGE("Get field name failed."); - return -E_INTERNAL_ERROR; - } - fieldInfos.push_back(iter->second); - data.rowData.push_back(value); + data.rowData.push_back(std::move(value)); } } - errCode = DataTransformer::SerializeDataItem(data, fieldInfos, dataItem); + errCode = DataTransformer::SerializeDataItem(data, table_.GetFieldInfos(), dataItem); if (errCode != E_OK) { LOGE("relational data value transfer to kv fail"); } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index 1cf81dab24b789ec4b0fd52a2b9f0fee6767ca3a..5cdf5dcc546c411aecedeab8c28bf2ed09c1430e 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -79,13 +79,15 @@ private: int SaveSyncDataItems(const QueryObject &object, std::vector &dataItems, const std::string &deviceName, TimeStamp &timeStamp); int SaveSyncDataItem(const DataItem &dataItem, sqlite3_stmt *&saveDataStmt, sqlite3_stmt *&rmDataStmt, - int64_t &rowid); + const std::vector &fieldInfos, int64_t &rowid); int DeleteSyncDataItem(const DataItem &dataItem, sqlite3_stmt *&rmDataStmt); - int SaveSyncLog(sqlite3_stmt *statement, const DataItem &dataItem, TimeStamp &maxTimestamp, int64_t rowid); + int SaveSyncLog(sqlite3_stmt *statement, sqlite3_stmt *queryStmt, + const DataItem &dataItem, TimeStamp &maxTimestamp, int64_t rowid); int PrepareForSavingData(const QueryObject &object, sqlite3_stmt *&statement) const; - int PrepareForSavingLog(const QueryObject &object, const std::string &deviceName, sqlite3_stmt *&statement) const; + int PrepareForSavingLog(const QueryObject &object, const std::string &deviceName, + sqlite3_stmt *&statement, sqlite3_stmt *&queryStmt) const; int AlterAuxTableForUpgrade(const TableInfo &oldTableInfo, const TableInfo &newTableInfo); diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_engine.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_engine.cpp index da5c9b02dd8cc15d87f40c2392ae9d84ee92b810..654425829ce0294e8877013857eb5e23a9781230 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_engine.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_engine.cpp @@ -102,7 +102,7 @@ void SyncAbleEngine::StartSyncer() return; } - int errCode = syncer_.Initialize(store_); + int errCode = syncer_.Initialize(store_, true); if (errCode == E_OK) { started_ = true; } else { diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.cpp index e9ada439e305d1431a2e0c76605ccbc8821062e6..4200046d94c9e428da50e767097e3f3ec761b738 100755 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.cpp @@ -19,13 +19,17 @@ #include "log_print.h" #include "parcel.h" #include "runtime_context.h" +#include "user_change_monitor.h" namespace DistributedDB { const EventType SyncAbleKvDB::REMOTE_PUSH_FINISHED = 1; SyncAbleKvDB::SyncAbleKvDB() : started_(false), - notifyChain_(nullptr) + isSyncModuleActiveCheck_(false), + isSyncNeedActive_(true), + notifyChain_(nullptr), + userChangeListerner_(nullptr) {} SyncAbleKvDB::~SyncAbleKvDB() @@ -35,6 +39,10 @@ SyncAbleKvDB::~SyncAbleKvDB() KillAndDecObjRef(notifyChain_); notifyChain_ = nullptr; } + if (userChangeListerner_ != nullptr) { + userChangeListerner_->Drop(true); + userChangeListerner_ = nullptr; + } } void SyncAbleKvDB::DelConnection(GenericKvDBConnection *connection) @@ -101,36 +109,138 @@ void SyncAbleKvDB::StopSync() } } -// Start syncer -void SyncAbleKvDB::StartSyncer() +void SyncAbleKvDB::SetSyncModuleActive() { + if (isSyncModuleActiveCheck_) { + return; + } IKvDBSyncInterface *syncInterface = GetSyncInterface(); if (syncInterface == nullptr) { LOGF("KvDB got null sync interface."); return; } + bool isSyncDualTupleMode = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + if (!isSyncDualTupleMode) { + isSyncNeedActive_ = true; + isSyncModuleActiveCheck_ = true; + return; + } + std::string userId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + std::string appId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + std::string storeId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + isSyncNeedActive_ = RuntimeContext::GetInstance()->IsSyncerNeedActive(userId, appId, storeId); + if (!isSyncNeedActive_) { + LOGI("syncer no need to active"); + } + isSyncModuleActiveCheck_ = true; +} + +bool SyncAbleKvDB::GetSyncModuleActive() +{ + return isSyncNeedActive_; +} - int errCode = syncer_.Initialize(syncInterface); +void SyncAbleKvDB::ReSetSyncModuleActive() +{ + isSyncModuleActiveCheck_ = false; + isSyncNeedActive_ = true; +} + +// Start syncer +void SyncAbleKvDB::StartSyncer(bool isCheckSyncActive, bool isNeedActive) +{ + IKvDBSyncInterface *syncInterface = GetSyncInterface(); + if (syncInterface == nullptr) { + LOGF("KvDB got null sync interface."); + return; + } + std::unique_lock lock(syncerOperateLock_); + if (!isCheckSyncActive) { + SetSyncModuleActive(); + isNeedActive = GetSyncModuleActive(); + } + int errCode = syncer_.Initialize(syncInterface, isNeedActive); if (errCode == E_OK) { started_ = true; } else { LOGE("KvDB start syncer failed, err:'%d'.", errCode); } + bool isSyncDualTupleMode = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + if (isSyncDualTupleMode && isCheckSyncActive && !isNeedActive && (userChangeListerner_ == nullptr)) { + // active to non_active + userChangeListerner_ = RuntimeContext::GetInstance()->RegisterUserChangedListerner( + std::bind(&SyncAbleKvDB::ChangeUserListerner, this), UserChangeMonitor::USER_ACTIVE_TO_NON_ACTIVE_EVENT); + } else if (isSyncDualTupleMode && (userChangeListerner_ == nullptr)) { + EventType event = started_? + UserChangeMonitor::USER_ACTIVE_EVENT : UserChangeMonitor::USER_NON_ACTIVE_EVENT; + userChangeListerner_ = RuntimeContext::GetInstance()->RegisterUserChangedListerner( + std::bind(&SyncAbleKvDB::UserChangeHandle, this), event); + } } // Stop syncer void SyncAbleKvDB::StopSyncer() { + std::unique_lock lock(syncerOperateLock_); + ReSetSyncModuleActive(); + syncer_.Close(); if (started_) { - syncer_.Close(); started_ = false; } + if (userChangeListerner_ != nullptr) { + userChangeListerner_->Drop(true); + userChangeListerner_ = nullptr; + } +} + +void SyncAbleKvDB::UserChangeHandle() +{ + bool isNeedChange; + bool isNeedActive = true; + { + IKvDBSyncInterface *syncInterface = GetSyncInterface(); + if (syncInterface == nullptr) { + LOGF("KvDB got null sync interface."); + return; + } + std::unique_lock lock(syncerOperateLock_); + std::string userId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + std::string appId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + std::string storeId = syncInterface->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + isNeedActive = RuntimeContext::GetInstance()->IsSyncerNeedActive(userId, appId, storeId); + isNeedChange = (isNeedActive != isSyncNeedActive_) ? true : false; + } + // non_active to active or active to non_active + if (isNeedChange) { + StopSyncer(); // will drop userChangeListerner; + { + std::unique_lock lock(syncerOperateLock_); + isSyncModuleActiveCheck_ = true; + isSyncNeedActive_ = isNeedActive; + } + StartSyncer(true, isNeedActive); + } +} + +void SyncAbleKvDB::ChangeUserListerner() +{ + // only active to non_active call, put into USER_NON_ACTIVE_EVENT listerner from USER_ACTIVE_TO_NON_ACTIVE_EVENT + if (userChangeListerner_ != nullptr) { + userChangeListerner_->Drop(true); + userChangeListerner_ = nullptr; + } + if (userChangeListerner_ == nullptr) { + userChangeListerner_ = RuntimeContext::GetInstance()->RegisterUserChangedListerner( + std::bind(&SyncAbleKvDB::UserChangeHandle, this), UserChangeMonitor::USER_NON_ACTIVE_EVENT); + } } // Get The current virtual timestamp uint64_t SyncAbleKvDB::GetTimeStamp() { - if (!started_) { + if (!started_ && !isSyncModuleActiveCheck_) { StartSyncer(); } return syncer_.GetTimeStamp(); @@ -177,17 +287,11 @@ int SyncAbleKvDB::EnableManualSync(void) int SyncAbleKvDB::GetLocalIdentity(std::string &outTarget) { - if (!started_) { - StartSyncer(); - } return syncer_.GetLocalIdentity(outTarget); } int SyncAbleKvDB::SetStaleDataWipePolicy(WipePolicy policy) { - if (!started_) { - StartSyncer(); - } return syncer_.SetStaleDataWipePolicy(policy); } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.h b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.h index 5c89a5e6a3b953f83621bb739756727d70b1991f..3d565a5cca5e32145a36a2134d6badb1dc65e10c 100755 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sync_able_kvdb.h @@ -86,12 +86,21 @@ public: protected: virtual IKvDBSyncInterface *GetSyncInterface() = 0; + void SetSyncModuleActive(); + + bool GetSyncModuleActive(); + + void ReSetSyncModuleActive(); // Start syncer - void StartSyncer(); + void StartSyncer(bool isCheckSyncActive = false, bool isNeedActive = true); // Stop syncer void StopSyncer(); + void UserChangeHandle(); + + void ChangeUserListerner(); + // Get the dataItem's append length, the append length = after-serialized-len - original-dataItem-len uint32_t GetAppendedLen() const; @@ -104,9 +113,14 @@ private: SyncerProxy syncer_; std::atomic started_; + std::atomic isSyncModuleActiveCheck_; + std::atomic isSyncNeedActive_; mutable std::shared_mutex notifyChainLock_; NotificationChain *notifyChain_; + mutable std::mutex syncerOperateLock_; + NotificationChain::Listener *userChangeListerner_; + static const EventType REMOTE_PUSH_FINISHED; }; } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/include/isyncer.h b/services/distributeddataservice/libs/distributeddb/syncer/include/isyncer.h index 3adf6e63e76a90f3c8a3fbf929f1ae62553d345f..ea0f7d45cae5570a330f7dbff01cdbc1f780be50 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/include/isyncer.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/include/isyncer.h @@ -42,7 +42,7 @@ public: virtual ~ISyncer() {}; // Init the Syncer modules - virtual int Initialize(ISyncInterface *syncInterface) + virtual int Initialize(ISyncInterface *syncInterface, bool isNeedActive) { return -E_NOT_SUPPORT; } @@ -75,8 +75,11 @@ public: virtual void EnableAutoSync(bool enable) = 0; // delete specified device's watermark + virtual int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) = 0; + + // delete specified device's and table's watermark virtual int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, - const std::string &tableName = "") = 0; + const std::string &tableName) = 0; // Local data changed callback virtual void LocalDataChanged(int notifyEvent) = 0; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/include/sync_config.h b/services/distributeddataservice/libs/distributeddb/syncer/include/sync_config.h index aff11c4a70891f7280286395f798cfd49a6c2dcb..686ac2d6de7e22900fba1820b2381461259f508b 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/include/sync_config.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/include/sync_config.h @@ -33,19 +33,14 @@ current ability format: |first bit|second bit|third bit| |DATABASE_COMPRESSION_ZLIB|ALLPREDICATEQUERY|SUBSCRIBEQUERY| */ -constexpr AbilityItem DATABASE_COMPRESSION_ZLIB = {0, 1}; -constexpr AbilityItem ALLPREDICATEQUERY = {1, 1}; // 0b10 {1: start at second bit, 1: 1 bit len} -constexpr AbilityItem SUBSCRIBEQUERY = {2, 1}; // 0b100 -constexpr AbilityItem INKEYS_QUERY = {3, 1}; // 0b1000 - -const std::vector ABILITYBITS = { - DATABASE_COMPRESSION_ZLIB, - ALLPREDICATEQUERY, - SUBSCRIBEQUERY, - INKEYS_QUERY}; - -const std::map COMPRESSALGOMAP = { - {static_cast(CompressAlgorithm::ZLIB), DATABASE_COMPRESSION_ZLIB}, +class SyncConfig final { +public: + static const AbilityItem DATABASE_COMPRESSION_ZLIB; + static const AbilityItem ALLPREDICATEQUERY; + static const AbilityItem SUBSCRIBEQUERY; + static const AbilityItem INKEYS_QUERY; + static const std::vector ABILITYBITS; + static const std::map COMPRESSALGOMAP; }; } #endif \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/include/syncer_proxy.h b/services/distributeddataservice/libs/distributeddb/syncer/include/syncer_proxy.h index 52be0f72a07fc3557baa02ba5343b0221002091b..64ebfd05a404e43be1199aff3e4e65cb2a05a969 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/include/syncer_proxy.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/include/syncer_proxy.h @@ -30,7 +30,7 @@ public: ~SyncerProxy() {}; // Init the Syncer modules - int Initialize(ISyncInterface *syncInterface) override; + int Initialize(ISyncInterface *syncInterface, bool isNeedActive) override; // Close the syncer int Close() override; @@ -60,8 +60,11 @@ public: void EnableAutoSync(bool enable) override; // delete specified device's watermark + int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) override; + + // delete specified device's and table's watermark int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, - const std::string &tableName = "") override; + const std::string &tableName) override; // Local data changed callback void LocalDataChanged(int notifyEvent) override; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp index 1b0509eedd20ec1fc93cdb52c263a6183fa0da67..5866ba5988508e82905cdcf7a4386538dce7659d 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp @@ -376,7 +376,9 @@ int AbilitySync::SyncStart(uint32_t sessionId, uint32_t sequenceId, uint16_t rem message->SetVersion(MSG_VERSION_EXT); message->SetSessionId(sessionId); message->SetSequenceId(sequenceId); - errCode = communicator_->SendMessage(deviceId_, message, false, SEND_TIME_OUT, handler); + SendConfig conf; + SetSendConfig(deviceId_, false, SEND_TIME_OUT, conf); + errCode = communicator_->SendMessage(deviceId_, message, conf, handler); if (errCode != E_OK) { LOGE("[AbilitySync][SyncStart] SendPacket failed, err %d", errCode); delete message; @@ -1002,7 +1004,7 @@ void AbilitySync::SetAbilityAckSyncOpinionInfo(AbilitySyncAckPacket &ackPacket, int AbilitySync::GetDbAbilityInfo(DbAbility &dbAbility) const { int errCode = E_OK; - for (const auto &item : ABILITYBITS) { + for (const auto &item : SyncConfig::ABILITYBITS) { errCode = dbAbility.SetAbilityItem(item, SUPPORT_MARK); if (errCode != E_OK) { return errCode; @@ -1133,7 +1135,9 @@ int AbilitySync::SendAck(const Message *inMsg, const AbilitySyncAckPacket &ackPa ackMessage->SetTarget(deviceId_); ackMessage->SetSessionId(inMsg->GetSessionId()); ackMessage->SetSequenceId(inMsg->GetSequenceId()); - errCode = communicator_->SendMessage(deviceId_, ackMessage, false, SEND_TIME_OUT); + SendConfig conf; + SetSendConfig(deviceId_, false, SEND_TIME_OUT, conf); + errCode = communicator_->SendMessage(deviceId_, ackMessage, conf); if (errCode != E_OK) { LOGE("[AbilitySync][SendAck] SendPacket failed, err %d", errCode); delete ackMessage; @@ -1193,4 +1197,16 @@ int AbilitySync::HandleRelationAckSchemaParam(const AbilitySyncAckPacket *recvPa } return errCode; } + +void AbilitySync::SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, SendConfig &sendConf) +{ + sendConf.nonBlock = nonBlock; + sendConf.timeout = timeout; + sendConf.isNeedExtendHead = storageInterface_->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + sendConf.paramInfo.appId = storageInterface_->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + sendConf.paramInfo.userId = storageInterface_->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + sendConf.paramInfo.storeId = storageInterface_->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + sendConf.paramInfo.dstTarget = dstTarget; +} } // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.h b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.h index e1fa1ad0cb8e28a7043e40723678cf9828d2f0ef..b35c8721212f92b9106c8488055b83e52a224dfb 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.h @@ -235,6 +235,8 @@ private: RelationalSyncOpinion MakeRelationSyncOpnion(const AbilitySyncRequestPacket *packet, const std::string &remoteSchema) const; + void SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, SendConfig &sendConf); + ICommunicator *communicator_; ISyncInterface *storageInterface_; std::shared_ptr metadata_; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.cpp index 8eff48509f404da12ac1d0cdf126a90de79de4eb..b8c0ad86e3765f0a2b1b28e15c3a88935ba700dd 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.cpp @@ -309,7 +309,7 @@ int CommitHistorySync::AckRecvCallback(MultiVerSyncTaskContext *context, const M uint32_t ver = packet->GetVersion(); context->SetCommits(commits); context->SetCommitIndex(0); - context->SetCommitsSize(commits.size()); + context->SetCommitsSize(static_cast(commits.size())); LOGD("CommitHistorySync::AckRecvCallback end, CommitsSize = %llu, dst = %s{private}, ver = %d, myversion = %u", commits.size(), context->GetDeviceId().c_str(), ver, SOFTWARE_VERSION_CURRENT); return E_OK; @@ -536,7 +536,8 @@ bool CommitHistorySync::IsPacketValid(const Message *inMsg, uint16_t messageType int CommitHistorySync::Send(const DeviceID &deviceId, const Message *inMsg) { - int errCode = communicateHandle_->SendMessage(deviceId, inMsg, false, SEND_TIME_OUT); + SendConfig conf = {false, SEND_TIME_OUT}; + int errCode = communicateHandle_->SendMessage(deviceId, inMsg, conf); if (errCode != E_OK) { LOGE("CommitHistorySync::Send ERR! err = %d", errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.h b/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.h index 80ff06d84b446906909d2128d10412b079375f09..5c7869fe5f3aafe1bda3f7e18f4cb5c6b930e0d1 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/commit_history_sync.h @@ -63,9 +63,9 @@ public: void GetData(std::vector &outData) const; - void SetErrorCode(int32_t errorCode); + void SetErrorCode(int32_t errCode); - void GetErrorCode(int32_t &errorCode) const; + void GetErrorCode(int32_t &errCode) const; void SetVersion(uint32_t version); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.cpp index 49e02f345df2467ff580971343bacfa17191cdd8..25cc48bb1ba6683819f09d12fb9a3e65a2d2331f 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.cpp @@ -193,12 +193,12 @@ int CommunicatorProxy::GetRemoteCommunicatorVersion(const std::string &target, u return -E_NOT_INIT; } -int CommunicatorProxy::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) +int CommunicatorProxy::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) { - return SendMessage(dstTarget, inMsg, nonBlock, timeout, nullptr); + return SendMessage(dstTarget, inMsg, config, nullptr); } -int CommunicatorProxy::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, +int CommunicatorProxy::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) { ICommunicator *targetCommunicator = nullptr; @@ -210,14 +210,14 @@ int CommunicatorProxy::SendMessage(const std::string &dstTarget, const Message * } } if (targetCommunicator != nullptr) { - LOGI("[CommProxy] use equal label to send data"); - int errCode = targetCommunicator->SendMessage(dstTarget, inMsg, nonBlock, timeout, onEnd); + LOGD("[CommProxy] use equal label to send data"); + int errCode = targetCommunicator->SendMessage(dstTarget, inMsg, config, onEnd); RefObject::DecObjRef(targetCommunicator); return errCode; } if (mainComm_ != nullptr) { - return mainComm_->SendMessage(dstTarget, inMsg, nonBlock, timeout, onEnd); + return mainComm_->SendMessage(dstTarget, inMsg, config, onEnd); } return -E_NOT_INIT; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.h b/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.h index 0f54e8e31649326480a42bb468abaa494b816a70..a106a7e2926b3073fc13e181c647a164b995c5cd 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/communicator_proxy.h @@ -42,8 +42,8 @@ public: bool IsDeviceOnline(const std::string &device) const override; int GetLocalIdentity(std::string &outTarget) const override; int GetRemoteCommunicatorVersion(const std::string &target, uint16_t &outVersion) const override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) override; + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) override; // Set an Main communicator for this database, used userid & appId & storeId diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/device_manager.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/device_manager.cpp index 989b8177a77c23ccab3d4d167e6ae42abe1cf3bc..46ee72b121922c1a9993595f1e1968c104b9d9e6 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/device_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/device_manager.cpp @@ -138,7 +138,8 @@ int DeviceManager::SendLocalDataChanged() } msg->SetMessageId(LOCAL_DATA_CHANGED); msg->SetTarget(deviceId); - int errCode = communicator_->SendMessage(deviceId, msg, false, SEND_TIME_OUT); + SendConfig conf = {false, SEND_TIME_OUT}; + int errCode = communicator_->SendMessage(deviceId, msg, conf); if (errCode != E_OK) { LOGE("[DeviceManager] SendLocalDataChanged to dev %s{private} failed. err %d", deviceId.c_str(), errCode); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.cpp index a6da32f7717dd9f55979a82aa0a77f129dbbd40d..d3cd89fe02ef691947ee8b8d5450c8c60d7cab1b 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.cpp @@ -63,7 +63,7 @@ GenericSyncer::~GenericSyncer() syncInterface_ = nullptr; } -int GenericSyncer::Initialize(ISyncInterface *syncInterface) +int GenericSyncer::Initialize(ISyncInterface *syncInterface, bool isNeedActive) { if (syncInterface == nullptr) { LOGE("[Syncer] Init failed, the syncInterface is null!"); @@ -79,6 +79,9 @@ int GenericSyncer::Initialize(ISyncInterface *syncInterface) LOGE("[Syncer] Syncer is closing, return!"); return -E_BUSY; } + std::vector label = syncInterface->GetIdentifier(); + label.resize(3); // only show 3 Bytes enough + label_ = DBCommon::VectorToHexString(label); // As metadata_ will be used in EraseDeviceWaterMark, it should not be clear even if engine init failed. // It will be clear in destructor. @@ -90,13 +93,17 @@ int GenericSyncer::Initialize(ISyncInterface *syncInterface) if (errCodeMetadata != E_OK || errCodeTimeHelper != E_OK) { return -E_INTERNAL_ERROR; } + int errCode = CheckSyncActive(syncInterface, isNeedActive); + if (errCode != E_OK) { + return errCode; + } if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) { LOGW("[Syncer] Communicator component not ready!"); return -E_NOT_INIT; } - int errCode = SyncModuleInit(); + errCode = SyncModuleInit(); if (errCode != E_OK) { LOGE("[Syncer] Sync ModuleInit ERR!"); return -E_INTERNAL_ERROR; @@ -112,6 +119,7 @@ int GenericSyncer::Initialize(ISyncInterface *syncInterface) // RegConnectCallback may start a auto sync, this function can not in syncerLock_ syncEngine_->RegConnectCallback(); + syncEngine_->SetEqualIdentifier(); return E_OK; } @@ -120,7 +128,9 @@ int GenericSyncer::Close() { std::lock_guard lock(syncerLock_); if (!initialized_) { - LOGW("[Syncer] Syncer don't need to close, because it has no been init."); + LOGW("[Syncer] Syncer[%s] don't need to close, because it has no been init", label_.c_str()); + timeHelper_ = nullptr; + metadata_ = nullptr; return -E_NOT_INIT; } initialized_ = false; @@ -364,6 +374,23 @@ int GenericSyncer::InitSyncEngine(ISyncInterface *syncInterface) } } +int GenericSyncer::CheckSyncActive(ISyncInterface *syncInterface, bool isNeedActive) +{ + bool isSyncDualTupleMode = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + if (!isSyncDualTupleMode || isNeedActive) { + return E_OK; + } + LOGI("[Syncer] syncer no need to active"); + if (syncEngine_ == nullptr) { + syncEngine_ = CreateSyncEngine(); + if (syncEngine_ == nullptr) { + return -E_OUT_OF_MEMORY; + } + } + return -E_NO_NEED_ACTIVE; +} + uint32_t GenericSyncer::GenerateSyncId() { std::lock_guard lock(syncIdLock_); @@ -583,20 +610,14 @@ int GenericSyncer::EnableManualSync(void) int GenericSyncer::GetLocalIdentity(std::string &outTarget) const { - std::lock_guard lock(syncerLock_); - if (!initialized_) { - LOGE("[Syncer] Syncer is not initialized, return!"); - return -E_NOT_INIT; - } - if (closing_) { - LOGE("[Syncer] Syncer is closing, return!"); - return -E_BUSY; - } - if (syncEngine_ == nullptr) { - LOGE("[Syncer] Syncer syncEngine_ is nullptr, return!"); - return -E_NOT_INIT; + std::string deviceId; + int errCode = RuntimeContext::GetInstance()->GetLocalIdentity(deviceId); + if (errCode != E_OK) { + LOGE("[GenericSyncer] GetLocalIdentity fail errCode:%d", errCode); + return errCode; } - return syncEngine_->GetLocalIdentity(outTarget); + outTarget = DBCommon::TransferHashString(deviceId); + return E_OK; } void GenericSyncer::GetOnlineDevices(std::vector &devices) const @@ -606,7 +627,14 @@ void GenericSyncer::GetOnlineDevices(std::vector &devices) const LOGI("[Syncer] GetOnlineDevices syncInterface_ is nullptr"); return; } - std::string identifier = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); + bool isSyncDualTupleMode = syncInterface_->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + std::string identifier; + if (isSyncDualTupleMode) { + identifier = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + } else { + identifier = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, ""); + } RuntimeContext::GetInstance()->GetAutoLaunchSyncDevices(identifier, devices); if (!devices.empty()) { return; @@ -623,6 +651,9 @@ void GenericSyncer::GetOnlineDevices(std::vector &devices) const int GenericSyncer::SetSyncRetry(bool isRetry) { + if (syncEngine_ == nullptr) { + return -E_NOT_INIT; + } syncEngine_->SetSyncRetry(isRetry); return E_OK; } @@ -633,7 +664,11 @@ int GenericSyncer::SetEqualIdentifier(const std::string &identifier, const std:: if (syncEngine_ == nullptr) { return -E_NOT_INIT; } - return syncEngine_->SetEqualIdentifier(identifier, targets); + int errCode = syncEngine_->SetEqualIdentifier(identifier, targets); + if (errCode == E_OK) { + syncEngine_->SetEqualIdentifierMap(identifier, targets); + } + return errCode; } std::string GenericSyncer::GetSyncDevicesStr(const std::vector &devices) const diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.h b/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.h index 5c4048e1b0bb85de8a9f279f4c4dc0a3853e25ac..2d080840648b7eedddfc44401f3939981258cbea 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/generic_syncer.h @@ -35,7 +35,7 @@ public: ~GenericSyncer() override; // Init the Syncer modules - int Initialize(ISyncInterface *syncInterface) override; + int Initialize(ISyncInterface *syncInterface, bool isNeedActive) override; // Close int Close() override; @@ -123,6 +123,8 @@ protected: // Init the Sync engine int InitSyncEngine(ISyncInterface *syncInterface); + int CheckSyncActive(ISyncInterface *syncInterface, bool isNeedActive); + // Used to general a sync id, maybe it is currentSyncId++; // The return value is sync id. uint32_t GenerateSyncId(); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/isync_engine.h b/services/distributeddataservice/libs/distributeddb/syncer/src/isync_engine.h index c073be6a13b59512a5c96c30434ec24b486205f1..3bc748449068ccf64b7794a0aa2387cf89ce6bfc 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/isync_engine.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/isync_engine.h @@ -52,9 +52,6 @@ public: // Register the device connect callback, this function must be called after Engine initted virtual void RegConnectCallback() = 0; - // Get local deviceId, is hashed - virtual int GetLocalIdentity(std::string &outTarget) const = 0; - // Get the database identifier virtual std::string GetLabel() const = 0; @@ -64,6 +61,11 @@ public: // Set an equal identifier for this database, After this called, send msg to the target will use this identifier virtual int SetEqualIdentifier(const std::string &identifier, const std::vector &targets) = 0; + // Set record device equal identifier when called in import/rekey scene when restart syncer + virtual void SetEqualIdentifier() = 0; + + virtual void SetEqualIdentifierMap(const std::string &identifier, const std::vector &targets) = 0; + // Add auto subscribe timer when start sync engine, used for auto subscribe failed subscribe task when db online virtual int StartAutoSubscribeTimer() = 0; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.cpp index c60415b26688202815288fb761bc381cc19e0462..0742cafa840fe37f6bd8913432deae42ff520169 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.cpp @@ -55,9 +55,16 @@ int Metadata::Initialize(ISyncInterface* storage) int errCode = GetMetadataFromDb(key, timeOffset); if (errCode == -E_NOT_FOUND) { uint64_t randTimeOffset = GetRandTimeOffset(); - SaveLocalTimeOffset(TimeHelper::BASE_OFFSET + randTimeOffset); - } else { + int err = SaveLocalTimeOffset(TimeHelper::BASE_OFFSET + static_cast(randTimeOffset)); + if (err != E_OK) { + LOGD("[Metadata][Initialize]SaveLocalTimeOffset failed errCode:%d", err); + return err; + } + } else if (errCode == E_OK) { localTimeOffset_ = StringToLong(timeOffset); + } else { + LOGE("Metadata::Initialize get meatadata from db failed,err=%d", errCode); + return errCode; } { std::lock_guard lockGuard(metadataLock_); @@ -145,6 +152,11 @@ TimeOffset Metadata::GetLocalTimeOffset() const return localTimeOffset; } +int Metadata::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) +{ + return EraseDeviceWaterMark(deviceId, isNeedHash, ""); +} + int Metadata::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName) { // try to erase all the waterMark @@ -302,7 +314,11 @@ bool IsMetaDataKey(const Key &inKey, const std::string &expectPrefix) int Metadata::LoadAllMetadata() { std::vector> metaDataKeys; - GetAllMetadataKey(metaDataKeys); + int errCode = GetAllMetadataKey(metaDataKeys); + if (errCode != E_OK) { + LOGE("[Metadata] get all metadata key failed err=%d", errCode); + return errCode; + } std::vector> querySyncIds; for (const auto &deviceId : metaDataKeys) { diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.h b/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.h index 0cbcbfa96c2c52b87662b8e4c77dce3927115548..ff14a90c16c90f9066fbda51727c471b193d14b4 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/meta_data.h @@ -58,7 +58,9 @@ public: TimeOffset GetLocalTimeOffset() const; - int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName = ""); + int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash); + + int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName); void SetLastLocalTime(TimeStamp lastLocalTime); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.cpp index bf7d17bffc8985dc257624d6f8210a01af732952..b08fe0da9736d7c09875923833d88561d2ee12f7 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.cpp @@ -278,7 +278,7 @@ int MultiVerDataSync::AckRecvCallback(MultiVerSyncTaskContext *context, const Me context->ReleaseEntries(); context->SetEntries(entries); context->SetEntriesIndex(0); - context->SetEntriesSize(entries.size()); + context->SetEntriesSize(static_cast(entries.size())); LOGD("MultiVerDataSync::AckRecvCallback src=%s{private}, entries num = %llu", context->GetDeviceId().c_str(), entries.size()); @@ -576,7 +576,8 @@ bool MultiVerDataSync::IsCommitExisted(const MultiVerCommitNode &commit) int MultiVerDataSync::Send(const DeviceID &deviceId, const Message *inMsg) { - int errCode = communicateHandle_->SendMessage(deviceId, inMsg, false, SEND_TIME_OUT); + SendConfig conf = {false, SEND_TIME_OUT}; + int errCode = communicateHandle_->SendMessage(deviceId, inMsg, conf); if (errCode != E_OK) { LOGE("MultiVerDataSync::Send ERR! ERR = %d", errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.h b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.h index 88de2845632682c4fd1b22fa0e00e6174b40a3bf..889be32c854c823f25b99fdb4dfb74d1db4d48f4 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_data_sync.h @@ -57,7 +57,7 @@ public: void SetErrorCode(int32_t errCode); - void GetErrorCode(int32_t &errorCode) const; + void GetErrorCode(int32_t &errCode) const; private: std::vector> entries_; int32_t errorCode_; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp index 7a0ec21ce0f79f4dccddba7cc7c07d399af81f9f..6ea439f847c0c9fff9a790db3ff52a43f037bf74 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp @@ -131,7 +131,7 @@ int MultiVerSyncStateMachine::ReceiveMessageCallback(Message *inMsg) } if (inMsg->IsFeedbackError()) { LOGE("[MultiVerSyncStateMachine] Feedback Message with errorNo=%u.", inMsg->GetErrorNo()); - return -(inMsg->GetErrorNo()); + return -static_cast(inMsg->GetErrorNo()); } if (inMsg->GetMessageId() == TIME_SYNC_MESSAGE) { return TimeSyncPacketRecvCallback(context_, inMsg); @@ -453,13 +453,14 @@ int MultiVerSyncStateMachine::OneCommitSyncFinish() return errCode; } TimeStamp currentLocalTime = context_->GetCurrentLocalTime(); - commit.timestamp -= outOffset; + commit.timestamp -= static_cast(outOffset); // Due to time sync error, commit timestamp may bigger than currentLocalTime, we need to fix the timestamp - TimeOffset timefixOffset = (commit.timestamp < currentLocalTime) ? 0 : (commit.timestamp - currentLocalTime); + TimeOffset timefixOffset = (commit.timestamp < currentLocalTime) ? 0 : (commit.timestamp - + static_cast(currentLocalTime)); LOGD("MultiVerSyncStateMachine::OneCommitSyncFinish src=%s, timefixOffset = %lld", STR_MASK(context_->GetDeviceId()), timefixOffset); - commit.timestamp -= timefixOffset; + commit.timestamp -= static_cast(timefixOffset); for (MultiVerKvEntry *entry : entries) { TimeStamp timeStamp; entry->GetTimestamp(timeStamp); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.cpp index c75695a44a57679c24045f1c9528e7f1f55b9e73..65ac108a13da50a940eb0a1d91412e2673da92b0 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.cpp @@ -58,6 +58,11 @@ void MultiVerSyncer::EnableAutoSync(bool enable) } } +int MultiVerSyncer::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) +{ + return EraseDeviceWaterMark(deviceId, isNeedHash, ""); +} + int MultiVerSyncer::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName) { diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.h b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.h index 9c93d4d9d5c0326fea7d269851cedfd735a3ea6b..37b431281d7b6c948c6a7c398765f12ba47f8fca 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/multi_ver_syncer.h @@ -30,8 +30,11 @@ public: void EnableAutoSync(bool enable) override; // delete specified device's watermark + int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) override; + + // delete specified device's and table's watermark int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, - const std::string &tableName = "") override; + const std::string &tableName) override; // Local data changed callback void LocalDataChanged(int notifyEvent) override; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/query_sync_water_mark_helper.h b/services/distributeddataservice/libs/distributeddb/syncer/src/query_sync_water_mark_helper.h index 6491633ccd60a3333ccf6c56c5985ab4d8b8f78c..11a95850b21037d2337920b923d0049eec7f8afb 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/query_sync_water_mark_helper.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/query_sync_water_mark_helper.h @@ -90,7 +90,7 @@ public: int RemoveLeastUsedQuerySyncItems(const std::vector &querySyncIds); // reset the waterMark to zero - int ResetRecvQueryWaterMark(const DeviceID &deviceId, const std::string &tableName = ""); + int ResetRecvQueryWaterMark(const DeviceID &deviceId, const std::string &tableName); static std::string GetQuerySyncPrefixKey(); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_packet.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_packet.cpp index 2942d8587917fc6a7370c5bdd7d7d8ed47ebd6ff..0b52e052886f3cdfa519903083990a08eec9d8cb 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_packet.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_packet.cpp @@ -357,7 +357,7 @@ void ControlRequestPacket::SetPacketHead(int sendCode, uint32_t version, int32_t { sendCode_ = sendCode; version_ = version; - controlCmdType_ = controlCmd; + controlCmdType_ = static_cast(controlCmd); flag_ = flag; } @@ -433,7 +433,7 @@ void ControlAckPacket::SetPacketHead(int recvCode, uint32_t version, int32_t con { recvCode_ = recvCode; version_ = version; - controlCmdType_ = controlCmd; + controlCmdType_ = static_cast(controlCmd); flag_ = flag; } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.cpp index f7a5071567595e7ba5941bb0f0638f8d34b78cdf..5f0e7066b8046bb69c0f1686e07a07b151a9cc1e 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.cpp @@ -22,6 +22,7 @@ #include "log_print.h" #include "message_transform.h" #include "performance_analysis.h" +#include "single_ver_data_sync_utils.h" #include "single_ver_sync_state_machine.h" #include "subscribe_manager.h" #ifdef RELATIONAL_STORE @@ -29,22 +30,6 @@ #endif namespace DistributedDB { -namespace { -void SetMessageHeadInfo(Message &message, uint16_t inMsgType, const std::string &inTarget, uint32_t inSequenceId, - uint32_t inSessionId) -{ - message.SetMessageType(inMsgType); - message.SetTarget(inTarget); - message.SetSequenceId(inSequenceId); - message.SetSessionId(inSessionId); -} - -inline bool IsGetDataSuccessfully(int errCode) -{ - return errCode == E_OK || errCode == -E_UNFINISHED; -} -} - SingleVerDataSync::SingleVerDataSync() : mtuSize_(0), storage_(nullptr), @@ -229,15 +214,6 @@ std::string SingleVerDataSync::GetLocalDeviceName() return deviceInfo; } -std::string SingleVerDataSync::TransferForeignOrigDevName(const std::string &deviceName, - const std::string &localHashName) -{ - if (localHashName == deviceName) { - return ""; - } - return deviceName; -} - int SingleVerDataSync::Send(SingleVerSyncTaskContext *context, const Message *message, const CommErrHandler &handler, uint32_t packetLen) { @@ -247,7 +223,9 @@ int SingleVerDataSync::Send(SingleVerSyncTaskContext *context, const Message *me static_cast(context->GetTimeoutTime()) / mtuSize_); // no overflow startFeedDogRet = context->StartFeedDogForSync(time, SyncDirectionFlag::SEND); } - int errCode = communicateHandle_->SendMessage(context->GetDeviceId(), message, false, SEND_TIME_OUT, handler); + SendConfig sendConfig; + SetSendConfig(context->GetDeviceId(), false, SEND_TIME_OUT, sendConfig); + int errCode = communicateHandle_->SendMessage(context->GetDeviceId(), message, sendConfig, handler); if (errCode != E_OK) { LOGE("[DataSync][Send] send message failed, errCode=%d", errCode); if (startFeedDogRet) { @@ -279,8 +257,9 @@ int SingleVerDataSync::GetData(SingleVerSyncTaskContext *context, std::vectorStepTimeRecordEnd(PT_TEST_RECORDS::RECORD_READ_DATA); } - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { context->SetTaskErrCode(errCode); return errCode; } @@ -351,7 +330,7 @@ int SingleVerDataSync::GetUnsyncData(SingleVerSyncTaskContext *context, std::vec syncDataSizeInfo, token, outData); } context->SetContinueToken(token); - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { LOGE("[DataSync][GetUnsyncData] get unsync data failed,errCode=%d", errCode); } return errCode; @@ -365,7 +344,7 @@ int SingleVerDataSync::GetNextUnsyncData(SingleVerSyncTaskContext *context, std: DataSizeSpecInfo syncDataSizeInfo = GetDataSizeSpecInfo(packetSize); int errCode = storage_->GetSyncDataNext(outData, token, syncDataSizeInfo); context->SetContinueToken(token); - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { LOGE("[DataSync][GetNextUnsyncData] get next unsync data failed, errCode=%d", errCode); } return errCode; @@ -382,7 +361,8 @@ int SingleVerDataSync::SaveData(const SingleVerSyncTaskContext *context, const s performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_SAVE_DATA); } - TransSendDataItemToLocal(context, inData); + const std::string localHashName = DBCommon::TransferHashString(GetLocalDeviceName()); + SingleVerDataSyncUtils::TransSendDataItemToLocal(context, localHashName, inData); int errCode = E_OK; // query only support prefix key and don't have query in packet in 104 version errCode = storage_->PutSyncDataWithQuery(query, inData, context->GetDeviceId()); @@ -415,21 +395,6 @@ void SingleVerDataSync::ResetSyncStatus(int inMode, SingleVerSyncTaskContext *co } } -TimeStamp SingleVerDataSync::GetMaxSendDataTime(const std::vector &inData) -{ - TimeStamp stamp = 0; - for (size_t i = 0; i < inData.size(); i++) { - if (inData[i] == nullptr) { - continue; - } - TimeStamp tempStamp = inData[i]->GetTimestamp(); - if (stamp < tempStamp) { - stamp = tempStamp; - } - } - return stamp; -} - SyncTimeRange SingleVerDataSync::GetSyncDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, const std::vector &inData, UpdateWaterMark &isUpdate) { @@ -437,99 +402,7 @@ SyncTimeRange SingleVerDataSync::GetSyncDataTimeRange(SyncType syncType, SingleV WaterMark deleteMark = 0; GetLocalWaterMark(syncType, context->GetQuerySyncId(), context, localMark); GetLocalDeleteSyncWaterMark(context, deleteMark); - if (syncType != SyncType::QUERY_SYNC_TYPE) { - return GetFullSyncDataTimeRange(inData, localMark, isUpdate); - } - return GetQuerySyncDataTimeRange(inData, localMark, deleteMark, isUpdate); -} - -SyncTimeRange SingleVerDataSync::GetRecvDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, - const std::vector &data, UpdateWaterMark &isUpdate) -{ - if (syncType != SyncType::QUERY_SYNC_TYPE) { - return GetFullSyncDataTimeRange(data, 0, isUpdate); - } - return GetQuerySyncDataTimeRange(data, 0, 0, isUpdate); -} - -SyncTimeRange SingleVerDataSync::GetFullSyncDataTimeRange(const std::vector &inData, - WaterMark localMark, UpdateWaterMark &isUpdate) -{ - TimeStamp maxTimeStamp = localMark; - TimeStamp minTimeStamp = localMark; - for (size_t i = 0; i < inData.size(); i++) { - if (inData[i] == nullptr) { - continue; - } - TimeStamp tempStamp = inData[i]->GetTimestamp(); - if (maxTimeStamp < tempStamp) { - maxTimeStamp = tempStamp; - } - if (minTimeStamp > tempStamp) { - minTimeStamp = tempStamp; - } - isUpdate.normalUpdateMark = true; - } - return {minTimeStamp, 0, maxTimeStamp, 0}; -} - -SyncTimeRange SingleVerDataSync::GetQuerySyncDataTimeRange(const std::vector &inData, - WaterMark localMark, WaterMark deletelocalMark, UpdateWaterMark &isUpdate) -{ - SyncTimeRange dataTimeRange = {localMark, deletelocalMark, localMark, deletelocalMark}; - for (size_t i = 0; i < inData.size(); i++) { - if (inData[i] == nullptr) { - continue; - } - TimeStamp tempStamp = inData[i]->GetTimestamp(); - if ((inData[i]->GetFlag() & DataItem::DELETE_FLAG) == 0) { // query data - if (dataTimeRange.endTime < tempStamp) { - dataTimeRange.endTime = tempStamp; - } - if (dataTimeRange.beginTime > tempStamp) { - dataTimeRange.beginTime = tempStamp; - } - isUpdate.normalUpdateMark = true; - } - if ((inData[i]->GetFlag() & DataItem::DELETE_FLAG) != 0) { // delete data - if (dataTimeRange.deleteEndTime < tempStamp) { - dataTimeRange.deleteEndTime = tempStamp; - } - if (dataTimeRange.deleteBeginTime > tempStamp) { - dataTimeRange.deleteBeginTime = tempStamp; - } - isUpdate.deleteUpdateMark = true; - } - } - return dataTimeRange; -} - -TimeStamp SingleVerDataSync::GetMinSendDataTime(const std::vector &inData, WaterMark localMark) -{ - TimeStamp stamp = localMark; - for (size_t i = 0; i < inData.size(); i++) { - if (inData[i] == nullptr) { - continue; - } - TimeStamp tempStamp = inData[i]->GetTimestamp(); - if (stamp > tempStamp) { - stamp = tempStamp; - } - } - return stamp; -} - -SyncTimeRange SingleVerDataSync::ReviseLocalMark(SyncType syncType, SyncTimeRange &dataTimeRange, - UpdateWaterMark updateMark) -{ - SyncTimeRange tmpDataTime = dataTimeRange; - if (updateMark.deleteUpdateMark && syncType == SyncType::QUERY_SYNC_TYPE) { - tmpDataTime.deleteEndTime += 1; - } - if (updateMark.normalUpdateMark) { - tmpDataTime.endTime += 1; - } - return tmpDataTime; + return SingleVerDataSyncUtils::GetSyncDataTimeRange(syncType, localMark, deleteMark, inData, isUpdate); } int SingleVerDataSync::SaveLocalWaterMark(SyncType syncType, const SingleVerSyncTaskContext *context, @@ -694,49 +567,6 @@ int SingleVerDataSync::DealRemoveDeviceDataByAck(SingleVerSyncTaskContext *conte return errCode; } -void SingleVerDataSync::TransDbDataItemToSendDataItem(const SingleVerSyncTaskContext *context, - std::vector &outData) -{ - std::string localHashName = DBCommon::TransferHashString(GetLocalDeviceName()); - for (size_t i = 0; i < outData.size(); i++) { - if (outData[i] == nullptr) { - continue; - } - outData[i]->SetOrigDevice(outData[i]->GetOrigDevice().empty() ? localHashName : outData[i]->GetOrigDevice()); - if (i == 0 || i == (outData.size() - 1)) { - LOGD("[DataSync][TransToSendItem] printData packet=%d,timeStamp=%llu,flag=%llu", i, - outData[i]->GetTimestamp(), outData[i]->GetFlag()); - } - } -} - -void SingleVerDataSync::TransSendDataItemToLocal(const SingleVerSyncTaskContext *context, - const std::vector &data) -{ - TimeOffset offset = context->GetTimeOffset(); - TimeStamp currentLocalTime = context->GetCurrentLocalTime(); - const std::string localHashName = DBCommon::TransferHashString(GetLocalDeviceName()); - for (auto &item : data) { - if (item == nullptr) { - continue; - } - item->SetOrigDevice(TransferForeignOrigDevName(item->GetOrigDevice(), localHashName)); - TimeStamp tempTimestamp = item->GetTimestamp(); - TimeStamp tempWriteTimestamp = item->GetWriteTimestamp(); - item->SetTimestamp(tempTimestamp - offset); - if (tempWriteTimestamp != 0) { - item->SetWriteTimestamp(tempWriteTimestamp - offset); - } - - if (item->GetTimestamp() > currentLocalTime) { - item->SetTimestamp(currentLocalTime); - } - if (item->GetWriteTimestamp() > currentLocalTime) { - item->SetWriteTimestamp(currentLocalTime); - } - } -} - void SingleVerDataSync::SetSessionEndTimeStamp(TimeStamp end) { sessionEndTimeStamp_ = end; @@ -807,7 +637,7 @@ void SingleVerDataSync::FillDataRequestPacket(DataRequestPacket *packet, SingleV packet->SetCompressDataMark(); packet->SetCompressAlgo(curAlgo); } - SetPacketId(packet, context, version); + SingleVerDataSyncUtils::SetPacketId(packet, context, version); if (curType == SyncType::QUERY_SYNC_TYPE && (context->GetQuery().HasLimit() || context->GetQuery().HasOrderBy())) { packet->SetUpdateWaterMark(); @@ -819,7 +649,7 @@ void SingleVerDataSync::FillDataRequestPacket(DataRequestPacket *packet, SingleV int SingleVerDataSync::RequestStart(SingleVerSyncTaskContext *context, int mode) { - if (!QuerySyncCheck(context)) { + if (!SingleVerDataSyncUtils::QuerySyncCheck(context)) { context->SetTaskErrCode(-E_NOT_SUPPORT); return -E_NOT_SUPPORT; } @@ -831,9 +661,9 @@ int SingleVerDataSync::RequestStart(SingleVerSyncTaskContext *context, int mode) SyncEntry syncData; // get data errCode = GetDataWithPerformanceRecord(context, syncData); - TranslateErrCodeIfNeed(mode, context->GetRemoteSoftwareVersion(), errCode); + SingleVerDataSyncUtils::TranslateErrCodeIfNeed(mode, context->GetRemoteSoftwareVersion(), errCode); - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { LOGE("[DataSync][PushStart] get data failed, errCode=%d", errCode); return errCode; } @@ -864,21 +694,12 @@ int SingleVerDataSync::RequestStart(SingleVerSyncTaskContext *context, int mode) LOGI("[DataSync][RequestStart] query contain limit/offset/orderby, no need to update watermark."); return E_OK; } - SyncTimeRange tmpDataTime = ReviseLocalMark(curType, dataTime, isUpdateWaterMark); + SyncTimeRange tmpDataTime = SingleVerDataSyncUtils::ReviseLocalMark(curType, dataTime, isUpdateWaterMark); SaveLocalWaterMark(curType, context, tmpDataTime); } return errCode; } -void SingleVerDataSync::TranslateErrCodeIfNeed(int mode, uint32_t version, int &errCode) -{ - // once get data occur E_EKEYREVOKED error, should also send request to remote dev to pull data. - if (SyncOperation::TransferSyncMode(mode) == SyncModeType::PUSH_AND_PULL && - version > SOFTWARE_VERSION_RELEASE_2_0 && errCode == -E_EKEYREVOKED) { - errCode = E_OK; - } -} - int SingleVerDataSync::PushStart(SingleVerSyncTaskContext *context) { if (context == nullptr) { @@ -902,7 +723,7 @@ int SingleVerDataSync::PullRequestStart(SingleVerSyncTaskContext *context) if (context == nullptr) { return -E_INVALID_ARGS; } - if (!QuerySyncCheck(context)) { + if (!SingleVerDataSyncUtils::QuerySyncCheck(context)) { context->SetTaskErrCode(-E_NOT_SUPPORT); return -E_NOT_SUPPORT; } @@ -935,7 +756,7 @@ int SingleVerDataSync::PullRequestStart(SingleVerSyncTaskContext *context) packet->SetQuery(context->GetQuery()); packet->SetQueryId(context->GetQuerySyncId()); packet->SetLastSequence(); - SetPacketId(packet, context, version); + SingleVerDataSyncUtils::SetPacketId(packet, context, version); LOGD("[DataSync][Pull] curType=%d,local=%llu,del=%llu,end=%llu,peer=%llu,label=%s,dev=%s", syncType, localMark, deleteMark, peerMark, endMark, label_.c_str(), STR_MASK(GetDeviceId())); @@ -951,7 +772,7 @@ int SingleVerDataSync::PullResponseStart(SingleVerSyncTaskContext *context) SyncEntry syncData; // get data int errCode = GetDataWithPerformanceRecord(context, syncData); - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_RELEASE_2_0) { SendPullResponseDataPkt(errCode, syncData, context); } @@ -981,7 +802,7 @@ int SingleVerDataSync::PullResponseStart(SingleVerSyncTaskContext *context) LOGI("[DataSync][PullResponseStart] query contain limit/offset/orderby, no need to update watermark."); return E_OK; } - SyncTimeRange tmpDataTime = ReviseLocalMark(curType, dataTime, isUpdateWaterMark); + SyncTimeRange tmpDataTime = SingleVerDataSyncUtils::ReviseLocalMark(curType, dataTime, isUpdateWaterMark); SaveLocalWaterMark(curType, context, tmpDataTime); } return errCode; @@ -1085,7 +906,7 @@ int SingleVerDataSync::DataRequestRecvPre(SingleVerSyncTaskContext *context, con errCode = CheckSchemaStrategy(context, message); } if (errCode == E_OK) { - errCode = RequestQueryCheck(packet); + errCode = SingleVerDataSyncUtils::RequestQueryCheck(packet, storage_); } if (errCode != E_OK) { (void)SendDataAck(context, message, errCode, 0); @@ -1108,7 +929,7 @@ int SingleVerDataSync::DataRequestRecv(SingleVerSyncTaskContext *context, const STR_MASK(GetDeviceId())); context->SetReceiveWaterMarkErr(false); UpdateWaterMark isUpdateWaterMark; - SyncTimeRange dataTime = GetRecvDataTimeRange(curType, context, data, isUpdateWaterMark); + SyncTimeRange dataTime = SingleVerDataSyncUtils::GetRecvDataTimeRange(curType, context, data, isUpdateWaterMark); errCode = RemoveDeviceDataHandle(context, message, dataTime.endTime); if (errCode != E_OK) { return errCode; @@ -1149,14 +970,14 @@ int SingleVerDataSync::DataRequestRecv(SingleVerSyncTaskContext *context, const int SingleVerDataSync::SendDataPacket(SyncType syncType, const DataRequestPacket *packet, SingleVerSyncTaskContext *context) { - Message *message = new (std::nothrow) Message(GetMessageId(syncType)); + Message *message = new (std::nothrow) Message(SingleVerDataSyncUtils::GetMessageId(syncType)); if (message == nullptr) { LOGE("[DataSync][SendDataPacket] new message error"); delete packet; packet = nullptr; return -E_OUT_OF_MEMORY; } - uint32_t packetLen = packet->CalculateLen(GetMessageId(syncType)); + uint32_t packetLen = packet->CalculateLen(SingleVerDataSyncUtils::GetMessageId(syncType)); int errCode = message->SetExternalObject(packet); if (errCode != E_OK) { delete packet; @@ -1166,8 +987,8 @@ int SingleVerDataSync::SendDataPacket(SyncType syncType, const DataRequestPacket LOGE("[DataSync][SendDataPacket] set external object failed errCode=%d", errCode); return errCode; } - SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), context->GetSequenceId(), - context->GetRequestSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), + context->GetSequenceId(), context->GetRequestSessionId()); PerformanceAnalysis *performance = PerformanceAnalysis::GetInstance(); if (performance != nullptr) { performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_DATA_SEND_REQUEST_TO_ACK_RECV); @@ -1193,8 +1014,8 @@ int SingleVerDataSync::SendPullResponseDataPkt(int ackCode, SyncEntry &syncOutDa } SyncType syncType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; FillDataRequestPacket(packet, context, syncOutData, ackCode, SyncModeType::RESPONSE_PULL); - uint32_t packetLen = packet->CalculateLen(GetMessageId(syncType)); - Message *message = new (std::nothrow) Message(GetMessageId(syncType)); + uint32_t packetLen = packet->CalculateLen(SingleVerDataSyncUtils::GetMessageId(syncType)); + Message *message = new (std::nothrow) Message(SingleVerDataSyncUtils::GetMessageId(syncType)); if (message == nullptr) { LOGE("[DataSync][SendPullResponseDataPkt] new message error"); delete packet; @@ -1210,8 +1031,8 @@ int SingleVerDataSync::SendPullResponseDataPkt(int ackCode, SyncEntry &syncOutDa LOGE("[SendPullResponseDataPkt] set external object failed, errCode=%d", errCode); return errCode; } - SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), context->GetSequenceId(), - context->GetResponseSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), + context->GetSequenceId(), context->GetResponseSessionId()); SendResetWatchDogPacket(context, packetLen); errCode = Send(context, message, nullptr, packetLen); if (errCode != E_OK) { @@ -1247,8 +1068,8 @@ int SingleVerDataSync::SendDataAck(SingleVerSyncTaskContext *context, const Mess LOGE("[DataSync][SendDataAck] set copied object failed, errcode=%d", errCode); return errCode; } - SetMessageHeadInfo(*ackMessage, TYPE_RESPONSE, context->GetDeviceId(), message->GetSequenceId(), - message->GetSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*ackMessage, TYPE_RESPONSE, context->GetDeviceId(), + message->GetSequenceId(), message->GetSessionId()); errCode = Send(context, ackMessage, nullptr, 0); if (errCode != E_OK) { @@ -1286,7 +1107,7 @@ bool SingleVerDataSync::AckPacketIdCheck(const Message *message) int SingleVerDataSync::AckRecv(SingleVerSyncTaskContext *context, const Message *message) { - int errCode = AckMsgErrnoCheck(context, message); + int errCode = SingleVerDataSyncUtils::AckMsgErrnoCheck(context, message); if (errCode != E_OK) { return errCode; } @@ -1362,7 +1183,7 @@ void SingleVerDataSync::SendSaveDataNotifyPacket(SingleVerSyncTaskContext *conte LOGE("[DataSync][SendSaveDataNotifyPacket] set copied object failed,errcode=%d", errCode); return; } - SetMessageHeadInfo(*ackMessage, TYPE_NOTIFY, context->GetDeviceId(), sequenceId, sessionId); + SingleVerDataSyncUtils::SetMessageHeadInfo(*ackMessage, TYPE_NOTIFY, context->GetDeviceId(), sequenceId, sessionId); errCode = Send(context, ackMessage, nullptr, 0); if (errCode != E_OK) { @@ -1384,7 +1205,7 @@ void SingleVerDataSync::GetPullEndWatermark(const SingleVerSyncTaskContext *cont WaterMark endMark = packet->GetEndWaterMark(); TimeOffset offset; metadata_->GetTimeOffset(context->GetDeviceId(), offset); - pullEndWatermark = endMark - offset; + pullEndWatermark = endMark - static_cast(offset); LOGD("[DataSync][PullEndWatermark] packetEndMark=%llu,offset=%llu,endWaterMark=%llu,label=%s,dev=%s", endMark, offset, pullEndWatermark, label_.c_str(), STR_MASK(GetDeviceId())); } @@ -1411,7 +1232,7 @@ int SingleVerDataSync::DealWaterMarkException(SingleVerSyncTaskContext *context, } context->SetRetryStatus(SyncTaskContext::NEED_RETRY); context->IncNegotiationCount(); - PushAndPUllKeyRevokHandle(context); + SingleVerDataSyncUtils::PushAndPullKeyRevokHandle(context); if (!context->IsNeedClearRemoteStaleData()) { return -E_RE_SEND_DATA; } @@ -1425,40 +1246,20 @@ int SingleVerDataSync::DealWaterMarkException(SingleVerSyncTaskContext *context, int SingleVerDataSync::RunPermissionCheck(SingleVerSyncTaskContext *context, const Message *message, const DataRequestPacket *packet) { - std::string appId = storage_->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); - std::string userId = storage_->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); - std::string storeId = storage_->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); - uint8_t flag; int mode = SyncOperation::TransferSyncMode(packet->GetMode()); - if (mode == SyncModeType::PUSH) { - flag = CHECK_FLAG_RECEIVE; - } else if (mode == SyncModeType::PULL) { - flag = CHECK_FLAG_SEND; - } else if (mode == SyncModeType::PUSH_AND_PULL) { - flag = CHECK_FLAG_SEND | CHECK_FLAG_RECEIVE; - } else { - // before add permissionCheck, PushStart packet and pullResponse packet do not setMode. - flag = CHECK_FLAG_RECEIVE; - } - int errCode = E_OK; - if (storage_->GetInterfaceType() != ISyncInterface::SYNC_RELATION) { - errCode = RuntimeContext::GetInstance()->RunPermissionCheck(userId, appId, storeId, context->GetDeviceId(), - flag); - } + int errCode = SingleVerDataSyncUtils::RunPermissionCheck(context, storage_, label_, mode); if (errCode != E_OK) { - LOGE("[DataSync][RunPermissionCheck] check failed flag=%d,Label=%s,dev=%s", flag, label_.c_str(), - STR_MASK(GetDeviceId())); if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_EARLIEST) { // ver 101 can't handle this errCode (void)SendDataAck(context, message, -E_NOT_PERMIT, 0); } return -E_NOT_PERMIT; } const std::vector &data = packet->GetData(); - WaterMark maxSendDataTime = GetMaxSendDataTime(data); + WaterMark maxSendDataTime = SingleVerDataSyncUtils::GetMaxSendDataTime(data); uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); if (version > SOFTWARE_VERSION_RELEASE_2_0 && (mode != SyncModeType::PULL) && !context->GetReceivcPermitCheck()) { - bool permitReceive = CheckPermitReceiveData(context); + bool permitReceive = SingleVerDataSyncUtils::CheckPermitReceiveData(context, communicateHandle_); if (permitReceive) { context->SetReceivcPermitCheck(true); } else { @@ -1496,8 +1297,8 @@ void SingleVerDataSync::SendResetWatchDogPacket(SingleVerSyncTaskContext *contex LOGE("[DataSync][ResetWatchDog] set copied object failed, errcode=%d", errCode); return; } - SetMessageHeadInfo(*ackMessage, TYPE_NOTIFY, context->GetDeviceId(), context->GetSequenceId(), - context->GetResponseSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*ackMessage, TYPE_NOTIFY, context->GetDeviceId(), + context->GetSequenceId(), context->GetResponseSessionId()); errCode = Send(context, ackMessage, nullptr, 0); if (errCode != E_OK) { @@ -1517,7 +1318,7 @@ int32_t SingleVerDataSync::ReSend(SingleVerSyncTaskContext *context, DataSyncReS } SyncEntry syncData; int errCode = GetReSendData(syncData, context, reSendInfo); - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { return errCode; } SyncType curType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; @@ -1546,14 +1347,14 @@ int SingleVerDataSync::SendReSendPacket(const DataRequestPacket *packet, SingleV uint32_t sessionId, uint32_t sequenceId) { SyncType syncType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; - Message *message = new (std::nothrow) Message(GetMessageId(syncType)); + Message *message = new (std::nothrow) Message(SingleVerDataSyncUtils::GetMessageId(syncType)); if (message == nullptr) { LOGE("[DataSync][SendDataPacket] new message error"); delete packet; packet = nullptr; return -E_OUT_OF_MEMORY; } - uint32_t packetLen = packet->CalculateLen(GetMessageId(syncType)); + uint32_t packetLen = packet->CalculateLen(SingleVerDataSyncUtils::GetMessageId(syncType)); int errCode = message->SetExternalObject(packet); if (errCode != E_OK) { delete packet; @@ -1563,7 +1364,7 @@ int SingleVerDataSync::SendReSendPacket(const DataRequestPacket *packet, SingleV LOGE("[DataSync][SendReSendPacket] SetExternalObject failed errCode=%d", errCode); return errCode; } - SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), sequenceId, sessionId); + SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), sequenceId, sessionId); CommErrHandler handler = std::bind(&SyncTaskContext::CommErrHandlerFunc, std::placeholders::_1, context, message->GetSessionId()); errCode = Send(context, message, handler, packetLen); @@ -1574,26 +1375,6 @@ int SingleVerDataSync::SendReSendPacket(const DataRequestPacket *packet, SingleV return errCode; } -bool SingleVerDataSync::IsPermitRemoteDeviceRecvData(const std::string &deviceId, - const SecurityOption &remoteSecOption) const -{ - SecurityOption localSecOption; - if (remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { - return true; - } - int errCode = storage_->GetSecurityOption(localSecOption); - if (errCode == -E_NOT_SUPPORT) { - return true; - } - return RuntimeContext::GetInstance()->CheckDeviceSecurityAbility(deviceId, localSecOption); -} - -bool SingleVerDataSync::IsPermitLocalDeviceRecvData(const std::string &deviceId, - const SecurityOption &remoteSecOption) const -{ - return RuntimeContext::GetInstance()->CheckDeviceSecurityAbility(deviceId, remoteSecOption); -} - int SingleVerDataSync::CheckPermitSendData(int inMode, SingleVerSyncTaskContext *context) { uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); @@ -1609,7 +1390,7 @@ int SingleVerDataSync::CheckPermitSendData(int inMode, SingleVerSyncTaskContext std::string deviceId = context->GetDeviceId(); SecurityOption remoteSecOption = context->GetRemoteSeccurityOption(); if (mode == SyncModeType::PUSH || mode == SyncModeType::PUSH_AND_PULL || mode == SyncModeType::RESPONSE_PULL) { - isPermitSync = IsPermitRemoteDeviceRecvData(deviceId, remoteSecOption); + isPermitSync = SingleVerDataSyncUtils::IsPermitRemoteDeviceRecvData(deviceId, remoteSecOption, storage_); } LOGI("[DataSync][PermitSendData] mode=%d,dev=%s,label=%d,flag=%d,PermitSync=%d", mode, STR_MASK(deviceId_), remoteSecOption.securityLabel, remoteSecOption.securityFlag, isPermitSync); @@ -1673,23 +1454,6 @@ bool SingleVerDataSync::WaterMarkErrHandle(SyncType syncType, SingleVerSyncTaskC return false; } -bool SingleVerDataSync::CheckPermitReceiveData(const SingleVerSyncTaskContext *context) -{ - SecurityOption remoteSecOption = context->GetRemoteSeccurityOption(); - std::string localDeviceId; - if (communicateHandle_ == nullptr || remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { - return true; - } - communicateHandle_->GetLocalIdentity(localDeviceId); - bool isPermitSync = IsPermitLocalDeviceRecvData(localDeviceId, remoteSecOption); - if (isPermitSync) { - return isPermitSync; - } - LOGE("[DataSync][PermitReceiveData] check failed: permitReceive=%d, localDev=%s, seclabel=%d, secflag=%d", - isPermitSync, STR_MASK(localDeviceId), remoteSecOption.securityLabel, remoteSecOption.securityFlag); - return isPermitSync; -} - int SingleVerDataSync::CheckSchemaStrategy(SingleVerSyncTaskContext *context, const Message *message) { auto *packet = message->GetObject(); @@ -1724,34 +1488,6 @@ void SingleVerDataSync::RemotePushFinished(int sendCode, int inMode, uint32_t ms } } -void SingleVerDataSync::SetPacketId(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t version) -{ - if (version > SOFTWARE_VERSION_RELEASE_2_0) { - context->IncPacketId(); // begin from 1 - std::vector reserved {context->GetPacketId()}; - packet->SetReserved(reserved); - } -} - -int SingleVerDataSync::GetMessageId(SyncType syncType) const -{ - if (syncType == SyncType::QUERY_SYNC_TYPE) { - return QUERY_SYNC_MESSAGE; - } - return DATA_SYNC_MESSAGE; -} - -void SingleVerDataSync::PushAndPUllKeyRevokHandle(SingleVerSyncTaskContext *context) -{ - // for push_and_pull mode it may be EKEYREVOKED error before receive watermarkexception - // should clear errCode and restart pushpull request. - int mode = SyncOperation::TransferSyncMode(context->GetMode()); - if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_RELEASE_2_0 && mode == SyncModeType::PUSH_AND_PULL && - context->GetTaskErrCode() == -E_EKEYREVOKED) { - context->SetTaskErrCode(E_OK); - } -} - void SingleVerDataSync::SetAckPacket(DataAckPacket &ackPacket, SingleVerSyncTaskContext *context, const DataRequestPacket *packet, int32_t recvCode, WaterMark maxSendDataTime) { @@ -1815,7 +1551,7 @@ int SingleVerDataSync::GetReSendData(SyncEntry &syncData, SingleVerSyncTaskConte context->SetTaskErrCode(errCode); return errCode; } - if (!IsGetDataSuccessfully(errCode)) { + if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { return errCode; } @@ -1839,23 +1575,6 @@ int SingleVerDataSync::GetReSendData(SyncEntry &syncData, SingleVerSyncTaskConte return errCode; } -int SingleVerDataSync::GetReSendMode(int mode, uint32_t sequenceId, SyncType syncType) -{ - int curMode = SyncOperation::TransferSyncMode(mode); - if (curMode == SyncModeType::PUSH || curMode == SyncModeType::PULL) { - return mode; - } - if (curMode == SyncModeType::RESPONSE_PULL) { - return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH : SyncModeType::PUSH; - } - // set push_and_pull mode when resend first sequenceId to inform remote to run RESPONSE_PULL task - // for sequenceId which is larger than first, only need to send data, means to set push or query_push mode - if (sequenceId == 1) { - return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH_PULL : SyncModeType::PUSH_AND_PULL; - } - return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH : SyncModeType::PUSH; -} - int SingleVerDataSync::RemoveDeviceDataIfNeed(SingleVerSyncTaskContext *context) { if (context->GetRemoteSoftwareVersion() <= SOFTWARE_VERSION_RELEASE_3_0) { @@ -1899,7 +1618,7 @@ void SingleVerDataSync::FillRequestReSendPacket(const SingleVerSyncTaskContext * uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); // transer reSend mode, RESPONSE_PULL transfer to push or query push // PUSH_AND_PULL mode which sequenceId lager than first transfer to push or query push - int reSendMode = GetReSendMode(context->GetMode(), reSendInfo.sequenceId, curType); + int reSendMode = SingleVerDataSyncUtils::GetReSendMode(context->GetMode(), reSendInfo.sequenceId, curType); if (GetSessionEndTimeStamp() == std::max(reSendInfo.end, reSendInfo.deleteDataEnd) || SyncOperation::TransferSyncMode(context->GetMode()) == SyncModeType::PULL) { LOGI("[DataSync][ReSend] set lastid,label=%s,dev=%s", label_.c_str(), STR_MASK(GetDeviceId())); @@ -1942,43 +1661,6 @@ DataSizeSpecInfo SingleVerDataSync::GetDataSizeSpecInfo(size_t packetSize) return {blockSize, packetSize}; } -int SingleVerDataSync::AckMsgErrnoCheck(const SingleVerSyncTaskContext *context, const Message *message) const -{ - if (context == nullptr || message == nullptr) { - return -E_INVALID_ARGS; - } - if (message->IsFeedbackError()) { - LOGE("[DataSync][AckMsgErrnoCheck] message errNo=%d", message->GetErrorNo()); - return -(message->GetErrorNo()); - } - return E_OK; -} - -bool SingleVerDataSync::QuerySyncCheck(const SingleVerSyncTaskContext *context) const -{ - if (!context->IsQuerySync()) { - return true; - } - uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); - // for 101 version, no need to do abilitySync, just send request to remote - if (version <= SOFTWARE_VERSION_RELEASE_1_0) { - return true; - } - if (version < SOFTWARE_VERSION_RELEASE_4_0) { - LOGE("[SingleVerDataSync] not support query sync when remote ver lower than 104"); - return false; - } - if (version < SOFTWARE_VERSION_RELEASE_5_0 && !(context->GetQuery().IsQueryOnlyByKey())) { - LOGE("[SingleVerDataSync] remote version only support prefix key"); - return false; - } - if (context->GetQuery().HasInKeys() && - context->GetRemoteDbAbility().GetAbilityItem(INKEYS_QUERY) != SUPPORT_MARK) { - return false; - } - return true; -} - int SingleVerDataSync::InterceptData(SyncEntry &syncEntry) { if (storage_ == nullptr) { @@ -1992,20 +1674,6 @@ int SingleVerDataSync::InterceptData(SyncEntry &syncEntry) return storage_->InterceptData(syncEntry.entries, GetLocalDeviceName(), GetDeviceId()); } -int SingleVerDataSync::RequestQueryCheck(const DataRequestPacket *packet) const -{ - if (SyncOperation::GetSyncType(packet->GetMode()) != SyncType::QUERY_SYNC_TYPE) { - return E_OK; - } - QuerySyncObject syncQuery = packet->GetQuery(); - int errCode = storage_->CheckAndInitQueryCondition(syncQuery); - if (errCode != E_OK) { - LOGE("[SingleVerDataSync] check sync query failed,errCode=%d", errCode); - return errCode; - } - return E_OK; -} - int SingleVerDataSync::ControlCmdStart(SingleVerSyncTaskContext *context) { if (context == nullptr) { @@ -2033,7 +1701,7 @@ int SingleVerDataSync::ControlCmdStart(SingleVerSyncTaskContext *context) return errCode; } } - FillControlRequestPacket(packet, context); + SingleVerDataSyncUtils::FillControlRequestPacket(packet, context); errCode = SendControlPacket(packet, context); if (errCode != E_OK && context->GetMode() == SyncModeType::SUBSCRIBE_QUERY) { subManager->DeleteLocalSubscribeQuery(context->GetDeviceId(), context->GetQuery()); @@ -2067,9 +1735,9 @@ int SingleVerDataSync::ControlCmdAckRecv(SingleVerSyncTaskContext *context, cons if (subManager == nullptr) { return -E_INVALID_ARGS; } - int errCode = AckMsgErrnoCheck(context, message); + int errCode = SingleVerDataSyncUtils::AckMsgErrnoCheck(context, message); if (errCode != E_OK) { - ControlAckErrorHandle(context, subManager); + SingleVerDataSyncUtils::ControlAckErrorHandle(context, subManager); return errCode; } const ControlAckPacket *packet = message->GetObject(); @@ -2082,7 +1750,7 @@ int SingleVerDataSync::ControlCmdAckRecv(SingleVerSyncTaskContext *context, cons LOGE("[DataSync][AckRecv] control sync abort,recvCode=%d,label=%s,dev=%s,type=%u", recvCode, label_.c_str(), STR_MASK(GetDeviceId()), cmdType); // for unsubscribe no need to do something - ControlAckErrorHandle(context, subManager); + SingleVerDataSyncUtils::ControlAckErrorHandle(context, subManager); return recvCode; } if (cmdType == ControlCmdType::SUBSCRIBE_QUERY_CMD) { @@ -2106,13 +1774,13 @@ int SingleVerDataSync::ControlCmdStartCheck(SingleVerSyncTaskContext *context) } if (context->GetMode() == SyncModeType::SUBSCRIBE_QUERY && context->GetQuery().HasInKeys() && - context->GetRemoteDbAbility().GetAbilityItem(INKEYS_QUERY) != SUPPORT_MARK) { + context->GetRemoteDbAbility().GetAbilityItem(SyncConfig::INKEYS_QUERY) != SUPPORT_MARK) { return -E_NOT_SUPPORT; } if ((context->GetMode() != SyncModeType::SUBSCRIBE_QUERY) || context->GetReceivcPermitCheck()) { return E_OK; } - bool permitReceive = CheckPermitReceiveData(context); + bool permitReceive = SingleVerDataSyncUtils::CheckPermitReceiveData(context, communicateHandle_); if (permitReceive) { context->SetReceivcPermitCheck(true); } else { @@ -2121,17 +1789,6 @@ int SingleVerDataSync::ControlCmdStartCheck(SingleVerSyncTaskContext *context) return E_OK; } -void SingleVerDataSync::FillControlRequestPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context) -{ - uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); - uint32_t flag = 0; - if (context->GetMode() == SyncModeType::SUBSCRIBE_QUERY && context->IsAutoSubscribe()) { - flag = flag | SubscribeRequest::IS_AUTO_SUBSCRIBE; - } - packet->SetPacketHead(E_OK, version, GetControlCmdType(context->GetMode()), flag); - packet->SetQuery(context->GetQuery()); -} - int SingleVerDataSync::SendControlPacket(const ControlRequestPacket *packet, SingleVerSyncTaskContext *context) { Message *message = new (std::nothrow) Message(CONTROL_SYNC_MESSAGE); @@ -2151,8 +1808,8 @@ int SingleVerDataSync::SendControlPacket(const ControlRequestPacket *packet, Sin LOGE("[DataSync][SendControlPacket] set external object failed errCode=%d", errCode); return errCode; } - SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), context->GetSequenceId(), - context->GetRequestSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), + context->GetSequenceId(), context->GetRequestSessionId()); CommErrHandler handler = std::bind(&SyncTaskContext::CommErrHandlerFunc, std::placeholders::_1, context, message->GetSessionId()); errCode = Send(context, message, handler, packetLen); @@ -2163,26 +1820,6 @@ int SingleVerDataSync::SendControlPacket(const ControlRequestPacket *packet, Sin return errCode; } -ControlCmdType SingleVerDataSync::GetControlCmdType(int mode) -{ - if (mode == SyncModeType::SUBSCRIBE_QUERY) { - return ControlCmdType::SUBSCRIBE_QUERY_CMD; - } else if (mode == SyncModeType::UNSUBSCRIBE_QUERY) { - return ControlCmdType::UNSUBSCRIBE_QUERY_CMD; - } - return ControlCmdType::INVALID_CONTROL_CMD; -} - -int SingleVerDataSync::GetModeByControlCmdType(ControlCmdType controlCmd) -{ - if (controlCmd == ControlCmdType::SUBSCRIBE_QUERY_CMD) { - return SyncModeType::SUBSCRIBE_QUERY; - } else if (controlCmd == ControlCmdType::UNSUBSCRIBE_QUERY_CMD) { - return SyncModeType::UNSUBSCRIBE_QUERY; - } - return SyncModeType::INVALID_MODE; -} - int SingleVerDataSync::SendControlAck(SingleVerSyncTaskContext *context, const Message *message, int32_t recvCode, uint32_t controlCmdType, const CommErrHandler &handler) { @@ -2193,7 +1830,7 @@ int SingleVerDataSync::SendControlAck(SingleVerSyncTaskContext *context, const M } uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); ControlAckPacket ack; - ack.SetPacketHead(recvCode, version, controlCmdType, 0); + ack.SetPacketHead(recvCode, version, static_cast(controlCmdType), 0); int errCode = ackMessage->SetCopiedObject(ack); if (errCode != E_OK) { delete ackMessage; @@ -2201,8 +1838,8 @@ int SingleVerDataSync::SendControlAck(SingleVerSyncTaskContext *context, const M LOGE("[DataSync][SendControlAck] set copied object failed, errcode=%d", errCode); return errCode; } - SetMessageHeadInfo(*ackMessage, TYPE_RESPONSE, context->GetDeviceId(), message->GetSequenceId(), - message->GetSessionId()); + SingleVerDataSyncUtils::SetMessageHeadInfo(*ackMessage, TYPE_RESPONSE, context->GetDeviceId(), + message->GetSequenceId(), message->GetSessionId()); errCode = Send(context, ackMessage, handler, 0); if (errCode != E_OK) { delete ackMessage; @@ -2248,7 +1885,8 @@ int SingleVerDataSync::SubscribeRequestRecvPre(SingleVerSyncTaskContext *context return -E_WAIT_NEXT_MESSAGE; } } - int mode = GetModeByControlCmdType(static_cast(packet->GetcontrolCmdType())); + int mode = SingleVerDataSyncUtils::GetModeByControlCmdType( + static_cast(packet->GetcontrolCmdType())); if (mode >= SyncModeType::INVALID_MODE) { LOGE("[SingleVerDataSync] invalid mode"); SendControlAck(context, message, -E_INVALID_ARGS, controlCmdType); @@ -2340,40 +1978,6 @@ int SingleVerDataSync::UnsubscribeRequestRecv(SingleVerSyncTaskContext *context, return errCode; } -bool SingleVerDataSync::IsNeedTriggerQueryAutoSync(Message *inMsg, QuerySyncObject &query) -{ - if (inMsg == nullptr) { - return false; - } - if (inMsg->GetMessageId() != CONTROL_SYNC_MESSAGE) { - return false; - } - const ControlRequestPacket *packet = inMsg->GetObject(); - if (packet == nullptr) { - return false; - } - uint32_t controlCmdType = packet->GetcontrolCmdType(); - if (controlCmdType == ControlCmdType::SUBSCRIBE_QUERY_CMD && inMsg->GetMessageType() == TYPE_REQUEST) { - const SubscribeRequest *subPacket = inMsg->GetObject(); - if (packet == nullptr) { - return false; - } - query = subPacket->GetQuery(); - LOGI("[SingleVerDataSync] receive sub scribe query cmd,begin to trigger query auto sync"); - return true; - } - return false; -} - -void SingleVerDataSync::ControlAckErrorHandle(const SingleVerSyncTaskContext *context, - const std::shared_ptr &subManager) const -{ - if (context->GetMode() == SyncModeType::SUBSCRIBE_QUERY) { - // reserve before need clear - subManager->DeleteLocalSubscribeQuery(context->GetDeviceId(), context->GetQuery()); - } -} - void SingleVerDataSync::PutDataMsg(Message *message) { return msgSchedule_.PutMsg(message); @@ -2399,4 +2003,17 @@ void SingleVerDataSync::ClearDataMsg() { msgSchedule_.ClearMsg(); } + +void SingleVerDataSync::SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, + SendConfig &sendConf) +{ + sendConf.nonBlock = nonBlock; + sendConf.timeout = timeout; + sendConf.isNeedExtendHead = storage_->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + sendConf.paramInfo.appId = storage_->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + sendConf.paramInfo.userId = storage_->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + sendConf.paramInfo.storeId = storage_->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + sendConf.paramInfo.dstTarget = dstTarget; +} } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.h b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.h index 932c7541bdc7ea1d4972ba62d0371a469af85645..54d24f678478b68116441d28d18c403e12b3bde6 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync.h @@ -105,11 +105,6 @@ public: int ControlCmdAckRecv(SingleVerSyncTaskContext *context, const Message *message); - bool IsNeedTriggerQueryAutoSync(Message *inMsg, QuerySyncObject &query); - - void ControlAckErrorHandle(const SingleVerSyncTaskContext *context, - const std::shared_ptr &subManager) const; - void PutDataMsg(Message *message); Message *MoveNextDataMsg(SingleVerSyncTaskContext *context, bool &isNeedHandle, bool &isNeedContinue); @@ -139,10 +134,6 @@ protected: int32_t ReSend(SingleVerSyncTaskContext *context, DataSyncReSendInfo reSendInfo); - TimeStamp GetMaxSendDataTime(const std::vector &inData); - - TimeStamp GetMinSendDataTime(const std::vector &inData, WaterMark localMark); - void SetSessionEndTimeStamp(TimeStamp end); TimeStamp GetSessionEndTimeStamp() const; @@ -152,20 +143,9 @@ protected: int RequestStart(SingleVerSyncTaskContext *context, int mode); - void TranslateErrCodeIfNeed(int mode, uint32_t version, int &errCode); - SyncTimeRange GetSyncDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, const std::vector &inData, UpdateWaterMark &isUpdate); - SyncTimeRange GetRecvDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, - const std::vector &data, UpdateWaterMark &isUpdate); - - SyncTimeRange GetFullSyncDataTimeRange(const std::vector &inData, WaterMark localMark, - UpdateWaterMark &isUpdate); - - SyncTimeRange GetQuerySyncDataTimeRange(const std::vector &inData, WaterMark localMark, - WaterMark deletelocalMark, UpdateWaterMark &isUpdate); - int GetData(SingleVerSyncTaskContext *context, std::vector &outData, size_t packetSize); int GetDataWithPerformanceRecord(SingleVerSyncTaskContext *context, SyncEntry &syncOutData); @@ -177,13 +157,9 @@ protected: int GetNextUnsyncData(SingleVerSyncTaskContext *context, std::vector &outData, size_t packetSize); - int GetMessageId(SyncType syncType) const; - int SaveData(const SingleVerSyncTaskContext *context, const std::vector &inData, SyncType curType, const QuerySyncObject &query); - SyncTimeRange ReviseLocalMark(SyncType syncType, SyncTimeRange &dataTimeRange, UpdateWaterMark updateMark); - int SaveLocalWaterMark(SyncType syncType, const SingleVerSyncTaskContext *context, SyncTimeRange dataTimeRange, bool isCheckBeforUpdate = false) const; @@ -202,12 +178,6 @@ protected: int DealRemoveDeviceDataByAck(SingleVerSyncTaskContext *context, WaterMark ackWaterMark, const std::vector &reserved); - void TransSendDataItemToLocal(const SingleVerSyncTaskContext *context, - const std::vector &data); - - void TransDbDataItemToSendDataItem(const SingleVerSyncTaskContext *context, - std::vector &outData); - int SendDataPacket(SyncType syncType, const DataRequestPacket *packet, SingleVerSyncTaskContext *context); void UpdateQueryPeerWaterMark(SyncType syncType, const std::string &queryId, SyncTimeRange &dataTime, @@ -218,8 +188,6 @@ protected: std::string GetLocalDeviceName(); - std::string TransferForeignOrigDevName(const std::string &deviceName, const std::string &localHashName); - int DoAbilitySyncIfNeed(SingleVerSyncTaskContext *context, const Message *message, bool isControlMsg = false); int DataRequestRecvPre(SingleVerSyncTaskContext *context, const Message *message); @@ -240,20 +208,10 @@ protected: int SendPullResponseDataPkt(int ackCode, SyncEntry &syncOutData, SingleVerSyncTaskContext *context); - void SetPacketId(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t version); - - bool IsPermitRemoteDeviceRecvData(const std::string &deviceId, const SecurityOption &secOption) const; - - bool IsPermitLocalDeviceRecvData(const std::string &deviceId, const SecurityOption &remoteSecOption) const; - - bool CheckPermitReceiveData(const SingleVerSyncTaskContext *context); - int CheckSchemaStrategy(SingleVerSyncTaskContext *context, const Message *message); void RemotePushFinished(int sendCode, int inMode, uint32_t msgSessionId, uint32_t contextSessionId); - void PushAndPUllKeyRevokHandle(SingleVerSyncTaskContext *context); - void SetAckPacket(DataAckPacket &ackPacket, SingleVerSyncTaskContext *context, const DataRequestPacket *packet, int32_t recvCode, WaterMark maxSendDataTime); @@ -262,8 +220,6 @@ protected: virtual int RemoveDeviceDataIfNeed(SingleVerSyncTaskContext *context); - int GetReSendMode(int mode, uint32_t sequenceId, SyncType syncType); - void UpdateSendInfo(SyncTimeRange dataTimeRange, SingleVerSyncTaskContext *context); void FillRequestReSendPacket(const SingleVerSyncTaskContext *context, DataRequestPacket *packet, @@ -273,22 +229,14 @@ protected: DataSizeSpecInfo GetDataSizeSpecInfo(size_t packetSize); - int AckMsgErrnoCheck(const SingleVerSyncTaskContext *context, const Message *message) const; - - bool QuerySyncCheck(const SingleVerSyncTaskContext *context) const; - int InterceptData(SyncEntry &syncEntry); - int RequestQueryCheck(const DataRequestPacket *packet) const; int ControlCmdStartCheck(SingleVerSyncTaskContext *context); void FillControlRequestPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context); int SendControlPacket(const ControlRequestPacket *packet, SingleVerSyncTaskContext *context); - ControlCmdType GetControlCmdType(int mode); - int GetModeByControlCmdType(ControlCmdType controlCmd); - int ControlCmdRequestRecvPre(SingleVerSyncTaskContext *context, const Message *message); int SubscribeRequestRecvPre(SingleVerSyncTaskContext *context, const SubscribeRequest *packet, const Message *message); @@ -297,6 +245,8 @@ protected: int SendControlAck(SingleVerSyncTaskContext *context, const Message *message, int32_t recvCode, uint32_t controlCmdType, const CommErrHandler &handler = nullptr); + void SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, SendConfig &sendConf); + uint32_t mtuSize_; SyncGenericInterface* storage_; ICommunicator* communicateHandle_; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea0ff39abc64ee97fda2014b966c9295720245f4 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "single_ver_data_sync_utils.h" + +#include +#include "db_common.h" +#include "version.h" +#include "log_print.h" +#include "message.h" +namespace DistributedDB { +bool SingleVerDataSyncUtils::QuerySyncCheck(const SingleVerSyncTaskContext *context) +{ + if (!context->IsQuerySync()) { + return true; + } + uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); + // for 101 version, no need to do abilitySync, just send request to remote + if (version <= SOFTWARE_VERSION_RELEASE_1_0) { + return true; + } + if (version < SOFTWARE_VERSION_RELEASE_4_0) { + LOGE("[SingleVerDataSync] not support query sync when remote ver lower than 104"); + return false; + } + if (version < SOFTWARE_VERSION_RELEASE_5_0 && !(context->GetQuery().IsQueryOnlyByKey())) { + LOGE("[SingleVerDataSync] remote version only support prefix key"); + return false; + } + if (context->GetQuery().HasInKeys() && + context->GetRemoteDbAbility().GetAbilityItem(SyncConfig::INKEYS_QUERY) != SUPPORT_MARK) { + return false; + } + return true; +} + +int SingleVerDataSyncUtils::AckMsgErrnoCheck(const SingleVerSyncTaskContext *context, const Message *message) +{ + if (context == nullptr || message == nullptr) { + return -E_INVALID_ARGS; + } + if (message->IsFeedbackError()) { + LOGE("[DataSync][AckMsgErrnoCheck] message errNo=%d", message->GetErrorNo()); + return -static_cast(message->GetErrorNo()); + } + return E_OK; +} + +int SingleVerDataSyncUtils::RequestQueryCheck(const DataRequestPacket *packet, SyncGenericInterface *storage) +{ + if (storage == nullptr || packet == nullptr) { + return -E_INVALID_ARGS; + } + if (SyncOperation::GetSyncType(packet->GetMode()) != SyncType::QUERY_SYNC_TYPE) { + return E_OK; + } + QuerySyncObject syncQuery = packet->GetQuery(); + int errCode = storage->CheckAndInitQueryCondition(syncQuery); + if (errCode != E_OK) { + LOGE("[SingleVerDataSync] check sync query failed,errCode=%d", errCode); + return errCode; + } + return E_OK; +} + +bool SingleVerDataSyncUtils::IsPermitLocalDeviceRecvData(const std::string &deviceId, + const SecurityOption &remoteSecOption) +{ + return RuntimeContext::GetInstance()->CheckDeviceSecurityAbility(deviceId, remoteSecOption); +} + +bool SingleVerDataSyncUtils::IsPermitRemoteDeviceRecvData(const std::string &deviceId, + const SecurityOption &remoteSecOption, SyncGenericInterface *storage) +{ + if (storage == nullptr) { + return -E_INVALID_ARGS; + } + SecurityOption localSecOption; + if (remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { + return true; + } + int errCode = storage->GetSecurityOption(localSecOption); + if (errCode == -E_NOT_SUPPORT) { + return true; + } + return RuntimeContext::GetInstance()->CheckDeviceSecurityAbility(deviceId, localSecOption); +} + +void SingleVerDataSyncUtils::TransDbDataItemToSendDataItem(const SingleVerSyncTaskContext *context, + const std::string &localHashName, std::vector &outData) +{ + for (size_t i = 0; i < outData.size(); i++) { + if (outData[i] == nullptr) { + continue; + } + outData[i]->SetOrigDevice(outData[i]->GetOrigDevice().empty() ? localHashName : outData[i]->GetOrigDevice()); + if (i == 0 || i == (outData.size() - 1)) { + LOGD("[DataSync][TransToSendItem] printData packet=%d,timeStamp=%llu,flag=%llu", i, + outData[i]->GetTimestamp(), outData[i]->GetFlag()); + } + } +} + +std::string SingleVerDataSyncUtils::TransferForeignOrigDevName(const std::string &deviceName, + const std::string &localHashName) +{ + if (localHashName == deviceName) { + return ""; + } + return deviceName; +} + +void SingleVerDataSyncUtils::TransSendDataItemToLocal(const SingleVerSyncTaskContext *context, + const std::string &localHashName, const std::vector &data) +{ + TimeOffset offset = context->GetTimeOffset(); + TimeStamp currentLocalTime = context->GetCurrentLocalTime(); + for (auto &item : data) { + if (item == nullptr) { + continue; + } + item->SetOrigDevice(TransferForeignOrigDevName(item->GetOrigDevice(), localHashName)); + TimeStamp tempTimestamp = item->GetTimestamp(); + TimeStamp tempWriteTimestamp = item->GetWriteTimestamp(); + item->SetTimestamp(tempTimestamp - static_cast(offset)); + if (tempWriteTimestamp != 0) { + item->SetWriteTimestamp(tempWriteTimestamp - static_cast(offset)); + } + + if (item->GetTimestamp() > currentLocalTime) { + item->SetTimestamp(currentLocalTime); + } + if (item->GetWriteTimestamp() > currentLocalTime) { + item->SetWriteTimestamp(currentLocalTime); + } + } +} + +void SingleVerDataSyncUtils::TranslateErrCodeIfNeed(int mode, uint32_t version, int &errCode) +{ + // once get data occur E_EKEYREVOKED error, should also send request to remote dev to pull data. + if (SyncOperation::TransferSyncMode(mode) == SyncModeType::PUSH_AND_PULL && + version > SOFTWARE_VERSION_RELEASE_2_0 && errCode == -E_EKEYREVOKED) { + errCode = E_OK; + } +} + +int SingleVerDataSyncUtils::RunPermissionCheck(SingleVerSyncTaskContext *context, const SyncGenericInterface* storage, + const std::string &label, int mode) +{ + std::string appId = storage->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + std::string userId = storage->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + std::string storeId = storage->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + uint8_t flag; + if (mode == SyncModeType::PUSH) { + flag = CHECK_FLAG_RECEIVE; + } else if (mode == SyncModeType::PULL) { + flag = CHECK_FLAG_SEND; + } else if (mode == SyncModeType::PUSH_AND_PULL) { + flag = CHECK_FLAG_SEND | CHECK_FLAG_RECEIVE; + } else { + // before add permissionCheck, PushStart packet and pullResponse packet do not setMode. + flag = CHECK_FLAG_RECEIVE; + } + int errCode = E_OK; + if (storage->GetInterfaceType() != ISyncInterface::SYNC_RELATION) { + errCode = RuntimeContext::GetInstance()->RunPermissionCheck(userId, appId, storeId, context->GetDeviceId(), + flag); + } + if (errCode != E_OK) { + LOGE("[DataSync][RunPermissionCheck] check failed flag=%d,Label=%s,dev=%s", flag, label.c_str(), + STR_MASK(context->GetDeviceId())); + } + return errCode; +} + +bool SingleVerDataSyncUtils::CheckPermitReceiveData(const SingleVerSyncTaskContext *context, + const ICommunicator *communicator) +{ + SecurityOption remoteSecOption = context->GetRemoteSeccurityOption(); + std::string localDeviceId; + if (communicator == nullptr || remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { + return true; + } + communicator->GetLocalIdentity(localDeviceId); + bool isPermitSync = SingleVerDataSyncUtils::IsPermitLocalDeviceRecvData(localDeviceId, remoteSecOption); + if (isPermitSync) { + return isPermitSync; + } + LOGE("[DataSync][PermitReceiveData] check failed: permitReceive=%d, localDev=%s, seclabel=%d, secflag=%d", + isPermitSync, STR_MASK(localDeviceId), remoteSecOption.securityLabel, remoteSecOption.securityFlag); + return isPermitSync; +} + +void SingleVerDataSyncUtils::SetPacketId(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t version) +{ + if (version > SOFTWARE_VERSION_RELEASE_2_0) { + context->IncPacketId(); // begin from 1 + std::vector reserved {context->GetPacketId()}; + packet->SetReserved(reserved); + } +} + +int SingleVerDataSyncUtils::GetMessageId(SyncType syncType) +{ + if (syncType == SyncType::QUERY_SYNC_TYPE) { + return QUERY_SYNC_MESSAGE; + } + return DATA_SYNC_MESSAGE; +} + +void SingleVerDataSyncUtils::PushAndPullKeyRevokHandle(SingleVerSyncTaskContext *context) +{ + // for push_and_pull mode it may be EKEYREVOKED error before receive watermarkexception + // should clear errCode and restart pushpull request. + int mode = SyncOperation::TransferSyncMode(context->GetMode()); + if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_RELEASE_2_0 && mode == SyncModeType::PUSH_AND_PULL && + context->GetTaskErrCode() == -E_EKEYREVOKED) { + context->SetTaskErrCode(E_OK); + } +} + +int SingleVerDataSyncUtils::GetReSendMode(int mode, uint32_t sequenceId, SyncType syncType) +{ + int curMode = SyncOperation::TransferSyncMode(mode); + if (curMode == SyncModeType::PUSH || curMode == SyncModeType::PULL) { + return mode; + } + if (curMode == SyncModeType::RESPONSE_PULL) { + return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH : SyncModeType::PUSH; + } + // set push_and_pull mode when resend first sequenceId to inform remote to run RESPONSE_PULL task + // for sequenceId which is larger than first, only need to send data, means to set push or query_push mode + if (sequenceId == 1) { + return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH_PULL : SyncModeType::PUSH_AND_PULL; + } + return (syncType == SyncType::QUERY_SYNC_TYPE) ? SyncModeType::QUERY_PUSH : SyncModeType::PUSH; +} + +void SingleVerDataSyncUtils::FillControlRequestPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context) +{ + uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); + uint32_t flag = 0; + if (context->GetMode() == SyncModeType::SUBSCRIBE_QUERY && context->IsAutoSubscribe()) { + flag = flag | SubscribeRequest::IS_AUTO_SUBSCRIBE; + } + packet->SetPacketHead(E_OK, version, GetControlCmdType(context->GetMode()), flag); + packet->SetQuery(context->GetQuery()); +} + +ControlCmdType SingleVerDataSyncUtils::GetControlCmdType(int mode) +{ + if (mode == SyncModeType::SUBSCRIBE_QUERY) { + return ControlCmdType::SUBSCRIBE_QUERY_CMD; + } else if (mode == SyncModeType::UNSUBSCRIBE_QUERY) { + return ControlCmdType::UNSUBSCRIBE_QUERY_CMD; + } + return ControlCmdType::INVALID_CONTROL_CMD; +} + +int SingleVerDataSyncUtils::GetModeByControlCmdType(ControlCmdType controlCmd) +{ + if (controlCmd == ControlCmdType::SUBSCRIBE_QUERY_CMD) { + return SyncModeType::SUBSCRIBE_QUERY; + } else if (controlCmd == ControlCmdType::UNSUBSCRIBE_QUERY_CMD) { + return SyncModeType::UNSUBSCRIBE_QUERY; + } + return SyncModeType::INVALID_MODE; +} + +bool SingleVerDataSyncUtils::IsNeedTriggerQueryAutoSync(Message *inMsg, QuerySyncObject &query) +{ + if (inMsg == nullptr) { + return false; + } + if (inMsg->GetMessageId() != CONTROL_SYNC_MESSAGE) { + return false; + } + const ControlRequestPacket *packet = inMsg->GetObject(); + if (packet == nullptr) { + return false; + } + uint32_t controlCmdType = packet->GetcontrolCmdType(); + if (controlCmdType == ControlCmdType::SUBSCRIBE_QUERY_CMD && inMsg->GetMessageType() == TYPE_REQUEST) { + const SubscribeRequest *subPacket = inMsg->GetObject(); + if (packet == nullptr) { + return false; + } + query = subPacket->GetQuery(); + LOGI("[SingleVerDataSync] receive sub scribe query cmd,begin to trigger query auto sync"); + return true; + } + return false; +} + +void SingleVerDataSyncUtils::ControlAckErrorHandle(const SingleVerSyncTaskContext *context, + const std::shared_ptr &subManager) +{ + if (context->GetMode() == SyncModeType::SUBSCRIBE_QUERY) { + // reserve before need clear + subManager->DeleteLocalSubscribeQuery(context->GetDeviceId(), context->GetQuery()); + } +} + +void SingleVerDataSyncUtils::SetMessageHeadInfo(Message &message, uint16_t inMsgType, const std::string &inTarget, + uint32_t inSequenceId, uint32_t inSessionId) +{ + message.SetMessageType(inMsgType); + message.SetTarget(inTarget); + message.SetSequenceId(inSequenceId); + message.SetSessionId(inSessionId); +} + +bool SingleVerDataSyncUtils::IsGetDataSuccessfully(int errCode) +{ + return errCode == E_OK || errCode == -E_UNFINISHED; +} + +TimeStamp SingleVerDataSyncUtils::GetMaxSendDataTime(const std::vector &inData) +{ + TimeStamp stamp = 0; + for (size_t i = 0; i < inData.size(); i++) { + if (inData[i] == nullptr) { + continue; + } + TimeStamp tempStamp = inData[i]->GetTimestamp(); + if (stamp < tempStamp) { + stamp = tempStamp; + } + } + return stamp; +} + +SyncTimeRange SingleVerDataSyncUtils::GetFullSyncDataTimeRange(const std::vector &inData, + WaterMark localMark, UpdateWaterMark &isUpdate) +{ + TimeStamp maxTimeStamp = localMark; + TimeStamp minTimeStamp = localMark; + for (size_t i = 0; i < inData.size(); i++) { + if (inData[i] == nullptr) { + continue; + } + TimeStamp tempStamp = inData[i]->GetTimestamp(); + if (maxTimeStamp < tempStamp) { + maxTimeStamp = tempStamp; + } + if (minTimeStamp > tempStamp) { + minTimeStamp = tempStamp; + } + isUpdate.normalUpdateMark = true; + } + return {minTimeStamp, 0, maxTimeStamp, 0}; +} + +SyncTimeRange SingleVerDataSyncUtils::GetQuerySyncDataTimeRange(const std::vector &inData, + WaterMark localMark, WaterMark deleteLocalMark, UpdateWaterMark &isUpdate) +{ + SyncTimeRange dataTimeRange = {localMark, deleteLocalMark, localMark, deleteLocalMark}; + for (size_t i = 0; i < inData.size(); i++) { + if (inData[i] == nullptr) { + continue; + } + TimeStamp tempStamp = inData[i]->GetTimestamp(); + if ((inData[i]->GetFlag() & DataItem::DELETE_FLAG) == 0) { // query data + if (dataTimeRange.endTime < tempStamp) { + dataTimeRange.endTime = tempStamp; + } + if (dataTimeRange.beginTime > tempStamp) { + dataTimeRange.beginTime = tempStamp; + } + isUpdate.normalUpdateMark = true; + } + if ((inData[i]->GetFlag() & DataItem::DELETE_FLAG) != 0) { // delete data + if (dataTimeRange.deleteEndTime < tempStamp) { + dataTimeRange.deleteEndTime = tempStamp; + } + if (dataTimeRange.deleteBeginTime > tempStamp) { + dataTimeRange.deleteBeginTime = tempStamp; + } + isUpdate.deleteUpdateMark = true; + } + } + return dataTimeRange; +} + +SyncTimeRange SingleVerDataSyncUtils::ReviseLocalMark(SyncType syncType, SyncTimeRange &dataTimeRange, + UpdateWaterMark updateMark) +{ + SyncTimeRange tmpDataTime = dataTimeRange; + if (updateMark.deleteUpdateMark && syncType == SyncType::QUERY_SYNC_TYPE) { + tmpDataTime.deleteEndTime += 1; + } + if (updateMark.normalUpdateMark) { + tmpDataTime.endTime += 1; + } + return tmpDataTime; +} + +SyncTimeRange SingleVerDataSyncUtils::GetRecvDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, + const std::vector &data, UpdateWaterMark &isUpdate) +{ + if (syncType != SyncType::QUERY_SYNC_TYPE) { + return SingleVerDataSyncUtils::GetFullSyncDataTimeRange(data, 0, isUpdate); + } + return SingleVerDataSyncUtils::GetQuerySyncDataTimeRange(data, 0, 0, isUpdate); +} + +SyncTimeRange SingleVerDataSyncUtils::GetSyncDataTimeRange(SyncType syncType, WaterMark localMark, WaterMark deleteMark, + const std::vector &inData, UpdateWaterMark &isUpdate) +{ + if (syncType != SyncType::QUERY_SYNC_TYPE) { + return SingleVerDataSyncUtils::GetFullSyncDataTimeRange(inData, localMark, isUpdate); + } + return SingleVerDataSyncUtils::GetQuerySyncDataTimeRange(inData, localMark, deleteMark, isUpdate); +} +} \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.h b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..8dc7b5c515969daf4bb89243b381cae2805de85f --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_data_sync_utils.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SINGLE_VER_DATA_SYNC_UTIL_H +#define SINGLE_VER_DATA_SYNC_UTIL_H +#include "single_ver_data_packet.h" +#include "single_ver_sync_task_context.h" +#include "message.h" +namespace DistributedDB { +class SingleVerDataSyncUtils { +public: + static bool QuerySyncCheck(const SingleVerSyncTaskContext *context); + + static int AckMsgErrnoCheck(const SingleVerSyncTaskContext *context, const Message *message); + + static int RequestQueryCheck(const DataRequestPacket *packet, SyncGenericInterface *storage); + + static bool IsPermitLocalDeviceRecvData(const std::string &deviceId, const SecurityOption &remoteSecOption); + + static bool IsPermitRemoteDeviceRecvData(const std::string &deviceId, const SecurityOption &remoteSecOption, + SyncGenericInterface *storage); + + static void TransDbDataItemToSendDataItem(const SingleVerSyncTaskContext *context, + const std::string &localHashName, std::vector &outData); + + static std::string TransferForeignOrigDevName(const std::string &deviceName, const std::string &localHashName); + + static void TransSendDataItemToLocal(const SingleVerSyncTaskContext *context, + const std::string &localHashName, const std::vector &data); + + static void TranslateErrCodeIfNeed(int mode, uint32_t version, int &errCode); + + static int RunPermissionCheck(SingleVerSyncTaskContext *context, const SyncGenericInterface* storage, + const std::string &label, int mode); + + static bool CheckPermitReceiveData(const SingleVerSyncTaskContext *context, const ICommunicator *communicator); + + static void SetPacketId(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t version); + + static int GetMessageId(SyncType syncType); + + static void PushAndPullKeyRevokHandle(SingleVerSyncTaskContext *context); + + static int GetReSendMode(int mode, uint32_t sequenceId, SyncType syncType); + + static void FillControlRequestPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context); + + static ControlCmdType GetControlCmdType(int mode); + + static int GetModeByControlCmdType(ControlCmdType controlCmd); + + static bool IsNeedTriggerQueryAutoSync(Message *inMsg, QuerySyncObject &query); + + static void ControlAckErrorHandle(const SingleVerSyncTaskContext *context, + const std::shared_ptr &subManager); + + static void SetMessageHeadInfo(Message &message, uint16_t inMsgType, + const std::string &inTarget, uint32_t inSequenceId, uint32_t inSessionId); + + static bool IsGetDataSuccessfully(int errCode); + + static TimeStamp GetMaxSendDataTime(const std::vector &inData); + + static SyncTimeRange GetFullSyncDataTimeRange(const std::vector &inData, WaterMark localMark, + UpdateWaterMark &isUpdate); + + static SyncTimeRange GetQuerySyncDataTimeRange(const std::vector &inData, WaterMark localMark, + WaterMark deleteLocalMark, UpdateWaterMark &isUpdate); + + static SyncTimeRange ReviseLocalMark(SyncType syncType, SyncTimeRange &dataTimeRange, UpdateWaterMark updateMark); + + static SyncTimeRange GetRecvDataTimeRange(SyncType syncType, SingleVerSyncTaskContext *context, + const std::vector &data, UpdateWaterMark &isUpdate); + + static SyncTimeRange GetSyncDataTimeRange(SyncType syncType, WaterMark localMark, WaterMark deleteMark, + const std::vector &inData, UpdateWaterMark &isUpdate); +}; +} +#endif // SINGLE_VER_DATA_SYNC_UTIL_H \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp index dbfec0286571ca8ec9e2bebdd788a3ed7fd99832..de0c054678a79ec59f67b694d766239a47aa2f6e 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp @@ -116,6 +116,10 @@ void SingleVerKVSyncer::LocalDataChanged(int notifyEvent) void SingleVerKVSyncer::RemoteDataChanged(const std::string &device) { LOGI("[SingleVerKVSyncer] device online dev %s", STR_MASK(device)); + if (!initialized_) { + LOGE("[Syncer] Syncer has not Init"); + return; + } std::string userId = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); std::string appId = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); std::string storeId = syncInterface_->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); @@ -154,6 +158,10 @@ void SingleVerKVSyncer::RemoteDataChanged(const std::string &device) void SingleVerKVSyncer::QueryAutoSync(const InternalSyncParma ¶m) { + if (!initialized_) { + LOGE("[Syncer] Syncer has not Init"); + return; + } LOGI("[SingleVerKVSyncer] trigger query syncmode=%u,dev=%s", param.mode, GetSyncDevicesStr(param.devices).c_str()); RefObject::IncObjRef(syncEngine_); int retCode = RuntimeContext::GetInstance()->ScheduleTask([this, param] { @@ -196,6 +204,10 @@ int SingleVerKVSyncer::SyncConditionCheck(QuerySyncObject &query, int mode, bool void SingleVerKVSyncer::TriggerSubscribe(const std::string &device, const QuerySyncObject &query) { + if (!initialized_) { + LOGE("[Syncer] Syncer has not Init"); + return; + } RefObject::IncObjRef(syncEngine_); int retCode = RuntimeContext::GetInstance()->ScheduleTask([this, device, query] { std::vector devices; @@ -222,6 +234,10 @@ void SingleVerKVSyncer::TriggerSubscribe(const std::string &device, const QueryS bool SingleVerKVSyncer::TryFullSync(const std::vector &devices) { + if (!initialized_) { + LOGE("[Syncer] Syncer has not Init"); + return true; + } if (!autoSyncEnable_) { LOGD("[Syncer] autoSync no enable"); return false; @@ -236,6 +252,10 @@ bool SingleVerKVSyncer::TryFullSync(const std::vector &devices) void SingleVerKVSyncer::TriggerSubQuerySync(const std::vector &devices) { + if (!initialized_) { + LOGE("[Syncer] Syncer has not Init"); + return; + } int errCode; for (auto &device : devices) { std::vector queries; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp index 226b72f5ab5f92efc1d251e603330cfa5bfda993..aa274c10041a710d3d3e1d281017d1015d017bda 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp @@ -19,9 +19,9 @@ #include "single_ver_sync_engine.h" namespace DistributedDB { -int SingleVerRelationalSyncer::Initialize(ISyncInterface *syncInterface) +int SingleVerRelationalSyncer::Initialize(ISyncInterface *syncInterface, bool isNeedActive) { - int errCode = SingleVerSyncer::Initialize(syncInterface); + int errCode = SingleVerSyncer::Initialize(syncInterface, isNeedActive); if (errCode != E_OK) { return errCode; } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.h b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.h index bf6bd992be9676b10302997ce0afc69b1ab65392..18f42a48a90cdf07635a03ca3e6c4e5f170b149f 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_relational_syncer.h @@ -22,7 +22,7 @@ public: SingleVerRelationalSyncer() = default; ~SingleVerRelationalSyncer() override = default; - int Initialize(ISyncInterface *syncInterface) override; + int Initialize(ISyncInterface *syncInterface, bool isNeedActive) override; // Sync function. use SyncParma to reduce paramter. int Sync(const SyncParma ¶m) override; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp index 94defbb15c166a996df422d82f135c7e2ac5f23f..41f410fe606a95699f1093960ee1febf24b29f4b 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp @@ -352,7 +352,7 @@ int SingleVerSerializeManager::DataPacketDeSerialization(const uint8_t *buffer, } packet->SetVersion(version); - packLen += GenericSingleVerKvEntry::DeSerializeDatas(dataItems, parcel); + packLen += static_cast(GenericSingleVerKvEntry::DeSerializeDatas(dataItems, parcel)); if (parcel.IsError()) { return -E_PARSE_FAIL; } @@ -602,7 +602,7 @@ int SingleVerSerializeManager::AckControlPacketDeSerialization(const uint8_t *bu errCode = -E_INVALID_ARGS; goto ERROR; } - packet->SetPacketHead(recvCode, version, controlCmdType, flag); + packet->SetPacketHead(recvCode, version, static_cast(controlCmdType), flag); errCode = inMsg->SetExternalObject<>(packet); if (errCode != E_OK) { goto ERROR; @@ -649,7 +649,7 @@ int SingleVerSerializeManager::ControlRequestDeSerialization(Parcel &parcel, Con LOGE("[ControlRequestDeSerialization] deserialize failed!"); return -E_LENGTH_ERROR; } - packet.SetPacketHead(sendCode, version, controlCmdType, flag); + packet.SetPacketHead(sendCode, version, static_cast(controlCmdType), flag); return E_OK; } @@ -696,8 +696,8 @@ int SingleVerSerializeManager::SubscribeDeSerialization(Parcel &parcel, Message if (errCode != E_OK) { goto ERROR; } - packet->SetPacketHead(controlPacket.GetSendCode(), controlPacket.GetVersion(), controlPacket.GetcontrolCmdType(), - controlPacket.GetFlag()); + packet->SetPacketHead(controlPacket.GetSendCode(), controlPacket.GetVersion(), + static_cast(controlPacket.GetcontrolCmdType()), controlPacket.GetFlag()); packet->SetQuery(querySyncObj); errCode = inMsg->SetExternalObject<>(packet); if (errCode != E_OK) { diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp index 49fb9b305d90c9babc8a037d3332370b7f09afef..2136dc6f80eb1d996d7312218717000601b34f25 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp @@ -29,6 +29,7 @@ #include "performance_analysis.h" #include "single_ver_sync_target.h" #include "single_ver_data_sync.h" +#include "single_ver_data_sync_utils.h" namespace DistributedDB { namespace { @@ -463,6 +464,7 @@ Event SingleVerSyncStateMachine::DoTimeSync() if (errCode == E_OK) { return Event::WAIT_ACK_EVENT; } + context_->SetTaskErrCode(errCode); return TransformErrCodeToEvent(errCode); } @@ -958,7 +960,7 @@ int SingleVerSyncStateMachine::MessageCallbackPre(const Message *inMsg) void SingleVerSyncStateMachine::AddPullResponseTarget(const Message *inMsg, WaterMark pullEndWatermark) { - int messageType = inMsg->GetMessageId(); + int messageType = static_cast(inMsg->GetMessageId()); uint32_t sessionId = inMsg->GetSessionId(); if (pullEndWatermark == 0) { LOGE("[StateMachine][AddPullResponseTarget] pullEndWatermark is 0!"); @@ -1155,7 +1157,7 @@ void SingleVerSyncStateMachine::DataAckRecvErrCodeHandle(int errCode, bool handl bool SingleVerSyncStateMachine::IsNeedTriggerQueryAutoSync(Message *inMsg, QuerySyncObject &query) { - return dataSync_->IsNeedTriggerQueryAutoSync(inMsg, query); + return SingleVerDataSyncUtils::IsNeedTriggerQueryAutoSync(inMsg, query); } void SingleVerSyncStateMachine::JumpStatusAfterAbilitySync(int mode) diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp index ded9bd059c147922d7eff0c2e0ac5b095090889b..2235ded7a5b87fcf9b6a7e074bc7ffc7d5ad3a2d 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp @@ -351,6 +351,7 @@ bool SingleVerSyncTaskContext::GetSendPermitCheck() const { return isSendPermitChecked_; } + void SingleVerSyncTaskContext::SetIsSchemaSync(bool isSchemaSync) { isSchemaSync_ = isSchemaSync; @@ -407,7 +408,7 @@ bool SingleVerSyncTaskContext::IsQuerySync() const std::set SingleVerSyncTaskContext::GetRemoteCompressAlgo() const { std::set compressAlgoSet; - for (const auto &algo : COMPRESSALGOMAP) { + for (const auto &algo : SyncConfig::COMPRESSALGOMAP) { if (remoteDbAbility_.GetAbilityItem(algo.second) == SUPPORT_MARK) { compressAlgoSet.insert(static_cast(algo.first)); } @@ -435,10 +436,12 @@ std::string SingleVerSyncTaskContext::GetRemoteCompressAlgoStr() const void SingleVerSyncTaskContext::SetDbAbility(DbAbility &remoteDbAbility) { remoteDbAbility_ = remoteDbAbility; - LOGI("[SingleVerSyncTaskContext] set dev=%s compressAlgo=%s, IsSupAllPredicateQuery=%u, \ - IsSupSubscribeQuery=%u, inKeys=%u", - STR_MASK(GetDeviceId()), GetRemoteCompressAlgoStr().c_str(), remoteDbAbility.GetAbilityItem(ALLPREDICATEQUERY), - remoteDbAbility.GetAbilityItem(SUBSCRIBEQUERY), remoteDbAbility.GetAbilityItem(INKEYS_QUERY)); + LOGI("[SingleVerSyncTaskContext] set dev=%s compressAlgo=%s, IsSupAllPredicateQuery=%u," + "IsSupSubscribeQuery=%u, inKeys=%u", + STR_MASK(GetDeviceId()), GetRemoteCompressAlgoStr().c_str(), + remoteDbAbility.GetAbilityItem(SyncConfig::ALLPREDICATEQUERY), + remoteDbAbility.GetAbilityItem(SyncConfig::SUBSCRIBEQUERY), + remoteDbAbility.GetAbilityItem(SyncConfig::INKEYS_QUERY)); } CompressAlgorithm SingleVerSyncTaskContext::ChooseCompressAlgo() const diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.h b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.h index b5921f7e4380ee2a84c5652f8b34a6cd0e97ddf4..303ba4a408ce737718b319e6fcebee93864a8a90 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_sync_task_context.h @@ -111,7 +111,7 @@ public: virtual SyncStrategy GetSyncStrategy(QuerySyncObject &querySyncObject) const = 0; - void SetIsSchemaSync(bool isChecked); + void SetIsSchemaSync(bool isSchemaSync); bool GetIsSchemaSync() const; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.cpp index 3069f5e90eacbbae05e105099ded7a6406e2bc9c..c923405f322db07832c29af46ec92bce6a9b8117 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.cpp @@ -37,6 +37,11 @@ void SingleVerSyncer::RemoteDeviceOffline(const std::string &device) RefObject::DecObjRef(syncEngine_); } +int SingleVerSyncer::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) +{ + return EraseDeviceWaterMark(deviceId, isNeedHash, ""); +} + int SingleVerSyncer::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName) { diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.h b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.h index dab50ddb802225a93b26768ba723635d77e3bff5..9dc5e0e1781185a7d96d9bedab6d5c8c7012d3b9 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/single_ver_syncer.h @@ -28,8 +28,11 @@ public: int SetStaleDataWipePolicy(WipePolicy policy) override; // delete specified device's watermark + int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) override; + + // delete specified device's and table's watermark int EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, - const std::string &tableName = "") override; + const std::string &tableName) override; protected: // Create a sync engine, if has memory error, will return nullptr. diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp index 23463325bf00b427f2890931d4f7e23693075261..ccff66498026e2c381100216ec9da985dfc974ec 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp @@ -206,7 +206,7 @@ void SubscribeManager::GetRemoteSubscribeQueryIds(const std::string &device, int SubscribeManager::LocalSubscribeLimitCheck(const std::vector &devices, QuerySyncObject &query) const { std::shared_lock lock(localSubscribeMapLock_); - int devNum = localSubscribeMap_.size(); + size_t devNum = localSubscribeMap_.size(); for (const auto &device : devices) { if (localSubscribeMap_.find(device) != localSubscribeMap_.end()) { continue; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_config.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8b3c6b89687ed0a32b25265c3bde347016ba24a8 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_config.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sync_config.h" +namespace DistributedDB { +const AbilityItem SyncConfig::DATABASE_COMPRESSION_ZLIB = {0, 1}; +const AbilityItem SyncConfig::ALLPREDICATEQUERY = {1, 1}; // 0b10 {1: start at second bit, 1: 1 bit len} +const AbilityItem SyncConfig::SUBSCRIBEQUERY = {2, 1}; // 0b100 +const AbilityItem SyncConfig::INKEYS_QUERY = {3, 1}; // 0b1000 + +const std::vector SyncConfig::ABILITYBITS = { + DATABASE_COMPRESSION_ZLIB, + ALLPREDICATEQUERY, + SUBSCRIBEQUERY, + INKEYS_QUERY}; + +const std::map SyncConfig::COMPRESSALGOMAP = { + {static_cast(CompressAlgorithm::ZLIB), DATABASE_COMPRESSION_ZLIB}, +}; +} // DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.cpp index c0176d53c34ce6230bc0ba4b5a48ee822a86101b..f86e196379492f5f0613a78dd20da9ae939adde9 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.cpp @@ -60,6 +60,7 @@ SyncEngine::~SyncEngine() { LOGD("[SyncEngine] ~SyncEngine!"); ClearInnerResource(); + equalIdentifierMap_.clear(); subManager_ = nullptr; LOGD("[SyncEngine] ~SyncEngine ok!"); } @@ -112,7 +113,7 @@ int SyncEngine::Initialize(ISyncInterface *syncInterface, std::shared_ptrClearAllRemoteQuery(); + if (subManager_ != nullptr) { + subManager_->ClearAllRemoteQuery(); + } ClearInnerResource(); LOGI("[SyncEngine] SyncEngine closed!"); return E_OK; @@ -241,9 +244,17 @@ int SyncEngine::InitComunicator(const ISyncInterface *syncInterface) LOGE("[SyncEngine] Get ICommunicatorAggregator error when init the sync engine err = %d", errCode); return errCode; } - std::vector label = syncInterface->GetIdentifier(); - communicator_ = communicatorAggregator->AllocCommunicator(label, errCode); + bool isSyncDualTupleMode = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + if (isSyncDualTupleMode) { + std::vector dualTuplelabel = syncInterface->GetDualTupleIdentifier(); + LOGI("[SyncEngine] dual tuple mode, original identifier=%0.6s, target identifier=%0.6s", VEC_TO_STR(label), + VEC_TO_STR(dualTuplelabel)); + communicator_ = communicatorAggregator->AllocCommunicator(dualTuplelabel, errCode); + } else { + communicator_ = communicatorAggregator->AllocCommunicator(label, errCode); + } if (communicator_ == nullptr) { LOGE("[SyncEngine] AllocCommunicator error when init the sync engine! err = %d", errCode); return errCode; @@ -650,22 +661,6 @@ void SyncEngine::SetMaxQueueCacheSize(int value) maxQueueCacheSize_ = value; } -int SyncEngine::GetLocalIdentity(std::string &outTarget) const -{ - if (communicatorProxy_ == nullptr) { - LOGE("[SyncEngine] communicatorProxy_ is nullptr, return!"); - return -E_NOT_INIT; - } - std::string deviceId; - int errCode = communicatorProxy_->GetLocalIdentity(deviceId); - if (errCode != E_OK) { - LOGE("[SyncEngine] communicatorProxy_ GetLocalIdentity fail errCode:%d", errCode); - return errCode; - } - outTarget = DBCommon::TransferHashString(deviceId); - return E_OK; -} - uint8_t SyncEngine::GetPermissionCheckFlag(bool isAutoSync, int syncMode) { uint8_t flag = 0; @@ -717,6 +712,7 @@ void SyncEngine::SetSyncRetry(bool isRetry) return; } isSyncRetry_ = isRetry; + LOGI("[SyncEngine] SetSyncRetry:%d ok", isRetry); std::lock_guard lock(contextMapLock_); for (auto &iter : syncTaskContextMap_) { ISyncTaskContext *context = iter.second; @@ -728,6 +724,10 @@ void SyncEngine::SetSyncRetry(bool isRetry) int SyncEngine::SetEqualIdentifier(const std::string &identifier, const std::vector &targets) { + if (!isActive_) { + LOGI("[SyncEngine] engine is closed, just put into map"); + return E_OK; + } ICommunicator *communicator = nullptr; { std::lock_guard lock(equalCommunicatorsLock_); @@ -742,13 +742,40 @@ int SyncEngine::SetEqualIdentifier(const std::string &identifier, const std::vec equalCommunicators_[identifier] = communicator; } } - LOGI("[SyncEngine] set equal identifier %s, original %s", - DBCommon::TransferStringToHex(identifier).c_str(), label_.c_str()); + std::string targetDevices; + for (const auto &dev : targets) { + targetDevices += DBCommon::StringMasking(dev) + ","; + } + LOGI("[SyncEngine] set equal identifier=%s, original=%s, targetDevices=%s", + DBCommon::TransferStringToHex(identifier).c_str(), label_.c_str(), + targetDevices.substr(0, targetDevices.size() - 1).c_str()); communicatorProxy_->SetEqualCommunicator(communicator, targets); communicator->Activate(); return E_OK; } +void SyncEngine::SetEqualIdentifier() +{ + std::map> equalIdentifier; // key: equalIdentifier value: devices + for (auto &item : equalIdentifierMap_) { + if (equalIdentifier.find(item.second) == equalIdentifier.end()) { + equalIdentifier[item.second] = {item.first}; + } else { + equalIdentifier[item.second].push_back(item.first); + } + } + for (auto &item : equalIdentifier) { + SetEqualIdentifier(item.first, item.second); + } +} + +void SyncEngine::SetEqualIdentifierMap(const std::string &identifier, const std::vector &targets) +{ + for (auto &device : targets) { + equalIdentifierMap_[device] = identifier; + } +} + void SyncEngine::OfflineHandleByDevice(const std::string &deviceId) { if (communicatorProxy_ == nullptr) { @@ -848,7 +875,6 @@ void SyncEngine::UnRegCommunicatorsCallback() communicator_->RegOnConnectCallback(nullptr, nullptr); communicator_->RegOnSendableCallback(nullptr, nullptr); } - std::lock_guard lock(equalCommunicatorsLock_); for (const auto &iter : equalCommunicators_) { iter.second->RegOnMessageCallback(nullptr, nullptr); @@ -930,8 +956,8 @@ int SyncEngine::InitTimeChangedListener() TimeStamp currentSysTime = TimeHelper::GetSysCurrentTime(); TimeStamp maxItemTime = 0; this->syncInterface_->GetMaxTimeStamp(maxItemTime); - if ((currentSysTime + orgOffset) <= maxItemTime) { - orgOffset = maxItemTime - currentSysTime + TimeHelper::MS_TO_100_NS; // 1ms + if ((currentSysTime + static_cast(orgOffset)) <= maxItemTime) { + orgOffset = static_cast(maxItemTime - currentSysTime + TimeHelper::MS_TO_100_NS); // 1ms } this->metadata_->SaveLocalTimeOffset(orgOffset); }, errCode); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.h b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.h index ca4d176d6b281931a77765b8a13ec52dfe662d69..280c7cc2147af7a4ea1afd83914a022c56c05209 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_engine.h @@ -72,9 +72,6 @@ public: // Set the maximum of queue cache memory size void SetMaxQueueCacheSize(int value); - // Get local deviceId, is hashed - int GetLocalIdentity(std::string &outTarget) const override; - std::string GetLabel() const override; bool GetSyncRetry() const; @@ -83,6 +80,10 @@ public: // Set an equal identifier for this database, After this called, send msg to the target will use this identifier int SetEqualIdentifier(const std::string &identifier, const std::vector &targets) override; + void SetEqualIdentifier() override; + + void SetEqualIdentifierMap(const std::string &identifier, const std::vector &targets) override; + void OfflineHandleByDevice(const std::string &deviceId); void GetLocalSubscribeQueries(const std::string &device, std::vector &subscribeQueries); @@ -209,6 +210,9 @@ private: static constexpr int DEFAULT_CACHE_SIZE = 160 * 1024 * 1024; // Initial the default cache size of queue as 160MB static std::mutex queueLock_; std::atomic isActive_; + + // key: device value: equalIdentifier + std::map equalIdentifierMap_; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_state_machine.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_state_machine.cpp index 53d7bb83c22cb3249080f945922972afaf3a14fe..5ab512fdeef16697cbcaccd4c1185dd22c378ebb 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_state_machine.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_state_machine.cpp @@ -277,7 +277,7 @@ bool SyncStateMachine::StartFeedDogForSync(uint32_t time, SyncDirectionFlag flag return false; } - int cnt = GetFeedDogTimeout(time / SAVE_DATA_NOTIFY_INTERVAL); + uint8_t cnt = GetFeedDogTimeout(time / SAVE_DATA_NOTIFY_INTERVAL); LOGI("[SyncStateMachine][feedDog] start cnt:%d, flag:%d", cnt, flag); std::lock_guard lockGuard(feedDogLock_[flag]); @@ -290,7 +290,7 @@ bool SyncStateMachine::StartFeedDogForSync(uint32_t time, SyncDirectionFlag flag LOGD("update feedDogUpperLimit = %d", cnt); watchDogController_[flag].feedDogUpperLimit = cnt; } - watchDogController_[flag].feedDogCnt = 0; + watchDogController_[flag].feedDogCnt = 0u; LOGW("[SyncStateMachine][feedDog] timer has been started!, flag:%d", flag); return false; } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_task_context.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_task_context.cpp index 5204e8eccd8b5b31e2153384a96303932bb3ba13..123310d0c7095d02ca256370254cb8fedee53eef 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_task_context.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_task_context.cpp @@ -470,7 +470,7 @@ void SyncTaskContext::CommErrHandlerFunc(int errCode, ISyncTaskContext *context, RefObject::IncObjRef(context); } - static_cast(context)->CommErrHandlerFuncInner(errCode, sessionId); + static_cast(context)->CommErrHandlerFuncInner(errCode, static_cast(sessionId)); RefObject::DecObjRef(context); } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_types.h b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_types.h index 9dddff22c1d19304cb8d9e03983ccb1b1e333861..ab36e40b2cc912b75cf63aca6ba3103c17e50615 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/sync_types.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/sync_types.h @@ -86,7 +86,7 @@ constexpr int NOTIFY_MIN_MTU_SIZE = 30 * 1024; // 30k constexpr int MAX_SUBSCRIBE_NUM_PER_DEV = 4; constexpr int MAX_SUBSCRIBE_NUM_PER_DB = 8; -constexpr int MAX_DEVICES_NUM = 32; +constexpr size_t MAX_DEVICES_NUM = 32; // index 0 for packetId in data request // if ack reserve size is 1, reserve is {localWaterMark} @@ -99,5 +99,4 @@ constexpr uint64_t MAX_TIMESTAMP = INT64_MAX; constexpr uint8_t REMOVE_DEVICE_DATA_MARK = 1; constexpr uint8_t SUPPORT_MARK = 1; // used for set is support one ability } - #endif \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/syncer_proxy.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/syncer_proxy.cpp index a2a9a20b7ceefacc8365dc807cb204910abfd77a..fbe0cb5bef0d1367312b514bc30d2d4b6a82c62a 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/syncer_proxy.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/syncer_proxy.cpp @@ -25,7 +25,7 @@ SyncerProxy::SyncerProxy() { } -int SyncerProxy::Initialize(ISyncInterface *syncInterface) +int SyncerProxy::Initialize(ISyncInterface *syncInterface, bool isNeedActive) { if (syncInterface == nullptr) { return -E_INVALID_ARGS; @@ -43,7 +43,7 @@ int SyncerProxy::Initialize(ISyncInterface *syncInterface) return -E_OUT_OF_MEMORY; } - return syncer_->Initialize(syncInterface); + return syncer_->Initialize(syncInterface, isNeedActive); } int SyncerProxy::Close() @@ -104,6 +104,11 @@ void SyncerProxy::EnableAutoSync(bool enable) syncer_->EnableAutoSync(enable); } +int SyncerProxy::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) +{ + return syncer_->EraseDeviceWaterMark(deviceId, isNeedHash, ""); +} + int SyncerProxy::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName) { diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.cpp index 9841961b19f94cc3ef6261d7aeb5ac20d0bb79f4..963ee284c364bed850cdf0f9f9aec5709f2ad8fb 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.cpp @@ -72,10 +72,14 @@ int TimeHelper::Initialize(const ISyncInterface *inStorage, std::shared_ptr(maxItemTime - currentSysTime + MS_TO_100_NS); // 1ms + int errCode = SaveLocalTimeOffset(localTimeOffset); + if (errCode != E_OK) { + LOGE("[TimeHelper] save local time offset faield,err=%d", errCode); + return errCode; + } } - metadata_->SetLastLocalTime(currentSysTime + localTimeOffset); + metadata_->SetLastLocalTime(currentSysTime + static_cast(localTimeOffset)); return E_OK; } @@ -111,4 +115,16 @@ int TimeHelper::SaveLocalTimeOffset(TimeOffset offset) { return metadata_->SaveLocalTimeOffset(offset); } + +void TimeHelper::SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, SendConfig &sendConf) +{ + sendConf.nonBlock = nonBlock; + sendConf.timeout = timeout; + sendConf.isNeedExtendHead = storage_->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, + false); + sendConf.paramInfo.appId = storage_->GetDbProperties().GetStringProp(KvDBProperties::APP_ID, ""); + sendConf.paramInfo.userId = storage_->GetDbProperties().GetStringProp(KvDBProperties::USER_ID, ""); + sendConf.paramInfo.storeId = storage_->GetDbProperties().GetStringProp(KvDBProperties::STORE_ID, ""); + sendConf.paramInfo.dstTarget = dstTarget; +} } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.h b/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.h index 8baa05019e4047fcf070274f2bb12c2afa79a251..63765e0c8c342a7259910b41118112dc7acd0929 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.h +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/time_helper.h @@ -18,6 +18,7 @@ #include +#include "icommunicator.h" #include "meta_data.h" #include "runtime_context.h" @@ -55,6 +56,8 @@ public: // Get local time int SaveLocalTimeOffset(TimeOffset offset); + void SetSendConfig(const std::string &dstTarget, bool nonBlock, uint32_t timeout, SendConfig &sendConf); + private: static std::mutex systemTimeLock_; static TimeStamp lastSystemTimeUs_; diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/time_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/time_sync.cpp index 2a4e778bb5dcce0ba42b144369107d1376683d7c..f1a9013acb79f6a3c8a6be8945f5c69f89392b24 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/time_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/time_sync.cpp @@ -386,7 +386,7 @@ int TimeSync::RequestRecv(const Message *message) return -E_INVALID_TIME; } - TimeOffset timeoffsetIgnoreRtt = ackPacket.GetSourceTimeBegin() - targetTimeBegin; + TimeOffset timeoffsetIgnoreRtt = static_cast(ackPacket.GetSourceTimeBegin() - targetTimeBegin); TimeOffset metadataTimeoffset; metadata_->GetTimeOffset(deviceId_, metadataTimeoffset); @@ -427,12 +427,12 @@ int TimeSync::SaveTimeOffset(const DeviceID &deviceID, TimeOffset timeOffset) TimeOffset TimeSync::CalculateTimeOffset(const TimeSyncPacket &timeSyncInfo) { - TimeOffset roundTrip = (timeSyncInfo.GetSourceTimeEnd() - timeSyncInfo.GetSourceTimeBegin()) - - (timeSyncInfo.GetTargetTimeEnd() - timeSyncInfo.GetTargetTimeBegin()); - TimeOffset offset1 = timeSyncInfo.GetTargetTimeBegin() - - timeSyncInfo.GetSourceTimeBegin() - (roundTrip / TRIP_DIV_HALF); - TimeOffset offset2 = timeSyncInfo.GetTargetTimeEnd() + (roundTrip / TRIP_DIV_HALF) - - timeSyncInfo.GetSourceTimeEnd(); + TimeOffset roundTrip = static_cast((timeSyncInfo.GetSourceTimeEnd() - + timeSyncInfo.GetSourceTimeBegin()) - (timeSyncInfo.GetTargetTimeEnd() - timeSyncInfo.GetTargetTimeBegin())); + TimeOffset offset1 = static_cast(timeSyncInfo.GetTargetTimeBegin() - + timeSyncInfo.GetSourceTimeBegin() - (roundTrip / TRIP_DIV_HALF)); + TimeOffset offset2 = static_cast(timeSyncInfo.GetTargetTimeEnd() + (roundTrip / TRIP_DIV_HALF) - + timeSyncInfo.GetSourceTimeEnd()); TimeOffset offset = (offset1 / TRIP_DIV_HALF) + (offset2 / TRIP_DIV_HALF); LOGD("TimeSync::CalculateTimeOffset roundTrip= %lld, offset1 = %lld, offset2 = %lld, offset = %lld", roundTrip, offset1, offset2, offset); @@ -457,7 +457,9 @@ bool TimeSync::IsPacketValid(const Message *inMsg, uint16_t messageType) int TimeSync::SendPacket(const DeviceID &deviceId, const Message *message, const CommErrHandler &handler) { - int errCode = communicateHandle_->SendMessage(deviceId, message, false, SEND_TIME_OUT, handler); + SendConfig conf; + timeHelper_->SetSendConfig(deviceId, false, SEND_TIME_OUT, conf); + int errCode = communicateHandle_->SendMessage(deviceId, message, conf, handler); if (errCode != E_OK) { LOGE("[TimeSync] SendPacket failed, err %d", errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/value_slice_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/value_slice_sync.cpp index 5659b6ed8c8fc1779a59c13d7aa9f0cd2b164c4c..7582cd3d9bb6fafd9d63bf05f2d55b95a7bd905d 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/value_slice_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/value_slice_sync.cpp @@ -217,7 +217,7 @@ int ValueSliceSync::SyncStart(MultiVerSyncTaskContext *context) } context->SetValueSliceHashNodes(valueHashes); context->SetValueSlicesIndex(0); - context->SetValueSlicesSize(valueHashes.size()); + context->SetValueSlicesSize(static_cast(valueHashes.size())); } else { // all entries are received, move to next commit return -E_NOT_FOUND; @@ -521,7 +521,8 @@ int ValueSliceSync::GetValidValueSliceHashNode(MultiVerSyncTaskContext *context, int ValueSliceSync::Send(const DeviceID &deviceId, const Message *inMsg) { - int errCode = communicateHandle_->SendMessage(deviceId, inMsg, false, SEND_TIME_OUT); + SendConfig conf = {false, SEND_TIME_OUT}; + int errCode = communicateHandle_->SendMessage(deviceId, inMsg, conf); if (errCode != E_OK) { LOGE("ValueSliceSync::Send ERR! err = %d", errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/test/BUILD.gn b/services/distributeddataservice/libs/distributeddb/test/BUILD.gn index efda2409d0a8070fcc23e21f6e93c61004777a7b..c29b5c53ac48729da63998e5f9cac51bc5752735 100755 --- a/services/distributeddataservice/libs/distributeddb/test/BUILD.gn +++ b/services/distributeddataservice/libs/distributeddb/test/BUILD.gn @@ -104,6 +104,7 @@ ohos_source_set("src_file") { "../common/src/task_queue.cpp", "../common/src/time_tick_monitor.cpp", "../common/src/types_export.cpp", + "../common/src/user_change_monitor.cpp", "../common/src/value_object.cpp", "../common/src/zlib_compression.cpp", "../communicator/src/combine_status.cpp", @@ -222,6 +223,7 @@ ohos_source_set("src_file") { "../syncer/src/single_ver_data_message_schedule.cpp", "../syncer/src/single_ver_data_packet.cpp", "../syncer/src/single_ver_data_sync.cpp", + "../syncer/src/single_ver_data_sync_utils.cpp", "../syncer/src/single_ver_kv_sync_task_context.cpp", "../syncer/src/single_ver_kv_syncer.cpp", "../syncer/src/single_ver_relational_sync_task_context.cpp", @@ -233,6 +235,7 @@ ohos_source_set("src_file") { "../syncer/src/single_ver_sync_task_context.cpp", "../syncer/src/single_ver_syncer.cpp", "../syncer/src/subscribe_manager.cpp", + "../syncer/src/sync_config.cpp", "../syncer/src/sync_engine.cpp", "../syncer/src/sync_operation.cpp", "../syncer/src/sync_state_machine.cpp", @@ -652,6 +655,11 @@ distributeddb_unittest("DistributedDBRelationalGetDataTest") { [ "unittest/common/storage/distributeddb_relational_get_data_test.cpp" ] } +distributeddb_unittest("DistributedDBSingleVerMultiUserTest") { + sources = + [ "unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp" ] +} + ############################################################################### group("unittest") { testonly = true @@ -703,6 +711,7 @@ group("unittest") { ":DistributedDBSchemaObjectTest", ":DistributedDBSchemalTest", ":DistributedDBSingleVerMsgScheduleTest", + ":DistributedDBSingleVerMultiUserTest", ":DistributedDBSingleVerP2PQuerySyncTest", ":DistributedDBSingleVerP2PSubscribeSyncTest", ":DistributedDBSingleVerP2PSyncCheckTest", diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_auto_launch_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_auto_launch_test.cpp index b4a84e5d34214c8da56aa1573ff3c79ee5b8c152..21c729bedda94a3f7b4fa5d803b1f0bfc2c6c2a9 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_auto_launch_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_auto_launch_test.cpp @@ -78,6 +78,15 @@ namespace { std::string g_identifierG; std::string g_identifierH; std::string g_identifierI; + std::string g_dualIdentifierA; + std::string g_dualIdentifierB; + std::string g_dualIdentifierC; + std::string g_dualIdentifierD; + std::string g_dualIdentifierE; + std::string g_dualIdentifierF; + std::string g_dualIdentifierG; + std::string g_dualIdentifierH; + std::string g_dualIdentifierI; } class DistributedDBAutoLaunchUnitTest : public testing::Test { @@ -119,18 +128,21 @@ void DistributedDBAutoLaunchUnitTest::TearDownTestCase(void) RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); } -static void GetProperty(KvDBProperties &prop, std::string &identifier, std::string storeId) +static void GetProperty(KvDBProperties &prop, std::string &identifier, std::string storeId, std::string &dualIdentifier) { prop.SetStringProp(KvDBProperties::USER_ID, USER_ID); prop.SetStringProp(KvDBProperties::APP_ID, APP_ID); prop.SetStringProp(KvDBProperties::STORE_ID, storeId); identifier = DBCommon::TransferHashString(USER_ID + "-" + APP_ID + "-" + storeId); prop.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier); + dualIdentifier = DBCommon::TransferHashString(APP_ID + "-" + storeId); + prop.SetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, dualIdentifier); std::string identifierDirA = DBCommon::TransferStringToHex(identifier); prop.SetStringProp(KvDBProperties::IDENTIFIER_DIR, identifierDirA); prop.SetStringProp(KvDBProperties::DATA_DIR, g_testDir); prop.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE); prop.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true); + prop.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false); } void DistributedDBAutoLaunchUnitTest::SetUp(void) @@ -140,15 +152,15 @@ void DistributedDBAutoLaunchUnitTest::SetUp(void) g_testDir + "/" + DBCommon::TransferStringToHex(g_identifierA) + "/single_ver") != 0) { LOGE("rm test db files error!"); } - GetProperty(g_propA, g_identifierA, STORE_ID_0); - GetProperty(g_propB, g_identifierB, STORE_ID_1); - GetProperty(g_propC, g_identifierC, STORE_ID_2); - GetProperty(g_propD, g_identifierD, STORE_ID_3); - GetProperty(g_propE, g_identifierE, STORE_ID_4); - GetProperty(g_propF, g_identifierF, STORE_ID_5); - GetProperty(g_propG, g_identifierG, STORE_ID_6); - GetProperty(g_propH, g_identifierH, STORE_ID_7); - GetProperty(g_propI, g_identifierI, STORE_ID_8); + GetProperty(g_propA, g_identifierA, STORE_ID_0, g_dualIdentifierA); + GetProperty(g_propB, g_identifierB, STORE_ID_1, g_dualIdentifierB); + GetProperty(g_propC, g_identifierC, STORE_ID_2, g_dualIdentifierC); + GetProperty(g_propD, g_identifierD, STORE_ID_3, g_dualIdentifierD); + GetProperty(g_propE, g_identifierE, STORE_ID_4, g_dualIdentifierE); + GetProperty(g_propF, g_identifierF, STORE_ID_5, g_dualIdentifierF); + GetProperty(g_propG, g_identifierG, STORE_ID_6, g_dualIdentifierG); + GetProperty(g_propH, g_identifierH, STORE_ID_7, g_dualIdentifierH); + GetProperty(g_propI, g_identifierI, STORE_ID_8, g_dualIdentifierI); } static void PutSyncData(const KvDBProperties &prop, const Key &key, const Value &value) @@ -223,21 +235,21 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch001, TestSize.Level3) * @tc.steps: step4. param A disable * @tc.expected: step4. E_OK. */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID); EXPECT_TRUE(errCode == E_OK); /** * @tc.steps: step5. param B disable * @tc.expected: step5. -E_NOT_FOUND. */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == -E_NOT_FOUND); /** * @tc.steps: step6. param C disable * @tc.expected: step6. E_OK. */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID); EXPECT_TRUE(errCode == E_OK); } @@ -306,8 +318,10 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch002, TestSize.Level3) * @tc.steps: step4. param A B disable * @tc.expected: step4. notifier WRITE_CLOSED */ - EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA) == E_OK); - EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID) + == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID) + == E_OK); std::unique_lock lock(cvMutex); cv.wait(lock, [&finished] {return finished;}); @@ -381,10 +395,10 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch003, TestSize.Level3) * @tc.steps: step4. param A B disable * @tc.expected: step4. notifier WRITE_CLOSED */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID); EXPECT_TRUE(errCode == E_OK); std::unique_lock lock(cvMutex); @@ -408,35 +422,27 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch004, TestSize.Level3) */ AutoLaunchOption option; option.notifier = nullptr; - int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propC, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propD, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propE, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propF, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propG, nullptr, option); - EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propH, nullptr, option); - EXPECT_TRUE(errCode == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propC, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propD, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propE, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propF, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propG, nullptr, option) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propH, nullptr, option) == E_OK); /** * @tc.steps: step2. right param I enable * @tc.expected: step2. -E_MAX_LIMITS. */ - errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propI, nullptr, option); + int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propI, nullptr, option); EXPECT_TRUE(errCode == -E_MAX_LIMITS); /** * @tc.steps: step3. param A disable * @tc.expected: step3. E_OK. */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID); EXPECT_TRUE(errCode == E_OK); /** @@ -450,21 +456,21 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch004, TestSize.Level3) * @tc.steps: step6. param B~I disable * @tc.expected: step6. E_OK. */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierD); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierD, g_dualIdentifierD, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierE); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierE, g_dualIdentifierE, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierF); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierF, g_dualIdentifierF, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierG); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierG, g_dualIdentifierG, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierH); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierH, g_dualIdentifierH, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierI); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierI, g_dualIdentifierI, USER_ID); EXPECT_TRUE(errCode == E_OK); } @@ -528,7 +534,9 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch005, TestSize.Level3) * @tc.steps: step4. param A disable * @tc.expected: step4. notifier WRITE_CLOSED */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + std::string identifierA = g_propA.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + std::string userIdA = g_propA.GetStringProp(KvDBProperties::USER_ID, ""); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == E_OK); std::unique_lock lock(cvMutex); @@ -581,9 +589,9 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch006, TestSize.Level3) errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, notifier, option); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == E_OK); LOGD("AutoLaunch006 disable i:%d", i); } @@ -910,9 +918,13 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch012, TestSize.Level3) * @tc.steps: step5. param A B disable * @tc.expected: step5. OK */ - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB); + std::string identifierA = g_propA.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + std::string userIdA = g_propA.GetStringProp(KvDBProperties::USER_ID, ""); + std::string identifierB = g_propB.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + std::string userIdB = g_propB.GetStringProp(KvDBProperties::USER_ID, ""); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID); EXPECT_TRUE(errCode == E_OK); - errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA); + errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID); EXPECT_TRUE(errCode == E_OK); } @@ -994,7 +1006,9 @@ HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch013, TestSize.Level3) * @tc.steps: step4. param A B disable * @tc.expected: step4. notifier WRITE_CLOSED */ - EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB) == E_OK); - EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC) == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID) + == E_OK); + EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID) + == E_OK); g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false); } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp index 3dac9b661ec5e06e301f0d4e69279063dd00e1ba..92312b64b35e4b93c0c6478bfc26296640c33ca7 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp @@ -14,16 +14,19 @@ */ #include "adapter_stub.h" +#include #include "db_errno.h" #include "endian_convert.h" #include "frame_header.h" +#include "iprocess_communicator.h" #include "log_print.h" +#include "distributeddb_communicator_common.h" using namespace DistributedDB; namespace { - const uint32_t MTU_SIZE = 5 * 1024 * 1024; // 5 M, 1024 is scale - const uint32_t TIME_OUT = 5 * 1000; // 5 S, 1000 is scale + const uint32_t STUB_MTU_SIZE = 5 * 1024 * 1024; // 5 M, 1024 is scale + const uint32_t STUB_TIME_OUT = 5 * 1000; // 5 S, 1000 is scale } /* @@ -46,7 +49,7 @@ void AdapterStub::StopAdapter() uint32_t AdapterStub::GetMtuSize() { - return MTU_SIZE; + return STUB_MTU_SIZE; } uint32_t AdapterStub::GetMtuSize(const std::string &target) @@ -56,7 +59,7 @@ uint32_t AdapterStub::GetMtuSize(const std::string &target) uint32_t AdapterStub::GetTimeout() { - return TIME_OUT; + return STUB_TIME_OUT; } uint32_t AdapterStub::GetTimeout(const std::string &target) @@ -127,6 +130,12 @@ bool AdapterStub::IsDeviceOnline(const std::string &device) { return true; } + +std::shared_ptr AdapterStub::GetExtendHeaderHandle(const ExtendInfo ¶mInfo) +{ + std::shared_ptr handle = std::make_shared(paramInfo); + return handle; +} /* * Extended Part */ @@ -180,7 +189,29 @@ void AdapterStub::DeliverBytes(const std::string &srcTarget, const uint8_t *byte { std::lock_guard onReceiveLockGuard(onReceiveMutex_); if (onReceiveHandle_) { - onReceiveHandle_(srcTarget, bytes, length); + uint32_t headLength = 0; + std::string userId; + CheckAndGetDataHeadInfo(bytes, length, headLength, userId); + onReceiveHandle_(srcTarget, bytes + headLength, length - headLength, userId); + } +} + +void AdapterStub::CheckAndGetDataHeadInfo(const uint8_t *data, uint32_t totalLen, uint32_t &headLength, + std::string &userId) +{ + auto info = reinterpret_cast(data); + NetToHost(info->magic); + if (info->magic == ExtendHeaderHandleTest::MAGIC_NUM) { + NetToHost(info->length); + NetToHost(info->version); + headLength = info->length; + std::string tmpUserId(BUFF_LEN, 0); + for (uint8_t i = 0; i < BUFF_LEN; i++) { + tmpUserId[i] = info->userId[i]; + } + userId = tmpUserId; + } else { + headLength = 0; } } diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h index e1e754474462bb18e8afcc0528927d65f2cbc9fe..bc942a5a430733b3830883e266ef0d15a1c64e86 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h @@ -48,6 +48,11 @@ public: bool IsDeviceOnline(const std::string &device) override; + std::shared_ptr GetExtendHeaderHandle(const ExtendInfo ¶mInfo) override; + + void CheckAndGetDataHeadInfo(const uint8_t *data, uint32_t totalLen, uint32_t &headLength, + std::string &userId); + /* * Extended Part */ diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h index 543ee944f6c0951214ec7102564fe505c61c189f..da8823946957063de7936830d5443e96510947d6 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h @@ -19,10 +19,13 @@ #include #include #include +#include "endian_convert.h" #include "message.h" #include "adapter_stub.h" #include "frame_header.h" +#include "iprocess_communicator.h" #include "communicator_aggregator.h" +#include "store_types.h" struct EnvHandle { DistributedDB::AdapterStub *adapterHandle = nullptr; @@ -59,6 +62,54 @@ struct UnRegedTinyObject { uint32_t placeHolder_ = 0; }; +const uint32_t BUFF_LEN = 16; +struct ExtendHeadInfo { + uint32_t magic; + uint32_t length; + uint32_t version; + uint8_t userId[BUFF_LEN] = {0}; +}; + +class ExtendHeaderHandleTest : public DistributedDB::ExtendHeaderHandle { +public: + explicit ExtendHeaderHandleTest(const DistributedDB::ExtendInfo &info) + { + localDbProperty_.appId = info.appId; + localDbProperty_.storeId = info.storeId; + localDbProperty_.userId = info.userId; + localDbProperty_.dstTarget = info.dstTarget; + }; + ~ExtendHeaderHandleTest() {}; + // headSize should be 8 byte align + // return OK and headSize = 0 if no need to fill Head Data + // return OK and headSize > 0 if permit sync and will call FillHeadData + // return NO_PERMISSION if not permit sync + DistributedDB::DBStatus GetHeadDataSize(uint32_t &headSize) override + { + headSize_ = sizeof(ExtendHeadInfo); + headSize_ = BYTE_8_ALIGN(headSize_); + headSize = headSize_; + return DistributedDB::OK; + }; + + DistributedDB::DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) override + { + ExtendHeadInfo info = {MAGIC_NUM, headSize_, 0}; + DistributedDB::HostToNet(info.magic); + DistributedDB::HostToNet(info.length); + DistributedDB::HostToNet(info.version); + for (uint8_t i = 0; i < BUFF_LEN; i++) { + info.userId[i] = localDbProperty_.userId[i]; + } + memcpy_s(data, totalLen, &info, sizeof(ExtendHeadInfo)); + return DistributedDB::OK; + }; + static constexpr int MAGIC_NUM = 0xF2; +private: + DistributedDB::ExtendInfo localDbProperty_; + uint32_t headSize_; +}; + const std::string DEVICE_NAME_A = "DeviceA"; const std::string DEVICE_NAME_B = "DeviceB"; const std::string DEVICE_NAME_C = "DeviceC"; diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp index d6bda1267a7719563f4a2c31fa9ebbfa12f1bc1d..c7447567c172c7b9a072715d351fddb27949a30d 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp @@ -161,7 +161,8 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, WaitAndRetrySend001, TestSize.Level2 */ Message *msgForAB = BuildRegedTinyMessage(); ASSERT_NE(msgForAB, nullptr); - int errCode = g_commAB->SendMessage(DEVICE_NAME_B, msgForAB, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commAB->SendMessage(DEVICE_NAME_B, msgForAB, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Wait 100 ms EXPECT_EQ(msgForBB, nullptr); @@ -327,7 +328,8 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, Fragment001, TestSize.Level2) const uint32_t dataLength = 13 * 1024 * 1024; // 13 MB, 1024 is scale Message *sendMsgForAB = BuildRegedGiantMessage(dataLength); ASSERT_NE(sendMsgForAB, nullptr); - int errCode = g_commAB->SendMessage(DEVICE_NAME_B, sendMsgForAB, false, 0); + SendConfig conf = {false, 0}; + int errCode = g_commAB->SendMessage(DEVICE_NAME_B, sendMsgForAB, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(2600)); // Wait 2600 ms to make sure send done ASSERT_NE(recvMsgForBB, nullptr); @@ -387,7 +389,8 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, Fragment002, TestSize.Level2) uint32_t dataLength = 13 * 1024 * 1024; // 13 MB, 1024 is scale Message *sendMsgForBC = BuildRegedGiantMessage(dataLength); ASSERT_NE(sendMsgForBC, nullptr); - int errCode = g_commBC->SendMessage(DEVICE_NAME_C, sendMsgForBC, false, 0); + SendConfig conf = {false, 0}; + int errCode = g_commBC->SendMessage(DEVICE_NAME_C, sendMsgForBC, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(2600)); // Wait 2600 ms to make sure send done EXPECT_EQ(recvMsgForCC, nullptr); @@ -404,7 +407,7 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, Fragment002, TestSize.Level2) dataLength = 17 * 1024 * 1024; // 17 MB, 1024 is scale Message *resendMsgForBC = BuildRegedGiantMessage(dataLength); ASSERT_NE(resendMsgForBC, nullptr); - errCode = g_commBC->SendMessage(DEVICE_NAME_C, resendMsgForBC, false, 0); + errCode = g_commBC->SendMessage(DEVICE_NAME_C, resendMsgForBC, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(3400)); // Wait 3400 ms to make sure send done ASSERT_NE(recvMsgForCC, nullptr); @@ -457,7 +460,8 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, Fragment003, TestSize.Level3) uint32_t dataLength = 23 * 1024 * 1024; // 23 MB, 1024 is scale Message *sendMsgForAB = BuildRegedGiantMessage(dataLength); ASSERT_NE(sendMsgForAB, nullptr); - int errCode = g_commAB->SendMessage(DEVICE_NAME_B, sendMsgForAB, false, 0); + SendConfig conf = {false, 0}; + int errCode = g_commAB->SendMessage(DEVICE_NAME_B, sendMsgForAB, conf); EXPECT_EQ(errCode, E_OK); /** @@ -465,7 +469,7 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, Fragment003, TestSize.Level3) */ Message *sendMsgForCC = BuildRegedGiantMessage(dataLength); ASSERT_NE(sendMsgForCC, nullptr); - errCode = g_commCC->SendMessage(DEVICE_NAME_B, sendMsgForCC, false, 0); + errCode = g_commCC->SendMessage(DEVICE_NAME_B, sendMsgForCC, conf); EXPECT_EQ(errCode, E_OK); /** diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp index 9fe08435dca6b1948b290db8c3d7fe93800bac18..204e08876f77e4661c782543a7a89317141b8078 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp @@ -20,6 +20,9 @@ #include "distributeddb_tools_unit_test.h" #include "log_print.h" #include "message.h" +#include "protocol_proto.h" +#include "time_sync.h" +#include "sync_types.h" using namespace std; using namespace testing::ext; @@ -105,6 +108,16 @@ void DistributedDBCommunicatorSendReceiveTest::TearDown() std::this_thread::sleep_for(std::chrono::milliseconds(200)); // Wait 200 ms to make sure all thread quiet } +static Message *BuildAppLayerFrameMessage() +{ + DistributedDBUnitTest::DataSyncMessageInfo info; + info.messageId_ = DistributedDB::TIME_SYNC_MESSAGE; + info.messageType_ = TYPE_REQUEST; + DistributedDB::Message *message = nullptr; + DistributedDBUnitTest::DistributedDBToolsUnitTest::BuildMessage(info, message); + return message; +} + /** * @tc.name: Send And Receive 001 * @tc.desc: Test send and receive based on equipment communicator @@ -145,7 +158,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendAndReceive001, TestSize.L */ Message *msgForAA = BuildRegedTinyMessage(); ASSERT_NE(msgForAA, nullptr); - int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, true, 0); + SendConfig conf = {false, 0}; + int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(200)); // sleep 200 ms EXPECT_EQ(recvMsgForBB, nullptr); @@ -165,7 +179,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendAndReceive001, TestSize.L */ Message *msgForBB = BuildRegedTinyMessage(); ASSERT_NE(msgForBB, nullptr); - errCode = g_commBB->SendMessage(DEVICE_NAME_A, msgForBB, true, 0); + conf = {true, 0}; + errCode = g_commBB->SendMessage(DEVICE_NAME_A, msgForBB, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(srcTargetForAA, ""); @@ -194,7 +209,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendAndReceive002, TestSize.L */ Message *msgForAA = BuildRegedOverSizeMessage(); ASSERT_NE(msgForAA, nullptr); - int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf); EXPECT_NE(errCode, E_OK); delete msgForAA; msgForAA = nullptr; @@ -223,7 +239,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendAndReceive003, TestSize.L */ Message *msgForAA = BuildUnRegedTinyMessage(); ASSERT_NE(msgForAA, nullptr); - int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf); EXPECT_NE(errCode, E_OK); delete msgForAA; msgForAA = nullptr; @@ -269,7 +286,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendFlowControl001, TestSize. while (true) { Message *msgForBA = BuildRegedHugeMessage(); ASSERT_NE(msgForBA, nullptr); - int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); if (errCode == E_OK) { sendCount++; } else { @@ -333,7 +351,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendFlowControl002, TestSize. while (sendCount < SEND_COUNT_GOAL) { Message *msgForBA = BuildRegedHugeMessage(); ASSERT_NE(msgForBA, nullptr); - int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, false, 0); + SendConfig conf = {false, 0}; + int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); if (errCode != E_OK) { delete msgForBA; msgForBA = nullptr; @@ -398,7 +417,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendFlowControl003, TestSize. while (sendCnt < SEND_COUNT_GOAL) { Message *msgForBA = BuildRegedHugeMessage(); ASSERT_NE(msgForBA, nullptr); - int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, false, 100); // 100 ms timeout + SendConfig conf = {false, 100}; + int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); // 100 ms timeout if (errCode != E_OK) { delete msgForBA; msgForBA = nullptr; @@ -451,7 +471,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck001, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInMagicField(true, 0xFFFF); Message *msgForBA = BuildRegedTinyMessage(); - int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -463,7 +484,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck001, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInVersionField(true, 0xFFFF); msgForBA = BuildRegedTinyMessage(); - errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -475,7 +496,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck001, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInCheckSumField(true, 0xFFFF); msgForBA = BuildRegedTinyMessage(); - errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -511,7 +532,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck002, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInPacketLenField(true, 0xFFFF); Message *msgForBA = BuildRegedTinyMessage(); - int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + SendConfig conf = {true, 0}; + int errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -523,7 +545,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck002, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInPacketTypeField(true, 0xFF); msgForBA = BuildRegedTinyMessage(); - errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -535,7 +557,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, ReceiveCheck002, TestSize.Lev */ g_envDeviceB.adapterHandle->SimulateSendBitErrorInPaddingLenField(true, 0xFF); msgForBA = BuildRegedTinyMessage(); - errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, true, 0); + errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(recvCount, 0); @@ -571,7 +593,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendResultNotify001, TestSize */ Message *msgForAA = BuildRegedTinyMessage(); ASSERT_NE(msgForAA, nullptr); - int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, false, 0, sendResultNotifier); + SendConfig conf = {false, 0}; + int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf, sendResultNotifier); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep 100 ms ASSERT_EQ(sendResult.size(), static_cast(1)); // 1 notify @@ -588,7 +611,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendResultNotify001, TestSize */ msgForAA = BuildRegedTinyMessage(); ASSERT_NE(msgForAA, nullptr); - errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, false, 0, sendResultNotifier); + errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf, sendResultNotifier); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep 100 ms ASSERT_EQ(sendResult.size(), static_cast(2)); // 2 notify @@ -630,7 +653,8 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, MessageFeedback001, TestSize. */ Message *msgForBB = BuildRegedTinyMessage(); ASSERT_NE(msgForBB, nullptr); - int errCode = g_commBB->SendMessage(DEVICE_NAME_A, msgForBB, false, 0); + SendConfig conf = {false, 0}; + int errCode = g_commBB->SendMessage(DEVICE_NAME_A, msgForBB, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep 100 ms ASSERT_NE(recvMsgForBB, nullptr); @@ -655,7 +679,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, MessageFeedback001, TestSize. */ Message *msgForBA = BuildRegedTinyMessage(); ASSERT_NE(msgForBA, nullptr); - errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, false, 0); + errCode = g_commBA->SendMessage(DEVICE_NAME_A, msgForBA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep 100 ms ASSERT_NE(recvMsgForBA, nullptr); @@ -673,4 +697,52 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, MessageFeedback001, TestSize. g_envDeviceB.adapterHandle->SimulateSendBitErrorInMessageIdField(false, 0); AdapterStub::DisconnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); CommunicatorAggregator::EnableCommunicatorNotFoundFeedback(false); +} + +/** + * @tc.name: SendAndReceiveWithExtendHead001 + * @tc.desc: Test fill extendHead func + * @tc.type: FUNC + * @tc.require: AR000BVDGI AR000CQE0M + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendAndReceiveWithExtendHead001, TestSize.Level1) +{ + // Preset + string srcTargetForAA; + Message *recvMsgForAA = nullptr; + string srcTargetForBA; + Message *recvMsgForBA = nullptr; + TimeSync::RegisterTransformFunc(); + g_commAA->RegOnMessageCallback([&srcTargetForAA, &recvMsgForAA](const std::string &srcTarget, Message *inMsg){ + srcTargetForAA = srcTarget; + recvMsgForAA = inMsg; + }, nullptr); + g_commBA->RegOnMessageCallback([&srcTargetForBA, &recvMsgForBA](const std::string &srcTarget, Message *inMsg){ + srcTargetForBA = srcTarget; + recvMsgForBA = inMsg; + }, nullptr); + + /** + * @tc.steps: step1. connect device A with device B + */ + AdapterStub::ConnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); + + /** + * @tc.steps: step2. device A send ApplayerFrameMessage to device B using communicator AA with extednHead + * @tc.expected: step2. communicator BA received the message + */ + Message *msgForAA = BuildAppLayerFrameMessage(); + ASSERT_NE(msgForAA, nullptr); + SendConfig conf = {false, 0, {"appId", "storeId", "userId", "deviceB"}, true}; + int errCode = g_commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf); + EXPECT_EQ(errCode, E_OK); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); // sleep 200 ms + EXPECT_EQ(srcTargetForBA, DEVICE_NAME_A); + ASSERT_NE(recvMsgForBA, nullptr); + delete recvMsgForBA; + recvMsgForBA = nullptr; + DistributedDB::ProtocolProto::UnRegTransformFunction(DistributedDB::TIME_SYNC_MESSAGE); + // CleanUp + AdapterStub::DisconnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp index 57bac997efc0167af773e3b6376e577ffa3d24cd..8407d33843047e2727445c8639086bad81e64bbc 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp @@ -447,7 +447,7 @@ HWTEST_F(DistributedDBCommunicatorTest, ReportCommunicatorNotFound001, TestSize. */ std::vector lackLabels; int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback( - [&lackLabels](const LabelType &commLabel)->int { + [&lackLabels](const LabelType &commLabel, const std::string &userId)->int { lackLabels.push_back(commLabel); return -E_NOT_FOUND; }, nullptr); @@ -467,7 +467,8 @@ HWTEST_F(DistributedDBCommunicatorTest, ReportCommunicatorNotFound001, TestSize. ASSERT_NOT_NULL_AND_ACTIVATE(commAA); Message *msgForAA = BuildRegedTinyMessage(); ASSERT_NE(msgForAA, nullptr); - errCode = commAA->SendMessage(DEVICE_NAME_B, msgForAA, true, 0); + SendConfig conf = {true, 0}; + errCode = commAA->SendMessage(DEVICE_NAME_B, msgForAA, conf); EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Sleep 100 ms ASSERT_EQ(lackLabels.size(), static_cast(1)); @@ -499,7 +500,8 @@ HWTEST_F(DistributedDBCommunicatorTest, ReportCommunicatorNotFound001, TestSize. Message *msgFor##src##label = BuildRegedTinyMessage(); \ ASSERT_NE(msgFor##src##label, nullptr); \ msgFor##src##label->SetSessionId(session); \ - errCode = comm##src##label->SendMessage(DEVICE_NAME_##dst, msgFor##src##label, true, 0); \ + SendConfig conf = {true, 0}; \ + errCode = comm##src##label->SendMessage(DEVICE_NAME_##dst, msgFor##src##label, conf); \ EXPECT_EQ(errCode, E_OK); \ } @@ -507,7 +509,8 @@ HWTEST_F(DistributedDBCommunicatorTest, ReportCommunicatorNotFound001, TestSize. { \ Message *msgFor##src##label = BuildRegedGiantMessage(size); \ ASSERT_NE(msgFor##src##label, nullptr); \ - errCode = comm##src##label->SendMessage(DEVICE_NAME_##dst, msgFor##src##label, false, 0); \ + SendConfig conf = {false, 0}; \ + errCode = comm##src##label->SendMessage(DEVICE_NAME_##dst, msgFor##src##label, conf); \ EXPECT_EQ(errCode, E_OK); \ } @@ -539,7 +542,7 @@ HWTEST_F(DistributedDBCommunicatorTest, ReDeliverMessage001, TestSize.Level1) */ std::vector lackLabels; int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback( - [&lackLabels](const LabelType &commLabel)->int { + [&lackLabels](const LabelType &commLabel, const std::string &userId)->int { lackLabels.push_back(commLabel); return E_OK; }, nullptr); @@ -626,7 +629,8 @@ HWTEST_F(DistributedDBCommunicatorTest, ReDeliverMessage002, TestSize.Level1) /** * @tc.steps: step2. device B register communicator not found callback to CommunicatorAggregator */ - int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback([](const LabelType &commLabel)->int { + int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback([](const LabelType &commLabel, + const std::string &userId)->int { return E_OK; }, nullptr); EXPECT_EQ(errCode, E_OK); @@ -699,7 +703,8 @@ HWTEST_F(DistributedDBCommunicatorTest, ReDeliverMessage003, TestSize.Level2) /** * @tc.steps: step1. device B register communicator not found callback to CommunicatorAggregator */ - int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback([](const LabelType &commLabel)->int { + int errCode = g_envDeviceB.commAggrHandle->RegCommunicatorLackCallback([](const LabelType &commLabel, + const std::string &userId)->int { return E_OK; }, nullptr); EXPECT_EQ(errCode, E_OK); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_auto_launch_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_auto_launch_test.cpp index abad6458f90f68cd73686568c9ce2b6712cce393..2be6f5f43f951f302cef774449a2a19e1d1dfeb5 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_auto_launch_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_auto_launch_test.cpp @@ -102,9 +102,14 @@ namespace { { if (lackCallback_) { std::vector vect(identifier.begin(), identifier.end()); - lackCallback_(vect); + lackCallback_(vect, USER_ID1); } } + + int GetLocalIdentity(std::string &outTarget) const override + { + return E_OK; + } private: CommunicatorLackCallback lackCallback_; }; diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index 6bf5b9feac71d3fbb79d9910c646efefc9a6b754..c96e31d1bc283ce7164662031d02469855b90b09 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -14,6 +14,8 @@ */ #include +#include +#include #include "db_common.h" #include "distributeddb_data_generate_unit_test.h" @@ -78,6 +80,7 @@ void DistributedDBInterfacesRelationalTest::SetUpTestCase(void) DistributedDBToolsUnitTest::TestDirInit(g_testDir); LOGD("Test dir is %s", g_testDir.c_str()); g_dbDir = g_testDir + "/"; + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); } void DistributedDBInterfacesRelationalTest::TearDownTestCase(void) @@ -648,4 +651,82 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePathCheckTest status = g_mgr.CloseStore(delegate2); EXPECT_EQ(status, INVALID_ARGS); +} + +HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePressureTest001, TestSize.Level1) +{ + /** + * @tc.steps:step1. Prepare db file + * @tc.expected: step1. Return OK. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + + DBStatus status = OK; + for (int i = 0; i < 1000; i++) { + RelationalStoreDelegate *delegate = nullptr; + status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + + status = g_mgr.CloseStore(delegate); + EXPECT_EQ(status, OK); + delegate = nullptr; + } +} + +HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalOpenStorePressureTest002, TestSize.Level1) +{ + /** + * @tc.steps:step1. Prepare db file + * @tc.expected: step1. Return OK. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + + std::queue delegateQueue; + std::mutex queuelock; + default_random_engine e; + uniform_int_distribution u(0, 9); + + std::thread openStoreThread([&, this]() { + for (int i = 0; i < 1000; i++) { + LOGD("++++> open store delegate: %d", i); + RelationalStoreDelegate *delegate = nullptr; + DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + { + std::lock_guard lock(queuelock); + delegateQueue.push(delegate); + } + LOGD("++++< open store delegate: %d", i); + } + }); + + int cnt = 0; + while (cnt < 1000) { + RelationalStoreDelegate *delegate = nullptr; + { + std::lock_guard lock(queuelock); + if (delegateQueue.empty()) { + std::this_thread::sleep_for(std::chrono::microseconds(100)); + continue; + } + delegate = delegateQueue.front(); + delegateQueue.pop(); + } + LOGD("++++> close store delegate: %d", cnt); + DBStatus status = g_mgr.CloseStore(delegate); + LOGD("++++< close store delegate: %d", cnt); + EXPECT_EQ(status, OK); + delegate = nullptr; + cnt++; + std::this_thread::sleep_for(std::chrono::microseconds(100 * u(e))); + } + openStoreThread.join(); } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp index c5d960d0bc3e952839ed8ee752643c959eb40c5f..b715fa7f8d8f4762058a96ef2439c086f62cd9af 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp @@ -165,6 +165,22 @@ int GetCount(sqlite3 *db, const string &sql, size_t &count) return errCode; } +std::string GetOneText(sqlite3 *db, const string &sql) +{ + std::string result; + sqlite3_stmt *stmt = nullptr; + int errCode = SQLiteUtils::GetStatement(db, sql, stmt); + if (errCode != E_OK) { + return result; + } + errCode = SQLiteUtils::StepWithRetry(stmt, false); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + SQLiteUtils::GetColumnTextValue(stmt, 0, result); + } + SQLiteUtils::ResetStatement(stmt, true, errCode); + return result; +} + int PutBatchData(uint32_t totalCount, uint32_t valueSize) { sqlite3 *db = nullptr; @@ -1149,4 +1165,101 @@ HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1 sqlite3_close(db); RefObject::DecObjRef(g_store); } + +/** + * @tc.name: SameFieldWithLogTable1 + * @tc.desc: Get query data OK when the table has same field with log table. + * @tc.type: FUNC + * @tc.require: AR000GK58H + * @tc.author: lidongwei + */ +HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1) +{ + ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); + ASSERT_NE(g_delegate, nullptr); + /** + * @tc.steps: step1. Create distributed table "dataPlus". + * @tc.expected: Succeed, return OK. + */ + const string tableName = g_tableName + "Plus"; + std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \ + device TEXT NOT NULL DEFAULT 'default_value');"; + sqlite3 *db = nullptr; + ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); + ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); + /** + * @tc.steps: step2. Put 1 record into dataPlus table. + * @tc.expected: Succeed, return OK. + */ + sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101 + ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + /** + * @tc.steps: step3. Get all data from dataPlus table. + * @tc.expected: Succeed and the count is right. + */ + auto store = GetRelationalStore(); + ASSERT_NE(store, nullptr); + ContinueToken token = nullptr; + QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false)); + std::vector entries; + EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); + EXPECT_EQ(entries.size(), 1UL); + SingleVerKvEntry::Release(entries); + sqlite3_close(db); + RefObject::DecObjRef(g_store); +} + +/** + * @tc.name: CompatibleData2 + * @tc.desc: Check compatibility. + * @tc.type: FUNC + * @tc.require: AR000GK58H + * @tc.author: lidongwei + */ +HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1) +{ + ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); + ASSERT_NE(g_delegate, nullptr); + ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); + + sqlite3 *db = nullptr; + ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); + + auto store = GetRelationalStore(); + ASSERT_NE(store, nullptr); + + /** + * @tc.steps: step1. Create distributed table from deviceA. + * @tc.expected: Succeed, return OK. + */ + const DeviceID deviceID = "deviceA"; + ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), + DBCommon::GetDistributedTableName(deviceID, g_tableName))); + + /** + * @tc.steps: step2. Alter "data" table and create distributed table again. + * @tc.expected: Succeed. + */ + std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;" + "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;" + "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;" + "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;"; + ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); + + /** + * @tc.steps: step3. Check deviceA's distributed table. + * @tc.expected: The create sql is correct. + */ + std::string expectSql = "CREATE TABLE naturalbase_rdb_aux_data_" + "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f(key integer NOT NULL PRIMARY KEY," + "value integer, integer_type integer, text_type text, real_type real, blob_type blob)"; + sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';"; + EXPECT_EQ(GetOneText(db, sql), expectSql); + + sqlite3_close(db); + RefObject::DecObjRef(g_store); +} #endif \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_ability_sync_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_ability_sync_test.cpp index b1a4da85c7dbefd5df738ce5aae14cc7d0353635..bd9ec951f80ba9373c9a24020712afed40bb09e7 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_ability_sync_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_ability_sync_test.cpp @@ -122,7 +122,7 @@ HWTEST_F(DistributedDBAbilitySyncTest, RequestPacketTest001, TestSize.Level0) AbilitySyncRequestPacket packet1; DbAbility ability1; #ifndef OMIT_ZLIB - ability1.SetAbilityItem(DATABASE_COMPRESSION_ZLIB, SUPPORT_MARK); + ability1.SetAbilityItem(SyncConfig::DATABASE_COMPRESSION_ZLIB, SUPPORT_MARK); #endif packet1.SetProtocolVersion(ABILITY_SYNC_VERSION_V1); packet1.SetSoftwareVersion(SOFTWARE_VERSION_CURRENT); @@ -339,7 +339,7 @@ HWTEST_F(DistributedDBAbilitySyncTest, AckPacketTest001, TestSize.Level0) AbilitySyncAckPacket packet1; DbAbility ability1; #ifndef OMIT_ZLIB - ability1.SetAbilityItem(DATABASE_COMPRESSION_ZLIB, SUPPORT_MARK); + ability1.SetAbilityItem(SyncConfig::DATABASE_COMPRESSION_ZLIB, SUPPORT_MARK); #endif packet1.SetProtocolVersion(ABILITY_SYNC_VERSION_V1); packet1.SetSoftwareVersion(SOFTWARE_VERSION_CURRENT); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_communicator_proxy_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_communicator_proxy_test.cpp index 0d4f923ba6fe8864e2d79ca00e698e884271912b..b3590ba985ea1154d4baa87130d6cebc52297703 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_communicator_proxy_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_communicator_proxy_test.cpp @@ -309,15 +309,16 @@ HWTEST_F(DistributedDBCommunicatorProxyTest, SendMessage001, TestSize.Level1) * @tc.steps: step1. Call SendMessage from CommProxy with param DEVICE_B. * @tc.expected: step1. MainComm's SendMessage willed called and return E_OK. */ - EXPECT_CALL(mainComm_, SendMessage(DEVICE_B, _, _, _, _)).WillOnce(Return(E_OK)); - EXPECT_EQ(commProxy_->SendMessage(DEVICE_B, nullptr, true, 0, nullptr), E_OK); + SendConfig conf = {true, 0}; + EXPECT_CALL(mainComm_, SendMessage(DEVICE_B, _, _, _)).WillOnce(Return(E_OK)); + EXPECT_EQ(commProxy_->SendMessage(DEVICE_B, nullptr, conf, nullptr), E_OK); /** * @tc.steps: step1. Call SendMessage from CommProxy with param DEVICE_C. * @tc.expected: step1. ExtComm's SendMessage willed called and return E_OK. */ - EXPECT_CALL(extComm_, SendMessage(DEVICE_C, _, _, _, _)).WillOnce(Return(E_OK)); - EXPECT_EQ(commProxy_->SendMessage(DEVICE_C, nullptr, true, 0, nullptr), E_OK); + EXPECT_CALL(extComm_, SendMessage(DEVICE_C, _, _, _)).WillOnce(Return(E_OK)); + EXPECT_EQ(commProxy_->SendMessage(DEVICE_C, nullptr, conf, nullptr), E_OK); } /** diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index f1ad561d2a0ea07a1a6d18297f5d70e2755761bb..711adc11ba56d0562f066341671f09ce3db43baf 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -212,8 +212,9 @@ HWTEST_F(DistributedDBMockSyncModuleTest, AutoLaunchCheck001, TestSize.Level1) * @tc.steps: step1. put AutoLaunchItem in cache to simulate a connection was auto launched */ std::string id = "TestAutoLaunch"; + std::string userId = "userId"; AutoLaunchItem item; - mockAutoLaunch.SetAutoLaunchItem(id, item); + mockAutoLaunch.SetAutoLaunchItem(id, userId, item); EXPECT_CALL(mockAutoLaunch, TryCloseConnection(_)).WillOnce(Return()); /** * @tc.steps: step2. send close singal to simulate a connection was unused in 1 min @@ -225,8 +226,8 @@ HWTEST_F(DistributedDBMockSyncModuleTest, AutoLaunchCheck001, TestSize.Level1) std::unique_lock lock(mutex); std::condition_variable cv; for (int i = 0; i < loopCount; i++) { - std::thread t = std::thread([&finishCount, &mockAutoLaunch, &id, &mutex, &cv] { - mockAutoLaunch.CallExtConnectionLifeCycleCallbackTask(id); + std::thread t = std::thread([&finishCount, &mockAutoLaunch, &id, &userId, &mutex, &cv] { + mockAutoLaunch.CallExtConnectionLifeCycleCallbackTask(id, userId); finishCount++; if (finishCount == loopCount) { std::unique_lock lockInner(mutex); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index 2b45522f0444436f955d3c4a75a63fe980175a60..69693babb9f83d77148a3ac70b7912ce981321fe 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -347,7 +347,9 @@ namespace { break; } case SQLITE_TEXT: { - dataValue.SetText(std::string(reinterpret_cast(sqlite3_column_text(statement, col)))); + std::string str; + SQLiteUtils::GetColumnTextValue(statement, col, str); + dataValue.SetText(str); break; } case SQLITE_BLOB: { diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10000da8aeee73b1453a5eeff6eea55b3512dba1 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "kv_store_nb_delegate.h" +#include "kv_virtual_device.h" +#include "platform_specific.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + string g_testDir; + const string STORE_ID = "kv_stroe_sync_test"; + const string USER_ID_1 = "userId1"; + const string USER_ID_2 = "userId2"; + const std::string DEVICE_B = "deviceB"; + const std::string DEVICE_C = "deviceC"; + const int WAIT_TIME = 1000; // 1000ms + + KvStoreDelegateManager g_mgr1(APP_ID, USER_ID_1); + KvStoreDelegateManager g_mgr2(APP_ID, USER_ID_2); + KvStoreConfig g_config; + DistributedDBToolsUnitTest g_tool; + KvStoreNbDelegate* g_kvDelegatePtr1 = nullptr; + KvStoreNbDelegate* g_kvDelegatePtr2 = nullptr; + VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr; + KvVirtualDevice *g_deviceB = nullptr; + KvVirtualDevice *g_deviceC = nullptr; + DBStatus g_kvDelegateStatus1 = INVALID_ARGS; + DBStatus g_kvDelegateStatus2 = INVALID_ARGS; + std::string g_identifier; + + // the type of g_kvDelegateCallback is function + auto g_kvDelegateCallback1 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, + placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus1), std::ref(g_kvDelegatePtr1)); + auto g_kvDelegateCallback2 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, + placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus2), std::ref(g_kvDelegatePtr2)); + auto g_syncActivationCheckCallback1 = [] (const std::string &userId, const std::string &appId, + const std::string &storeId)-> bool { + if (userId == USER_ID_2) { + return true; + } else { + return false; + } + return true; + }; + auto g_syncActivationCheckCallback2 = [] (const std::string &userId, const std::string &appId, + const std::string &storeId)-> bool { + if (userId == USER_ID_1) { + return true; + } else { + return false; + } + return true; + }; +} + +class DistributedDBSingleVerMultiUserTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedDBSingleVerMultiUserTest::SetUpTestCase(void) +{ + /** + * @tc.setup: Init datadir and Virtual Communicator. + */ + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + g_config.dataDir = g_testDir; + g_mgr1.SetKvStoreConfig(g_config); + g_mgr2.SetKvStoreConfig(g_config); + + string dir = g_testDir + "/single_ver"; + DIR* dirTmp = opendir(dir.c_str()); + if (dirTmp == nullptr) { + OS::MakeDBDirectory(dir); + } else { + closedir(dirTmp); + } + + g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator(); + ASSERT_TRUE(g_communicatorAggregator != nullptr); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator); +} + +void DistributedDBSingleVerMultiUserTest::TearDownTestCase(void) +{ + /** + * @tc.teardown: Release virtual Communicator and clear data dir. + */ + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error!"); + } + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); +} + +void DistributedDBSingleVerMultiUserTest::SetUp(void) +{ + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + /** + * @tc.setup: create virtual device B + */ + g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B); + ASSERT_TRUE(g_deviceB != nullptr); + VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_TRUE(syncInterfaceB != nullptr); + ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK); + g_deviceC = new (std::nothrow) KvVirtualDevice(DEVICE_C); + ASSERT_TRUE(g_deviceC != nullptr); + VirtualSingleVerSyncDBInterface *syncInterfaceC = new (std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_TRUE(syncInterfaceC != nullptr); + ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK); +} + +void DistributedDBSingleVerMultiUserTest::TearDown(void) +{ + /** + * @tc.teardown: Release device A, B, C + */ + if (g_deviceB != nullptr) { + delete g_deviceB; + g_deviceB = nullptr; + } + if (g_deviceC != nullptr) { + delete g_deviceC; + g_deviceC = nullptr; + } + SyncActivationCheckCallback callback = nullptr; + g_mgr1.SetSyncActivationCheckCallback(callback); +} + +namespace { +void OpenStore1(bool syncDualTupleMode = true) +{ + KvStoreNbDelegate::Option option; + option.syncDualTupleMode = syncDualTupleMode; + g_mgr1.GetKvStore(STORE_ID, option, g_kvDelegateCallback1); + ASSERT_TRUE(g_kvDelegateStatus1 == OK); + ASSERT_TRUE(g_kvDelegatePtr1 != nullptr); +} + +void OpenStore2(bool syncDualTupleMode = true) +{ + KvStoreNbDelegate::Option option; + option.syncDualTupleMode = syncDualTupleMode; + g_mgr2.GetKvStore(STORE_ID, option, g_kvDelegateCallback2); + ASSERT_TRUE(g_kvDelegateStatus2 == OK); + ASSERT_TRUE(g_kvDelegatePtr2 != nullptr); +} + +void CloseStore() +{ + if (g_kvDelegatePtr1 != nullptr) { + ASSERT_EQ(g_mgr1.CloseKvStore(g_kvDelegatePtr1), OK); + g_kvDelegatePtr1 = nullptr; + DBStatus status = g_mgr1.DeleteKvStore(STORE_ID); + LOGD("delete kv store status %d", status); + ASSERT_TRUE(status == OK); + } + if (g_kvDelegatePtr2 != nullptr) { + ASSERT_EQ(g_mgr2.CloseKvStore(g_kvDelegatePtr2), OK); + g_kvDelegatePtr2 = nullptr; + DBStatus status = g_mgr2.DeleteKvStore(STORE_ID); + LOGD("delete kv store status %d", status); + ASSERT_TRUE(status == OK); + } +} + +void CheckSyncTest(DBStatus status1, DBStatus status2, std::vector &devices) +{ + std::map result; + DBStatus status = g_tool.SyncTest(g_kvDelegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_TRUE(status == status1); + if (status == OK) { + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_TRUE(pair.second == OK); + } + } + result.clear(); + status = g_tool.SyncTest(g_kvDelegatePtr2, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_TRUE(status == status2); + if (status == OK) { + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_TRUE(pair.second == OK); + } + } +} + +bool AutoLaunchCallBack(const std::string &identifier, AutoLaunchParam ¶m, KvStoreObserverUnitTest *observer, + bool ret) +{ + LOGD("int AutoLaunchCallBack"); + EXPECT_TRUE(identifier == g_identifier); + param.appId = APP_ID; + param.storeId = STORE_ID; + CipherPassword passwd; + param.option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer, + 0, nullptr}; + param.notifier = nullptr; + param.option.syncDualTupleMode = true; + return ret; +} +} + +/** + * @tc.name: multi user 001 + * @tc.desc: Test multi user change + * @tc.type: FUNC + * @tc.require: AR000CQS3S SR000CQE0B + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser001, TestSize.Level0) +{ + /** + * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active + */ + g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1); + /** + * @tc.steps: step2. openstore1 and openstore2 + * @tc.expected: step2. only user2 sync mode is active + */ + + OpenStore1(); + OpenStore2(); + /** + * @tc.steps: step3. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k1, v1} + */ + Key key = {'1'}; + Value value = {'1'}; + Value value2 = {'2'}; + ASSERT_TRUE(g_kvDelegatePtr1->Put(key, value2) == OK); + ASSERT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK); + /** + * @tc.steps: step4. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync + * @tc.expected: step4. g_kvDelegatePtr2 call success + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + CheckSyncTest(NOT_ACTIVE, OK, devices); + /** + * @tc.steps: step5. g_kvDelegatePtr1 support some pragma cmd call + * @tc.expected: step5. Pragma call success + */ + int pragmaData = 1; + PragmaData input = static_cast(&pragmaData); + ASSERT_TRUE(g_kvDelegatePtr1->Pragma(AUTO_SYNC, input) == OK); + pragmaData = 100; + input = static_cast(&pragmaData); + ASSERT_TRUE(g_kvDelegatePtr1->Pragma(SET_QUEUED_SYNC_LIMIT, input) == OK); + ASSERT_TRUE(g_kvDelegatePtr1->Pragma(GET_QUEUED_SYNC_LIMIT, input) == OK); + ASSERT_TRUE(input == static_cast(&pragmaData)); + pragmaData = 1; + input = static_cast(&pragmaData); + ASSERT_TRUE(g_kvDelegatePtr1->Pragma(SET_WIPE_POLICY, input) == OK); + ASSERT_TRUE(g_kvDelegatePtr1->Pragma(SET_SYNC_RETRY, input) == OK); + /** + * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1} + */ + VirtualDataItem item; + g_deviceB->GetData(key, item); + EXPECT_TRUE(item.value == value); + /** + * @tc.expected: step7. user change + */ + g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2); + KvStoreDelegateManager::NotifyUserChanged(); + /** + * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync + * @tc.expected: step8. g_kvDelegatePtr1 call success + */ + devices.clear(); + devices.push_back(g_deviceC->GetDeviceId()); + CheckSyncTest(OK, NOT_ACTIVE, devices); + /** + * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1} + */ + g_deviceC->GetData(key, item); + EXPECT_TRUE(item.value == value2); + CloseStore(); +} + +/** + * @tc.name: multi user 002 + * @tc.desc: Test multi user not change + * @tc.type: FUNC + * @tc.require: AR000CQS3S SR000CQE0B + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser002, TestSize.Level0) +{ + /** + * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active + */ + g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1); + /** + * @tc.steps: step2. openstore1 and openstore2 + * @tc.expected: step2. only user2 sync mode is active + */ + + OpenStore1(); + OpenStore2(); + /** + * @tc.steps: step3. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k1, v1} + */ + Key key = {'1'}; + Value value = {'1'}; + ASSERT_TRUE(g_kvDelegatePtr1->Put(key, value) == OK); + ASSERT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK); + /** + * @tc.steps: step4. GetKvStoreIdentifier success when userId is invalid + */ + std::string userId; + ASSERT_TRUE(g_mgr1.GetKvStoreIdentifier(userId, APP_ID, USER_ID_2, true) != ""); + userId.resize(130); + ASSERT_TRUE(g_mgr1.GetKvStoreIdentifier(userId, APP_ID, USER_ID_2, true) != ""); + /** + * @tc.steps: step5. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync + * @tc.expected: step5. g_kvDelegatePtr2 call success + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + CheckSyncTest(NOT_ACTIVE, OK, devices); + /** + * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1} + */ + VirtualDataItem item; + g_deviceB->GetData(key, item); + EXPECT_TRUE(item.value == value); + /** + * @tc.expected: step7. user change + */ + KvStoreDelegateManager::NotifyUserChanged(); + /** + * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k2, v2} + */ + key = {'2'}; + value = {'2'}; + ASSERT_TRUE(g_kvDelegatePtr1->Put(key, value) == OK); + ASSERT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK); + /** + * @tc.steps: step9. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync + * @tc.expected: step9. g_kvDelegatePtr2 call success + */ + devices.clear(); + devices.push_back(g_deviceB->GetDeviceId()); + CheckSyncTest(NOT_ACTIVE, OK, devices); + /** + * @tc.expected: step10. onComplete should be called, DeviceB have {k2,v2} + */ + g_deviceB->GetData(key, item); + EXPECT_TRUE(item.value == value); + CloseStore(); +} + +/** + * @tc.name: multi user 003 + * @tc.desc: enhancement callback return true in multiuser mode + * @tc.type: FUNC + * @tc.require: AR000EPARJ + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser003, TestSize.Level3) +{ + /** + * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active + */ + g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1); + + KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest; + ASSERT_TRUE(observer != nullptr); + /** + * @tc.steps: step2. SetAutoLaunchRequestCallback + * @tc.expected: step2. success. + */ + g_mgr1.SetAutoLaunchRequestCallback( + std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true)); + + /** + * @tc.steps: step2. RunCommunicatorLackCallback + * @tc.expected: step2. success. + */ + g_identifier = g_mgr1.GetKvStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true); + EXPECT_TRUE(g_identifier == g_mgr1.GetKvStoreIdentifier(USER_ID_1, APP_ID, STORE_ID, true)); + std::vector label(g_identifier.begin(), g_identifier.end()); + g_communicatorAggregator->SetCurrentUserId(USER_ID_2); + g_communicatorAggregator->RunCommunicatorLackCallback(label); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); + /** + * @tc.steps: step3. device B put {k1, v1} + * @tc.expected: step3. success. + */ + Key key = {'1'}; + Value value = {'1'}; + TimeStamp currentTime; + (void)OS::GetCurrentSysTimeInMicrosecond(currentTime); + EXPECT_TRUE(g_deviceB->PutData(key, value, currentTime, 0) == OK); + /** + * @tc.steps: step4. device B push sync to A + * @tc.expected: step4. success. + */ + EXPECT_TRUE(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true) == OK); + EXPECT_TRUE(observer->GetCallCount() == 1); // only A + /** + * @tc.steps: step5. deviceA have {k1,v1} + * @tc.expected: step5. success. + */ + OpenStore2(); + Value actualValue; + g_kvDelegatePtr2->Get(key, actualValue); + EXPECT_EQ(actualValue, value); + std::this_thread::sleep_for(std::chrono::seconds(70)); + g_mgr1.SetAutoLaunchRequestCallback(nullptr); + CloseStore(); + delete observer; +} + +/** + * @tc.name: MultiUser004 + * @tc.desc: CommunicatorLackCallback in multi user mode + * @tc.type: FUNC + * @tc.require: AR000E8S2T + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser004, TestSize.Level0) +{ + /** + * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active + */ + g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1); + + /** + * @tc.steps: step2. right param A B enable + * @tc.expected: step2. success. + */ + AutoLaunchNotifier notifier = nullptr; + KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest; + ASSERT_TRUE(observer != nullptr); + AutoLaunchOption option; + CipherPassword passwd; + option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer, + 0, nullptr}; + option.notifier = nullptr; + option.observer = observer; + option.syncDualTupleMode = true; + EXPECT_TRUE(g_mgr1.EnableKvStoreAutoLaunch(USER_ID_2, APP_ID, STORE_ID, option, notifier) == OK); + EXPECT_TRUE(g_mgr1.EnableKvStoreAutoLaunch(USER_ID_1, APP_ID, STORE_ID, option, notifier) == OK); + + /** + * @tc.steps: step3. RunCommunicatorLackCallback + * @tc.expected: step3. userId2 open db successfully. + */ + g_identifier = g_mgr1.GetKvStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true); + std::vector label(g_identifier.begin(), g_identifier.end()); + g_communicatorAggregator->SetCurrentUserId(USER_ID_2); + g_communicatorAggregator->RunCommunicatorLackCallback(label); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); + /** + * @tc.steps: step5. device B put {k1, v1} + * @tc.expected: step5. success. + */ + Key key = {'1'}; + Value value = {'1'}; + TimeStamp currentTime; + (void)OS::GetCurrentSysTimeInMicrosecond(currentTime); + EXPECT_TRUE(g_deviceB->PutData(key, value, currentTime, 0) == OK); + /** + * @tc.steps: step6. device B push sync to A + * @tc.expected: step6. success. + */ + EXPECT_TRUE(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true) == OK); + EXPECT_TRUE(observer->GetCallCount() == 1); // only A + /** + * @tc.steps: step7. deviceA have {k1,v1} + * @tc.expected: step7. success. + */ + OpenStore2(); + Value actualValue; + g_kvDelegatePtr2->Get(key, actualValue); + EXPECT_EQ(actualValue, value); + /** + * @tc.steps: step8. param A B disable + * @tc.expected: step8. notifier WRITE_CLOSED + */ + EXPECT_TRUE(g_mgr1.DisableKvStoreAutoLaunch(USER_ID_2, APP_ID, STORE_ID) == OK); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); + EXPECT_TRUE(g_mgr1.DisableKvStoreAutoLaunch(USER_ID_1, APP_ID, STORE_ID) == OK); + CloseStore(); + delete observer; +} + +/** + * @tc.name: MultiUser005 + * @tc.desc: test NotifyUserChanged func when all db in normal sync mode + * @tc.type: FUNC + * @tc.require: AR000E8S2T + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser005, TestSize.Level0) +{ + /** + * @tc.steps: step1. openstore1 and openstore2 in normal sync mode + * @tc.expected: step1. only user2 sync mode is active + */ + + OpenStore1(false); + OpenStore2(false); + /** + * @tc.steps: step2. call NotifyUserChanged + * @tc.expected: step2. return OK + */ + EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK); + CloseStore(); + /** + * @tc.steps: step3. openstore1 open normal sync mode and and openstore2 in dual tuple + * @tc.expected: step3. only user2 sync mode is active + */ + OpenStore1(false); + OpenStore2(); + /** + * @tc.steps: step4. call NotifyUserChanged + * @tc.expected: step4. return OK + */ + EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK); + CloseStore(); +} \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_time_sync_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_time_sync_test.cpp index 0ab564c2bf6f2827d07d5330b37604ab10c7d164..42bec439f926a01dbef620f35b549ceb673cbe1a 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_time_sync_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_time_sync_test.cpp @@ -346,7 +346,8 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest001, TestSize.Level0) */ msg->SetMessageId(TIME_SYNC_MESSAGE); msg->SetMessageType(TYPE_REQUEST); - errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, false, 0); + SendConfig conf = {false, 0}; + errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); TimeSyncPacket data; @@ -364,7 +365,7 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest001, TestSize.Level0) msg->SetMessageId(DATA_SYNC_MESSAGE); msg->SetMessageType(TYPE_REQUEST); msg->SetCopiedObject<>(data); - errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, false, 0); + errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); /** @@ -376,7 +377,7 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest001, TestSize.Level0) msg->SetMessageId(TIME_SYNC_MESSAGE); msg->SetMessageType(TYPE_RESPONSE); msg->SetCopiedObject<>(data); - errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, false, 0); + errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); } @@ -416,7 +417,8 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest002, TestSize.Level0) */ msg->SetMessageId(TIME_SYNC_MESSAGE); msg->SetMessageType(TYPE_RESPONSE); - errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, false, 0); + SendConfig conf = {false, 0}; + errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); TimeSyncPacket data; @@ -434,7 +436,7 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest002, TestSize.Level0) msg->SetMessageId(DATA_SYNC_MESSAGE); msg->SetMessageType(TYPE_RESPONSE); msg->SetCopiedObject<>(data); - errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, false, 0); + errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); /** @@ -446,7 +448,7 @@ HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest002, TestSize.Level0) msg->SetMessageId(TIME_SYNC_MESSAGE); msg->SetMessageType(TYPE_REQUEST); msg->SetCopiedObject<>(data); - errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, false, 0); + errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf); EXPECT_TRUE(errCode == -E_INVALID_ARGS); } diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_auto_launch.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_auto_launch.h index f9f0d7a83f515694302a1e5114380b06df3fe476..253d605f7ebbb405504136cc8457028149352fdf 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_auto_launch.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_auto_launch.h @@ -23,15 +23,15 @@ namespace DistributedDB { class MockAutoLaunch : public AutoLaunch { public: - void SetAutoLaunchItem(const std::string &identify, AutoLaunchItem &item) + void SetAutoLaunchItem(const std::string &identify, const std::string &userId, AutoLaunchItem &item) { std::lock_guard autoLock(extLock_); - extItemMap_[identify] = item; + extItemMap_[identify][userId] = item; } - void CallExtConnectionLifeCycleCallbackTask(const std::string &identifier) + void CallExtConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId) { - AutoLaunch::ExtConnectionLifeCycleCallbackTask(identifier); + AutoLaunch::ExtConnectionLifeCycleCallbackTask(identifier, userId); } MOCK_METHOD1(TryCloseConnection, void(AutoLaunchItem &)); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_communicator.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_communicator.h index 52a103ec07191c6c949604d8936b90bd4bf5a5e8..b927f3216bdd3b7a1e11ed9c4e99f8d27f376965 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_communicator.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_communicator.h @@ -24,8 +24,8 @@ class MockCommunicator : public ICommunicator { public: MOCK_CONST_METHOD1(GetLocalIdentity, int(std::string &)); MOCK_CONST_METHOD2(GetRemoteCommunicatorVersion, int(const std::string &, uint16_t &)); - MOCK_METHOD4(SendMessage, int(const std::string &, const Message *, bool, uint32_t)); - MOCK_METHOD5(SendMessage, int(const std::string &, const Message *, bool, uint32_t, const OnSendEnd &)); + MOCK_METHOD3(SendMessage, int(const std::string &, const Message *, SendConfig &)); + MOCK_METHOD4(SendMessage, int(const std::string &, const Message *, SendConfig &, const OnSendEnd &)); MOCK_CONST_METHOD0(GetCommunicatorMtuSize, uint32_t(void)); MOCK_CONST_METHOD1(GetCommunicatorMtuSize, uint32_t(const std::string &)); MOCK_CONST_METHOD0(GetTimeout, uint32_t(void)); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp index afae09798630d3a47cab30e5b19a044a4e78124a..c8c946e7dd51f7f4fb3fa36ce77d00c5fa7baca0 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp @@ -43,14 +43,13 @@ void VirtualCommunicator::Activate() { } -int VirtualCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, - uint32_t timeout) +int VirtualCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) { - return SendMessage(dstTarget, inMsg, nonBlock, timeout, nullptr); + return SendMessage(dstTarget, inMsg, config, nullptr); } int VirtualCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, - bool nonBlock, uint32_t timeout, const OnSendEnd &onEnd) + SendConfig &config, const OnSendEnd &onEnd) { AutoLock lock(this); if (IsKilled()) { diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.h index 89b6cecbbf37499f7c9d1f1056c2cc15728c4002..ec7f766d178623cfc2e9a2dff28417c835ab4f19 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.h @@ -51,8 +51,8 @@ public: uint32_t GetTimeout(const std::string &target) const override; int GetLocalIdentity(std::string &outTarget) const override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) override; + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) override; int GetRemoteCommunicatorVersion(const std::string &deviceId, uint16_t &version) const override; diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp index 3bea5ac2fb44b4b45f486604e48ad426978c104c..561a3f46c30143f53673f083978ac0ebd24091c6 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp @@ -79,7 +79,8 @@ int VirtualCommunicatorAggregator::RegOnConnectCallback(const OnConnectCallback void VirtualCommunicatorAggregator::RunCommunicatorLackCallback(const LabelType &commLabel) { if (onCommLack_) { - onCommLack_(commLabel); + std::string userId; + onCommLack_(commLabel, userId_); } } @@ -90,6 +91,11 @@ void VirtualCommunicatorAggregator::RunOnConnectCallback(const std::string &targ } } +int VirtualCommunicatorAggregator::GetLocalIdentity(std::string &outTarget) const +{ + return E_OK; +} + void VirtualCommunicatorAggregator::OnlineDevice(const std::string &deviceId) const { if (!isEnable_) { @@ -231,5 +237,10 @@ void VirtualCommunicatorAggregator::RegOnDispatch( { onDispatch_ = onDispatch; } + +void VirtualCommunicatorAggregator::SetCurrentUserId(const std::string &userId) +{ + userId_ = userId; +} } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h index 28b92184ded03420a99f98199edd47e6348b3798..22db8b586c7f60bce98f337dda3621bca0501baf 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h @@ -42,6 +42,8 @@ public: void RunCommunicatorLackCallback(const LabelType &commLabel); void RunOnConnectCallback(const std::string &target, bool isConnect); + int GetLocalIdentity(std::string &outTarget) const override; + // online a virtual device to the VirtualCommunicator, should call in main thread void OnlineDevice(const std::string &deviceId) const; @@ -66,6 +68,8 @@ public: void RegOnDispatch(const std::function &onDispatch); + void SetCurrentUserId(const std::string &userId); + ~VirtualCommunicatorAggregator() {}; VirtualCommunicatorAggregator() {}; @@ -82,6 +86,7 @@ private: CommunicatorLackCallback onCommLack_; OnConnectCallback onConnect_; std::function onDispatch_; + std::string userId_; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.cpp index 37fe299b6c138d164abcbe05a93238145a5230d3..fa20e0c2c6581674d2d8195dbc88427a54cd845b 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.cpp @@ -82,14 +82,13 @@ int VirtualTimeSyncCommunicator::GetLocalIdentity(std::string &outTarget) const return 0; } -int VirtualTimeSyncCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, - uint32_t timeout) +int VirtualTimeSyncCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) { - return SendMessage(dstTarget, inMsg, nonBlock, timeout, nullptr); + return SendMessage(dstTarget, inMsg, config, nullptr); } int VirtualTimeSyncCommunicator::SendMessage(const std::string &dstTarget, const Message *inMsg, - bool nonBlock, uint32_t timeout, const OnSendEnd &onEnd) + SendConfig &config, const OnSendEnd &onEnd) { if (!isEnable_) { LOGD("[VirtualTimeSyncCommunicator]the VirtualTimeSyncCommunicator disabled!"); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.h index cc7c46ac3631493656ee4de61aa018378484929f..410f587d4b62ca6359ea02c777c37956e4b3a947 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_time_sync_communicator.h @@ -57,8 +57,8 @@ public: // Get local target name for identify self int GetLocalIdentity(std::string &outTarget) const override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout) override; - int SendMessage(const std::string &dstTarget, const Message *inMsg, bool nonBlock, uint32_t timeout, + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config) override; + int SendMessage(const std::string &dstTarget, const Message *inMsg, SendConfig &config, const OnSendEnd &onEnd) override; int GetRemoteCommunicatorVersion(const std::string &deviceId, uint16_t &version) const override;