Skip to content

Commit

Permalink
feat(app-server): expose gridfs storage api to cloud-sdk;
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Aug 18, 2021
1 parent d393f6c commit ece5dd4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 49 deletions.
27 changes: 21 additions & 6 deletions packages/app-server/src/cloud-sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { FunctionContext, FunctionResult, CloudFunction } from "cloud-function-e
import { FileStorageInterface } from "../lib/storage/interface"
import * as mongodb from "mongodb"
import { DatabaseAgent } from "../lib/database"
import { LocalFileStorage } from "../lib/storage/local_file_storage"
import { LocalFSStorage } from "../lib/storage/localfs-storage"
import Config from "../config"
import request from 'axios'
import { SchedulerInstance } from "../lib/scheduler"
import { getToken, parseToken } from "../lib/utils/token"
import { invokeInFunction } from "./invoke"
import { GridFSStorage } from "../lib/storage/gridfs-storage"


export type InvokeFunctionType = (name: string, param: FunctionContext) => Promise<FunctionResult>
Expand All @@ -30,9 +31,9 @@ export interface CloudSdkInterface {

/**
* 获取一个文件存储管理器
* @param bucket 文件的名字空间,如 'public'
* @param bucket 文件 Bucket 名字,默认为 'public'
*/
storage(bucket: string): FileStorageInterface
storage(bucket?: string): FileStorageInterface

/**
* 获取 less api database ORM 实例
Expand Down Expand Up @@ -98,7 +99,7 @@ export interface CloudSdkInterface {
*/
const cloud: CloudSdkInterface = {
database: () => DatabaseAgent.createDb(),
storage: (namespace: string) => new LocalFileStorage(Config.LOCAL_STORAGE_ROOT_PATH, namespace),
storage: createStorage,
fetch: request,
invoke: invokeInFunction,
emit: (event: string, param: any) => SchedulerInstance.emit(event, param),
Expand Down Expand Up @@ -126,7 +127,7 @@ DatabaseAgent.accessor.ready.then(() => {
export function create() {
const cloud: CloudSdkInterface = {
database: () => DatabaseAgent.createDb(),
storage: (namespace: string) => new LocalFileStorage(Config.LOCAL_STORAGE_ROOT_PATH, namespace),
storage: (namespace: string) => new LocalFSStorage(Config.LOCAL_STORAGE_ROOT_PATH, namespace),
fetch: request,
invoke: invokeInFunction,
emit: (event: string, param: any) => SchedulerInstance.emit(event, param),
Expand All @@ -141,4 +142,18 @@ export function create() {
return cloud
}

export default cloud
export default cloud


/**
* Create fs storage by configured fs driver
* @param bucket bucket name
* @returns
*/
function createStorage(bucket = 'public'): FileStorageInterface {
if (Config.FILE_SYSTEM_DRIVER === 'localfs') {
return new LocalFSStorage(Config.LOCAL_STORAGE_ROOT_PATH, bucket)
}

return new GridFSStorage(bucket, DatabaseAgent.accessor.db)
}
40 changes: 14 additions & 26 deletions packages/app-server/src/router/file/gridfs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

import * as fs from 'fs'

import * as express from 'express'
import { GridFSBucket } from 'mongodb'
import { DatabaseAgent } from '../../lib/database'
import { checkFileOperationToken, FS_OPERATION, generateETag } from './utils'
import Config from '../../config'
import { logger } from '../../lib/logger'
import { GridFSStorage } from '../../lib/storage/gridfs-storage'


export const GridFSHandlers = {
Expand Down Expand Up @@ -35,37 +36,24 @@ async function handleUploadFile(req: express.Request, res: express.Response) {
return res.status(422).send('file cannot be empty')
}

// create a local file system driver
const bucket = new GridFSBucket(DatabaseAgent.accessor.db, { bucketName: bucket_name })

const stream = bucket.openUploadStream(file.filename, {
metadata: {
original_name: file.originalname,
created_by: auth?.uid,
bucket: bucket_name,
created_at: Date.now(),
contentType: file.mimetype
},
// @deprecated: this field will be deprecated in future, use metadata instead. keep it now for history reasons
// save file to gridfs
const storage = new GridFSStorage(bucket_name, DatabaseAgent.accessor.db)
const metadata = {
original_name: file.originalname,
created_by: auth?.uid,
bucket: bucket_name,
created_at: Date.now(),
contentType: file.mimetype
})

}

// save to gridfs
fs.createReadStream(file.path)
.pipe(stream as any)
.on('finish', () => {
storage.save(file.path, file.filename, metadata)
.then(saved => {
res.send({
code: 0,
data: {
id: stream.id,
filename: stream.filename,
bucket: bucket_name,
contentType: file.mimetype
}
data: saved
})
})
.on('error', (err: Error) => {
.catch(err => {
logger.error('upload file to gridfs stream occurred error', err)
res.status(500).send('internal server error')
})
Expand Down
26 changes: 9 additions & 17 deletions packages/app-server/src/router/file/localfs.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-08-11 18:01:25
* @LastEditTime: 2021-08-17 17:52:20
* @LastEditTime: 2021-08-19 00:19:42
* @Description:
*/
import { logger } from '../../lib/logger'
import * as express from 'express'
import * as path from 'path'
import Config from '../../config'
import { LocalFileStorage } from '../../lib/storage/local_file_storage'
import { LocalFSStorage } from '../../lib/storage/localfs-storage'
import { checkFileOperationToken, FS_OPERATION } from './utils'


Expand All @@ -24,7 +24,7 @@ export const LocalFileSystemHandlers = {
async function handleUploadFile(req: express.Request, res: express.Response) {

const bucket = req.params.bucket
if (!checkBucketName(bucket)) {
if (!LocalFSStorage.checkDirectoryName(bucket)) {
return res.status(422).send('invalid bucket name')
}

Expand All @@ -43,9 +43,9 @@ async function handleUploadFile(req: express.Request, res: express.Response) {
}

// create a local file system driver
const localStorage = new LocalFileStorage(Config.LOCAL_STORAGE_ROOT_PATH, bucket)
const localStorage = new LocalFSStorage(Config.LOCAL_STORAGE_ROOT_PATH, bucket)
const filepath = path.join(file.destination, `${file.filename}`)
const info = await localStorage.saveFile(filepath)
const info = await localStorage.save(filepath, file.filename)

// do not expose server path to client
delete info.fullpath
Expand All @@ -64,11 +64,11 @@ async function handleUploadFile(req: express.Request, res: express.Response) {
async function handleDownloadFile(req: express.Request, res: express.Response) {

const { bucket, filename } = req.params
if (!checkBucketName(bucket)) {
if (!LocalFSStorage.checkDirectoryName(bucket)) {
return res.status(422).send('invalid bucket')
}

if (!checkFilename(filename)) {
if (!LocalFSStorage.checkFilename(filename)) {
return res.status(422).send('invalid filename')
}

Expand All @@ -80,21 +80,13 @@ async function handleDownloadFile(req: express.Request, res: express.Response) {
}
}

const localStorage = new LocalFileStorage(Config.LOCAL_STORAGE_ROOT_PATH, bucket)
const localStorage = new LocalFSStorage(Config.LOCAL_STORAGE_ROOT_PATH, bucket)

try {
const info = await localStorage.getFileInfo(filename)
const info = await localStorage.info(filename)
return res.download(info.fullpath)
} catch (error) {
logger.error('get file info failed', error)
return res.status(404).send('Not Found')
}
}

function checkBucketName(namespace: string) {
return (new LocalFileStorage('')).checkSafeDirectoryName(namespace)
}

function checkFilename(name: string) {
return (new LocalFileStorage('')).checkSafeFilename(name)
}

0 comments on commit ece5dd4

Please sign in to comment.