1
1
# -*- coding: utf-8 -*-
2
2
import logging
3
- from datetime import datetime
4
3
5
4
from flask import g
6
5
7
- from src .modules .auth .auth import Auth
8
- from src .modules .auth .user import UserManager
9
- from src .modules .database .mongodb_client import MongodbClient
10
- from src .modules .backup .backup_client import BackupClient
11
- from src .modules .backup .backup_executor import ExecutorBase , BackupServerExecutor
12
- from src .modules .subscription .subscription import VaultSubscription
13
- from src .modules .subscription .vault import VaultManager
14
6
from src .utils .consts import BKSERVER_REQ_STATE , BACKUP_REQUEST_STATE_PROCESS , BKSERVER_REQ_ACTION , \
15
7
BACKUP_REQUEST_ACTION_BACKUP , BKSERVER_REQ_CID , BKSERVER_REQ_SHA256 , BKSERVER_REQ_SIZE , \
16
8
BKSERVER_REQ_STATE_MSG , BACKUP_REQUEST_STATE_FAILED , COL_IPFS_BACKUP_SERVER , USR_DID , BACKUP_REQUEST_STATE_SUCCESS
17
- from src .utils .db_client import cli
18
- from src .utils .file_manager import fm
19
9
from src .utils .http_exception import BackupNotFoundException , AlreadyExistsException , BadRequestException , \
20
10
InsufficientStorageException , NotImplementedException , VaultNotFoundException
21
- from src .utils_v1 .constants import DID_INFO_DB_NAME , \
22
- VAULT_BACKUP_SERVICE_MAX_STORAGE , VAULT_BACKUP_SERVICE_START_TIME , VAULT_BACKUP_SERVICE_END_TIME , \
11
+ from src .utils_v1 .constants import VAULT_BACKUP_SERVICE_MAX_STORAGE , VAULT_BACKUP_SERVICE_START_TIME , VAULT_BACKUP_SERVICE_END_TIME , \
23
12
VAULT_BACKUP_SERVICE_USING , VAULT_BACKUP_SERVICE_USE_STORAGE , VAULT_SERVICE_MAX_STORAGE
24
13
from src .utils_v1 .payment .payment_config import PaymentConfig
14
+ from src .modules .auth .auth import Auth
15
+ from src .modules .auth .user import UserManager
16
+ from src .modules .backup .backup import BackupManager
17
+ from src .modules .database .mongodb_client import MongodbClient
18
+ from src .modules .backup .backup_client import BackupClient
19
+ from src .modules .backup .backup_executor import ExecutorBase , BackupServerExecutor
20
+ from src .modules .files .ipfs_client import IpfsClient
21
+ from src .modules .subscription .subscription import VaultSubscription
22
+ from src .modules .subscription .vault import VaultManager
25
23
26
24
27
25
class BackupServer :
@@ -32,6 +30,8 @@ def __init__(self):
32
30
self .mcli = MongodbClient ()
33
31
self .user_manager = UserManager ()
34
32
self .vault_manager = VaultManager ()
33
+ self .backup_manager = BackupManager ()
34
+ self .ipfs_client = IpfsClient ()
35
35
36
36
def promotion (self ):
37
37
""" This processing is just like restore the vault:
@@ -42,7 +42,7 @@ def promotion(self):
42
42
4. increase the reference count of the file cid.
43
43
5. restore all user databases.
44
44
"""
45
- doc = self .find_backup_request (g .usr_did , throw_exception = True )
45
+ backup = self .backup_manager . get_backup (g .usr_did )
46
46
47
47
try :
48
48
self .vault_manager .get_vault (g .usr_did )
@@ -51,7 +51,7 @@ def promotion(self):
51
51
pass
52
52
53
53
vault = self .vault_manager .create_vault (g .usr_did , PaymentConfig .get_vault_plan ('Free' ), is_upgraded = True )
54
- request_metadata = self .get_server_request_metadata (g .usr_did , doc , is_promotion = True ,
54
+ request_metadata = self .get_server_request_metadata (g .usr_did , backup , is_promotion = True ,
55
55
vault_max_size = vault [VAULT_SERVICE_MAX_STORAGE ])
56
56
57
57
# INFO: if free vault can not hold the backup data, then let it go
@@ -64,10 +64,10 @@ def promotion(self):
64
64
ExecutorBase .update_vault_usage_by_metadata (g .usr_did , request_metadata )
65
65
66
66
def internal_backup (self , cid , sha256 , size , is_force ):
67
- doc = self .find_backup_request (g .usr_did , throw_exception = True )
68
- if not is_force and doc .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
67
+ backup = self .backup_manager . get_backup (g .usr_did )
68
+ if not is_force and backup .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
69
69
raise BadRequestException ('Failed because backup is in processing.' )
70
- fm . ipfs_pin_cid (cid )
70
+ self . ipfs_client . cid_pin (cid )
71
71
update = {
72
72
BKSERVER_REQ_ACTION : BACKUP_REQUEST_ACTION_BACKUP ,
73
73
BKSERVER_REQ_STATE : BACKUP_REQUEST_STATE_PROCESS ,
@@ -76,125 +76,116 @@ def internal_backup(self, cid, sha256, size, is_force):
76
76
BKSERVER_REQ_SHA256 : sha256 ,
77
77
BKSERVER_REQ_SIZE : size
78
78
}
79
- self .update_backup_request (g .usr_did , update )
80
- BackupServerExecutor (g .usr_did , self , self .find_backup_request (g .usr_did , False )).start ()
79
+ self .backup_manager . update_backup (g .usr_did , update )
80
+ BackupServerExecutor (g .usr_did , self , self .backup_manager . get_backup (g .usr_did )).start ()
81
81
82
82
def internal_backup_state (self ):
83
- doc = self .find_backup_request (g .usr_did , throw_exception = True )
83
+ backup = self .backup_manager . get_backup (g .usr_did )
84
84
return {
85
- 'state' : doc .get (BKSERVER_REQ_ACTION ), # None or backup
86
- 'result' : doc .get (BKSERVER_REQ_STATE ),
87
- 'message' : doc .get (BKSERVER_REQ_STATE_MSG )
85
+ 'state' : backup .get (BKSERVER_REQ_ACTION ), # None or backup
86
+ 'result' : backup .get (BKSERVER_REQ_STATE ),
87
+ 'message' : backup .get (BKSERVER_REQ_STATE_MSG )
88
88
}
89
89
90
90
def internal_restore (self ):
91
- doc = self .find_backup_request (g .usr_did , throw_exception = True )
91
+ backup = self .backup_manager . get_backup (g .usr_did )
92
92
93
93
# BKSERVER_REQ_ACTION: None, means not backup called; 'backup', backup called, and can be three states.
94
- if not doc .get (BKSERVER_REQ_ACTION ):
94
+ if not backup .get (BKSERVER_REQ_ACTION ):
95
95
raise BadRequestException ('No backup data for restoring on backup node.' )
96
- elif doc .get (BKSERVER_REQ_ACTION ) != BACKUP_REQUEST_ACTION_BACKUP :
97
- raise BadRequestException (f'No backup data for restoring with invalid action "{ doc .get (BKSERVER_REQ_ACTION )} " on backup node.' )
96
+ elif backup .get (BKSERVER_REQ_ACTION ) != BACKUP_REQUEST_ACTION_BACKUP :
97
+ raise BadRequestException (f'No backup data for restoring with invalid action "{ backup .get (BKSERVER_REQ_ACTION )} " on backup node.' )
98
98
99
99
# if BKSERVER_REQ_ACTION is not None, it can be three states
100
- if doc .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
100
+ if backup .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
101
101
raise BadRequestException ('Failed because backup is in processing..' )
102
- elif doc .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_FAILED :
102
+ elif backup .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_FAILED :
103
103
raise BadRequestException ('Cannot execute restore because last backup is failed.' )
104
- elif doc .get (BKSERVER_REQ_STATE ) != BACKUP_REQUEST_STATE_SUCCESS :
105
- raise BadRequestException (f'Cannot execute restore because unknown state "{ doc .get (BKSERVER_REQ_STATE )} ".' )
104
+ elif backup .get (BKSERVER_REQ_STATE ) != BACKUP_REQUEST_STATE_SUCCESS :
105
+ raise BadRequestException (f'Cannot execute restore because unknown state "{ backup .get (BKSERVER_REQ_STATE )} ".' )
106
106
107
- if not doc .get (BKSERVER_REQ_CID ):
108
- raise BadRequestException (f'Cannot execute restore because invalid data cid "{ doc .get (BKSERVER_REQ_CID )} ".' )
107
+ if not backup .get (BKSERVER_REQ_CID ):
108
+ raise BadRequestException (f'Cannot execute restore because invalid data cid "{ backup .get (BKSERVER_REQ_CID )} ".' )
109
109
110
110
# backup data is valid, go on
111
111
return {
112
- 'cid' : doc .get (BKSERVER_REQ_CID ),
113
- 'sha256' : doc .get (BKSERVER_REQ_SHA256 ),
114
- 'size' : doc .get (BKSERVER_REQ_SIZE ),
112
+ 'cid' : backup .get (BKSERVER_REQ_CID ),
113
+ 'sha256' : backup .get (BKSERVER_REQ_SHA256 ),
114
+ 'size' : backup .get (BKSERVER_REQ_SIZE ),
115
115
}
116
116
117
117
# the flowing is for the executors.
118
118
119
119
def update_request_state (self , user_did , state , msg = None ):
120
- self .update_backup_request (user_did , {BKSERVER_REQ_STATE : state , BKSERVER_REQ_STATE_MSG : msg })
120
+ self .backup_manager . update_backup (user_did , {BKSERVER_REQ_STATE : state , BKSERVER_REQ_STATE_MSG : msg })
121
121
122
122
def get_server_request_metadata (self , user_did , req , is_promotion = False , vault_max_size = 0 ):
123
123
""" Get the request metadata for promotion or backup.
124
+
125
+ :param user_did
126
+ :param req
127
+ :param is_promotion
124
128
:param vault_max_size Only for promotion.
125
129
"""
126
- request_metadata = self ._get_verified_request_metadata (user_did , req )
130
+ request_metadata = self .__get_verified_request_metadata (user_did , req )
127
131
logging .info ('[IpfsBackupServer] Success to get verified request metadata.' )
128
- self ._check_verified_request_metadata (request_metadata , req ,
129
- is_promotion = is_promotion ,
130
- vault_max_size = vault_max_size )
131
- logging .info ('[IpfsBackupServer] Success to check the verified request metadata.' )
132
- return request_metadata
133
-
134
- def _get_verified_request_metadata (self , user_did , req ):
135
- cid , sha256 , size = req .get (BKSERVER_REQ_CID ), req .get (BKSERVER_REQ_SHA256 ), req .get (BKSERVER_REQ_SIZE )
136
- return fm .ipfs_download_file_content (cid , is_proxy = True , sha256 = sha256 , size = size )
137
132
138
- def _check_verified_request_metadata (self , request_metadata , req , is_promotion = False , vault_max_size = 0 ):
139
133
if is_promotion :
140
134
if request_metadata ['vault_size' ] > vault_max_size :
141
135
raise InsufficientStorageException ('No enough space for promotion.' )
142
136
else :
143
137
# for backup
144
138
if request_metadata ['backup_size' ] > req [VAULT_BACKUP_SERVICE_MAX_STORAGE ]:
145
139
raise InsufficientStorageException ('No enough space for backup on the backup node.' )
140
+ logging .info ('[IpfsBackupServer] Success to check the verified request metadata.' )
141
+
142
+ return request_metadata
143
+
144
+ def __get_verified_request_metadata (self , user_did , req ):
145
+ cid , sha256 , size = req .get (BKSERVER_REQ_CID ), req .get (BKSERVER_REQ_SHA256 ), req .get (BKSERVER_REQ_SIZE )
146
+ return self .ipfs_client .download_file_json_content (cid , is_proxy = True , sha256 = sha256 , size = size )
146
147
147
148
# ipfs-subscription
148
149
149
150
def subscribe (self ):
150
- doc = self .find_backup_request (g .usr_did , throw_exception = False )
151
- if doc :
152
- raise AlreadyExistsException ('The backup service is already subscribed.' )
153
- return self ._get_backup_info (self ._create_backup (g .usr_did , PaymentConfig .get_free_backup_plan ()))
151
+ try :
152
+ backup = self .backup_manager .get_backup (g .usr_did )
153
+ if backup :
154
+ raise AlreadyExistsException ('The backup service is already subscribed.' )
155
+ except BackupNotFoundException as e :
156
+ pass
157
+
158
+ new_backup = self .backup_manager .create_backup (g .usr_did , PaymentConfig .get_free_backup_plan ())
159
+ return self .__get_backup_info (new_backup )
154
160
155
161
def unsubscribe (self ):
156
- doc = self .find_backup_request (g .usr_did , throw_exception = True )
157
- if doc .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
158
- raise BadRequestException (f"The '{ doc .get (BKSERVER_REQ_ACTION )} ' is in process." )
162
+ backup = self .backup_manager . get_backup (g .usr_did )
163
+ if backup .get (BKSERVER_REQ_STATE ) == BACKUP_REQUEST_STATE_PROCESS :
164
+ raise BadRequestException (f"The '{ backup .get (BKSERVER_REQ_ACTION )} ' is in process." )
159
165
160
166
# INFO: maybe use has a vault.
161
167
# self.user_manager.remove_user(g.usr_did)
162
- self .remove_backup_by_did (g .usr_did , doc )
168
+ self .remove_backup_by_did (g .usr_did , backup )
163
169
164
170
def remove_backup_by_did (self , user_did , doc ):
165
171
""" Remove all data belongs to the backup of the user. """
166
172
logging .debug (f'start remove the backup of the user { user_did } , _id, { str (doc ["_id" ])} ' )
167
173
if doc .get (BKSERVER_REQ_CID ):
168
- request_metadata = self ._get_verified_request_metadata (user_did , doc )
174
+ request_metadata = self .__get_verified_request_metadata (user_did , doc )
169
175
ExecutorBase .handle_cids_in_local_ipfs (request_metadata , root_cid = doc .get (BKSERVER_REQ_CID ), is_unpin = True )
170
176
171
- cli .delete_one_origin (DID_INFO_DB_NAME ,
172
- COL_IPFS_BACKUP_SERVER ,
173
- {USR_DID : user_did },
174
- is_check_exist = False )
177
+ self .backup_manager .remove_backup (user_did )
175
178
176
179
def get_info (self ):
177
- return self ._get_backup_info (self .find_backup_request (g .usr_did , throw_exception = True ))
180
+ return self .__get_backup_info (self .backup_manager . get_backup (g .usr_did ))
178
181
179
182
def activate (self ):
180
183
raise NotImplementedException ()
181
184
182
185
def deactivate (self ):
183
186
raise NotImplementedException ()
184
187
185
- def _create_backup (self , user_did , price_plan ):
186
- now = int (datetime .now ().timestamp ())
187
- end_time = - 1 if price_plan ['serviceDays' ] == - 1 else now + price_plan ['serviceDays' ] * 24 * 60 * 60
188
- doc = {USR_DID : user_did ,
189
- VAULT_BACKUP_SERVICE_USING : price_plan ['name' ],
190
- VAULT_BACKUP_SERVICE_MAX_STORAGE : price_plan ["maxStorage" ] * 1024 * 1024 ,
191
- VAULT_BACKUP_SERVICE_USE_STORAGE : 0 ,
192
- VAULT_BACKUP_SERVICE_START_TIME : now ,
193
- VAULT_BACKUP_SERVICE_END_TIME : int (end_time )}
194
- cli .insert_one_origin (DID_INFO_DB_NAME , COL_IPFS_BACKUP_SERVER , doc , create_on_absence = True , is_extra = True )
195
- return doc
196
-
197
- def _get_backup_info (self , doc ):
188
+ def __get_backup_info (self , doc ):
198
189
return {
199
190
'service_did' : self .auth .get_did_string (),
200
191
'pricing_plan' : doc [VAULT_BACKUP_SERVICE_USING ],
@@ -207,22 +198,7 @@ def _get_backup_info(self, doc):
207
198
}
208
199
209
200
def update_storage_usage (self , user_did , size ):
210
- self .update_backup_request (user_did , {VAULT_BACKUP_SERVICE_USE_STORAGE : size })
211
-
212
- def update_backup_request (self , user_did , update ):
213
- col_filter = {USR_DID : user_did }
214
- cli .update_one_origin (DID_INFO_DB_NAME , COL_IPFS_BACKUP_SERVER , col_filter , {'$set' : update }, is_extra = True )
215
-
216
- def find_backup_request (self , user_did , throw_exception = True ):
217
- """ get the backup request information belonged to the user DID
218
- :param user_did: user DID
219
- :param throw_exception: throw BackupNotFoundException when True
220
- """
221
- doc = cli .find_one_origin (DID_INFO_DB_NAME , COL_IPFS_BACKUP_SERVER , {USR_DID : user_did },
222
- create_on_absence = True , throw_exception = False )
223
- if throw_exception and not doc :
224
- raise BackupNotFoundException ()
225
- return doc
201
+ self .backup_manager .update_backup (user_did , {VAULT_BACKUP_SERVICE_USE_STORAGE : size })
226
202
227
203
def retry_backup_request (self ):
228
204
""" retry unfinished backup&restore action when node rebooted """
0 commit comments