Skip to content

Commit 46a0cd4

Browse files
HUAHUAI23HUAHUAI23
and
HUAHUAI23
authored
feat(server): recover the application and synchronize the recovery functions to sys_db (#1879)
* feat(server): recover the application and synchronize the recovery functions to sys_db --------- Co-authored-by: HUAHUAI23 <[email protected]>
1 parent 1c688b8 commit 46a0cd4

File tree

1 file changed

+111
-9
lines changed

1 file changed

+111
-9
lines changed

server/src/database/database.service.ts

+111-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import { GenerateAlphaNumericPassword } from 'src/utils/random'
55
import { MongoService } from './mongo.service'
66
import * as mongodb_uri from 'mongodb-uri'
77
import { RegionService } from 'src/region/region.service'
8-
import { TASK_LOCK_INIT_TIME } from 'src/constants'
8+
import {
9+
CN_PUBLISHED_CONF,
10+
CN_PUBLISHED_FUNCTIONS,
11+
CN_PUBLISHED_WEBSITE_HOSTING,
12+
TASK_LOCK_INIT_TIME,
13+
} from 'src/constants'
914
import { Region } from 'src/region/entities/region'
1015
import { SystemDatabase } from '../system-database'
1116
import {
@@ -18,6 +23,9 @@ import { exec } from 'node:child_process'
1823
import { promisify } from 'node:util'
1924
import { DatabaseSyncRecord } from './entities/database-sync-record'
2025
import { MongoClient, ObjectId } from 'mongodb'
26+
import { DedicatedDatabaseService } from './dedicated-database/dedicated-database.service'
27+
import { CloudFunction } from 'src/function/entities/cloud-function'
28+
import { ApplicationConfiguration } from 'src/application/entities/application-configuration'
2129

2230
const p_exec = promisify(exec)
2331

@@ -29,6 +37,7 @@ export class DatabaseService {
2937
constructor(
3038
private readonly mongoService: MongoService,
3139
private readonly regionService: RegionService,
40+
private readonly dedicatedDatabaseService: DedicatedDatabaseService,
3241
) {}
3342

3443
async create(appid: string) {
@@ -226,11 +235,31 @@ export class DatabaseService {
226235

227236
async exportDatabase(appid: string, filePath: string, uid: ObjectId) {
228237
const region = await this.regionService.findByAppId(appid)
229-
const database = await this.findOne(appid)
230-
assert(database, 'Database not found')
238+
const sharedDatabase = await this.findOne(appid)
239+
const dedicatedDatabase = await this.dedicatedDatabaseService.findOne(appid)
231240

232-
const connectionUri = this.getControlConnectionUri(region, database)
233-
assert(connectionUri, 'Database connection uri not found')
241+
if (sharedDatabase && dedicatedDatabase) {
242+
throw new Error(
243+
`Database ${appid} found in both shared and dedicated databases.`,
244+
)
245+
}
246+
247+
if (!sharedDatabase && !dedicatedDatabase) {
248+
throw new Error(
249+
`Database ${appid} not found in both shared and dedicated databases.`,
250+
)
251+
}
252+
let connectionUri
253+
if (sharedDatabase) {
254+
connectionUri = this.getControlConnectionUri(region, sharedDatabase)
255+
} else {
256+
connectionUri = await this.dedicatedDatabaseService.getConnectionUri(
257+
region,
258+
dedicatedDatabase,
259+
)
260+
}
261+
262+
assert(connectionUri, `Database ${appid} connection uri not found`)
234263

235264
try {
236265
await p_exec(
@@ -252,16 +281,39 @@ export class DatabaseService {
252281
uid: ObjectId,
253282
): Promise<void> {
254283
const region = await this.regionService.findByAppId(appid)
255-
const database = await this.findOne(appid)
256-
assert(database, 'Database not found')
257284

258-
const connectionUri = this.getControlConnectionUri(region, database)
259-
assert(connectionUri, 'Database connection uri not found')
285+
const sharedDatabase = await this.findOne(appid)
286+
const dedicatedDatabase = await this.dedicatedDatabaseService.findOne(appid)
287+
288+
if (sharedDatabase && dedicatedDatabase) {
289+
throw new Error(
290+
`Database ${appid} found in both shared and dedicated databases.`,
291+
)
292+
}
293+
294+
if (!sharedDatabase && !dedicatedDatabase) {
295+
throw new Error(
296+
`Database ${appid} not found in both shared and dedicated databases.`,
297+
)
298+
}
299+
let connectionUri
300+
if (sharedDatabase) {
301+
connectionUri = this.getControlConnectionUri(region, sharedDatabase)
302+
} else {
303+
connectionUri = await this.dedicatedDatabaseService.getConnectionUri(
304+
region,
305+
dedicatedDatabase,
306+
)
307+
}
308+
assert(connectionUri, `Database ${appid} connection uri not found`)
260309

261310
try {
262311
await p_exec(
263312
`mongorestore --uri='${connectionUri}' --gzip --archive='${filePath}' --nsFrom="${dbName}.*" --nsTo="${appid}.*" -v --nsInclude="${dbName}.*"`,
264313
)
314+
315+
await this.recoverFunctionsToSystemDatabase(appid, uid)
316+
265317
await this.db
266318
.collection<DatabaseSyncRecord>('DatabaseSyncRecord')
267319
.insertOne({ uid, createdAt: new Date() })
@@ -271,4 +323,54 @@ export class DatabaseService {
271323
throw error
272324
}
273325
}
326+
327+
async recoverFunctionsToSystemDatabase(appid: string, uid: ObjectId) {
328+
const { db, client } =
329+
(await this.dedicatedDatabaseService.findAndConnect(appid)) ||
330+
(await this.findAndConnect(appid))
331+
332+
try {
333+
const appFunctionCollection = db.collection(CN_PUBLISHED_FUNCTIONS)
334+
const appConfCollection = db.collection(CN_PUBLISHED_CONF)
335+
const appWebsiteCollection = db.collection(CN_PUBLISHED_WEBSITE_HOSTING)
336+
337+
const functionsExist = await this.db
338+
.collection<CloudFunction>('CloudFunction')
339+
.countDocuments({ appid })
340+
341+
if (functionsExist) {
342+
this.logger.debug(`${appid} Functions already exist in system database`)
343+
return
344+
}
345+
346+
const funcs: CloudFunction[] = await appFunctionCollection
347+
.find<CloudFunction>({})
348+
.toArray()
349+
350+
if (funcs.length === 0) {
351+
this.logger.debug(` ${appid} No functions for recover.`)
352+
return
353+
}
354+
355+
funcs.forEach((func) => {
356+
delete func._id
357+
func.appid = appid
358+
func.createdBy = uid
359+
})
360+
361+
await this.db.collection<CloudFunction>('CloudFunction').insertMany(funcs)
362+
363+
// sync conf
364+
const conf = await this.db
365+
.collection<ApplicationConfiguration>('ApplicationConfiguration')
366+
.findOne({ appid })
367+
368+
await appConfCollection.deleteMany({})
369+
await appConfCollection.insertOne(conf)
370+
371+
await appWebsiteCollection.deleteMany({})
372+
} finally {
373+
await client.close()
374+
}
375+
}
274376
}

0 commit comments

Comments
 (0)