1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef AUTO_LAUNCH_H
17 #define AUTO_LAUNCH_H
18 
19 #include <set>
20 #include <map>
21 #include <mutex>
22 #include "auto_launch_export.h"
23 #include "db_properties.h"
24 #include "ikvdb_connection.h"
25 #include "icommunicator_aggregator.h"
26 #include "kv_store_observer.h"
27 #include "kvdb_properties.h"
28 #include "types_export.h"
29 #include "relational_store_connection.h"
30 #include "relationaldb_properties.h"
31 #include "semaphore_utils.h"
32 #include "store_observer.h"
33 
34 namespace DistributedDB {
35 enum class AutoLaunchItemState {
36     UN_INITIAL = 0,
37     IN_ENABLE,
38     IN_LIFE_CYCLE_CALL_BACK, // in LifeCycleCallback
39     IN_COMMUNICATOR_CALL_BACK, // in OnConnectCallback or CommunicatorLackCallback
40     IDLE,
41 };
42 
43 enum class DBTypeInner {
44     DB_KV = 1,
45     DB_RELATION,
46     DB_INVALID,
47 };
48 
49 struct AutoLaunchItem {
50     std::shared_ptr<DBProperties> propertiesPtr;
51     AutoLaunchNotifier notifier;
52     KvStoreObserver *observer = nullptr;
53     int conflictType = 0;
54     KvStoreNbConflictNotifier conflictNotifier;
55     void *conn = nullptr;
56     KvDBObserverHandle *observerHandle = nullptr;
57     bool isWriteOpenNotified = false;
58     AutoLaunchItemState state = AutoLaunchItemState::UN_INITIAL;
59     bool isDisable = false;
60     bool inObserver = false;
61     bool isAutoSync = true;
62     DBTypeInner type = DBTypeInner::DB_INVALID;
63     StoreObserver *storeObserver = nullptr;
64 };
65 
66 class AutoLaunch {
67 public:
68     static int GetAutoLaunchProperties(const AutoLaunchParam &param, const DBTypeInner &openType, bool checkDir,
69         std::shared_ptr<DBProperties> &propertiesPtr);
70 
71     AutoLaunch() = default;
72 
73     virtual ~AutoLaunch();
74 
75     DISABLE_COPY_ASSIGN_MOVE(AutoLaunch);
76 
77     void SetCommunicatorAggregator(ICommunicatorAggregator *aggregator);
78 
79     int EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
80         const AutoLaunchOption &option);
81 
82     int DisableKvStoreAutoLaunch(const std::string &normalIdentifier, const std::string &dualTupleIdentifier,
83         const std::string &userId);
84 
85     void GetAutoLaunchSyncDevices(const std::string &identifier, std::vector<std::string> &devices) const;
86 
87     void SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBTypeInner type);
88 
89     void Dump(int fd);
90 
91     void CloseConnection(DBTypeInner type, const DBProperties &properties);
92 
93 protected:
94     static int OpenOneConnection(AutoLaunchItem &autoLaunchItem);
95 
96     // we will return errCode, if errCode != E_OK
97     static int CloseConnectionStrict(AutoLaunchItem &autoLaunchItem);
98 
99     static void CloseNotifier(const AutoLaunchItem &autoLaunchItem);
100 
101     static int SetConflictNotifier(AutoLaunchItem &autoLaunchItem);
102 
103     static int GetAutoLaunchKVProperties(const AutoLaunchParam &param,
104         const std::shared_ptr<KvDBProperties> &propertiesPtr, bool checkDir);
105 
106     static int GetAutoLaunchRelationProperties(const AutoLaunchParam &param,
107         const std::shared_ptr<RelationalDBProperties> &propertiesPtr);
108 
109     static int OpenKvConnection(AutoLaunchItem &autoLaunchItem);
110 
111     static int OpenRelationalConnection(AutoLaunchItem &autoLaunchItem);
112 
113     static int PragmaAutoSync(AutoLaunchItem &autoLaunchItem);
114 
115     int EnableKvStoreAutoLaunchParmCheck(AutoLaunchItem &autoLaunchItem, const std::string &normalIdentifier,
116         const std::string &dualTupleIdentifier, bool isDualTupleMode);
117 
118     int GetKVConnectionInEnable(AutoLaunchItem &autoLaunchItem, const std::string &identifier);
119 
120     // before ReleaseDatabaseConnection, if errCode != E_OK, we not return, we try close more
121     virtual void TryCloseConnection(AutoLaunchItem &autoLaunchItem);
122 
123     int RegisterObserverAndLifeCycleCallback(AutoLaunchItem &autoLaunchItem, const std::string &identifier,
124         bool isExt);
125 
126     int RegisterObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt);
127 
128     void ObserverFunc(const KvDBCommitNotifyData &notifyData, const std::string &identifier,
129         const std::string &userId);
130 
131     void ConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId);
132 
133     void OnlineCallBackTask();
134 
135     void GetDoOpenMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap);
136 
137     void GetConnInDoOpenMapInner(std::pair<const std::string, std::map<std::string, AutoLaunchItem>> &items,
138         SemaphoreUtils &sema);
139 
140     void GetConnInDoOpenMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap);
141 
142     void UpdateGlobalMap(std::map<std::string, std::map<std::string, AutoLaunchItem>> &doOpenMap);
143 
144     void ReceiveUnknownIdentifierCallBackTask(const std::string &identifier, const std::string &userId);
145 
146     void ConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId);
147 
148     void OnlineCallBack(const std::string &device, bool isConnect);
149 
150     int ReceiveUnknownIdentifierCallBack(const LabelType &label, const std::string &originalUserId);
151 
152     int AutoLaunchExt(const std::string &identifier, const std::string &userId);
153 
154     void AutoLaunchExtTask(const std::string &identifier, const std::string &userId, AutoLaunchItem &autoLaunchItem);
155 
156     void ExtObserverFunc(const KvDBCommitNotifyData &notifyData, const std::string &identifier,
157         const std::string &userId);
158 
159     void ExtConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId);
160 
161     void ExtConnectionLifeCycleCallbackTask(const std::string &identifier, const std::string &userId);
162 
163     int ExtAutoLaunchRequestCallBack(const std::string &identifier, AutoLaunchParam &param, DBTypeInner &openType);
164 
165     int RegisterLifeCycleCallback(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt);
166 
167     void TryCloseKvConnection(AutoLaunchItem &autoLaunchItem);
168 
169     void TryCloseRelationConnection(AutoLaunchItem &autoLaunchItem);
170 
171     void EraseAutoLaunchItem(const std::string &identifier, const std::string &userId);
172 
173     void NotifyInvalidParam(const AutoLaunchItem &autoLaunchItem);
174 
175     int CheckAutoLaunchRealPath(const AutoLaunchItem &autoLaunchItem);
176 
177     int RegisterKvObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt);
178 
179     int RegisterRelationalObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt);
180 
181     std::string GetAutoLaunchItemUid(const std::string &identifier, const std::string &originalUserId,
182         bool &handleByCallback);
183 
184     bool ChkAutoLaunchAbort(const std::string &identifier, AutoLaunchItem &autoLaunchItem);
185 
186     void NotifyAutoLaunch(const std::string &userId, AutoLaunchItem &autoLaunchItem, AutoLaunchNotifier &notifier);
187 
188     void AutoLaunchOnChange(const std::string &changedDevice, std::string &userId, std::string &appId,
189         std::string &storeId, AutoLaunchItem autoLaunchItem);
190 
191     mutable std::mutex dataLock_;
192     mutable std::mutex communicatorLock_;
193     std::set<std::string> onlineDevices_;
194     // key: label, value: <userId, AutoLaunchItem>
195     std::map<std::string, std::map<std::string, AutoLaunchItem>> autoLaunchItemMap_;
196     ICommunicatorAggregator *communicatorAggregator_ = nullptr;
197     std::condition_variable cv_;
198 
199     std::mutex extLock_;
200     std::map<DBTypeInner, AutoLaunchRequestCallback> autoLaunchRequestCallbackMap_;
201     // key: label, value: <userId, AutoLaunchItem>
202     std::map<std::string, std::map<std::string, AutoLaunchItem>> extItemMap_;
203 };
204 } // namespace DistributedDB
205 #endif // AUTO_LAUNCH_H
206