Skip to content

Commit

Permalink
fix(storage,grpc-sdk): fix storage rpc functions (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisPdgn authored Apr 7, 2023
1 parent 8b6d2fa commit c799c5d
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 31 deletions.
52 changes: 49 additions & 3 deletions libraries/grpc-sdk/src/modules/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ConduitModule } from '../../classes/ConduitModule';
import {
DeleteFileResponse,
FileResponse,
GetFileDataResponse,
StorageDefinition,
Expand All @@ -21,11 +22,56 @@ export class Storage extends ConduitModule<typeof StorageDefinition> {

createFile(
name: string,
mimeType: string,
data: string,
folder: string,
folder?: string,
container?: string,
mimeType?: string,
isPublic: boolean = false,
): Promise<FileResponse> {
return this.client!.createFile({ name, mimeType, data, folder, isPublic });
return this.client!.createFile({ name, mimeType, data, folder, isPublic, container });
}

updateFile(
id: string,
data: string,
name?: string,
folder?: string,
container?: string,
mimeType?: string,
): Promise<FileResponse> {
return this.client!.updateFile({ name, mimeType, data, folder, id, container });
}

deleteFile(id: string): Promise<DeleteFileResponse> {
return this.client!.deleteFile({ id });
}

createFileByUrl(
name: string,
folder?: string,
container?: string,
mimeType?: string,
size?: number,
isPublic: boolean = false,
) {
return this.client!.createFileByUrl({
name,
mimeType,
folder,
container,
size,
isPublic,
});
}

updateFileByUrl(
id: string,
name?: string,
folder?: string,
container?: string,
mimeType?: string,
size?: number,
) {
return this.client!.updateFileByUrl({ id, name, folder, container, mimeType, size });
}
}
100 changes: 89 additions & 11 deletions modules/storage/src/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import ConduitGrpcSdk, {
ConfigController,
DatabaseProvider,
GrpcCallback,
GrpcRequest,
GrpcResponse,
HealthCheckStatus,
ManagedModule,
ParsedRouterRequest,
} from '@conduitplatform/grpc-sdk';
import AppConfigSchema, { Config } from './config';
import { AdminRoutes } from './admin';
Expand All @@ -15,11 +16,22 @@ import path from 'path';
import { status } from '@grpc/grpc-js';
import { isEmpty, isNil } from 'lodash';
import { runMigrations } from './migrations';
import { FileResponse, GetFileDataResponse } from './protoTypes/storage';
import {
CreateFileByUrlRequest,
CreateFileRequest,
DeleteFileResponse,
FileByUrlResponse,
FileResponse,
GetFileDataResponse,
GetFileRequest,
UpdateFileByUrlRequest,
UpdateFileRequest,
} from './protoTypes/storage';
import MetricsSchema from './metrics';
import { IStorageProvider } from './interfaces';
import { createStorageProvider } from './providers';
import { getAwsAccountId } from './utils';
import { StorageParamAdapter } from './adapter/StorageParamAdapter';

export default class Storage extends ManagedModule<Config> {
configSchema = AppConfigSchema;
Expand All @@ -30,9 +42,12 @@ export default class Storage extends ManagedModule<Config> {
functions: {
setConfig: this.setConfig.bind(this),
getFile: this.getFile.bind(this),
getFileData: this.getFileData.bind(this),
createFile: this.createFile.bind(this),
updateFile: this.updateFile.bind(this),
getFileData: this.getFileData.bind(this),
deleteFile: this.deleteFile.bind(this),
createFileByUrl: this.createFileByUrl.bind(this),
updateFileByUrl: this.updateFileByUrl.bind(this),
},
};
private adminRouter: AdminRoutes;
Expand All @@ -41,6 +56,7 @@ export default class Storage extends ManagedModule<Config> {
private storageProvider: IStorageProvider;
private _fileHandlers: FileHandlers;
private enableAuthRoutes: boolean = false;
private storageParamAdapter: StorageParamAdapter;

constructor() {
super('storage');
Expand All @@ -54,6 +70,7 @@ export default class Storage extends ManagedModule<Config> {
await runMigrations(this.grpcSdk);
this.storageProvider = createStorageProvider('local', {} as Config);
this._fileHandlers = new FileHandlers(this.grpcSdk, this.storageProvider);
this.storageParamAdapter = new StorageParamAdapter();
}

async preConfig(config: Config) {
Expand Down Expand Up @@ -149,42 +166,103 @@ export default class Storage extends ManagedModule<Config> {
}

// gRPC Service
async getFile(call: ParsedRouterRequest, callback: GrpcCallback<FileResponse>) {
async getFile(call: GrpcRequest<GetFileRequest>, callback: GrpcCallback<FileResponse>) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
await this._fileHandlers.getFile(call);
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.getFile(request);
const response = this.storageParamAdapter.getFileResponse(result);
callback(null, response);
}

async getFileData(
call: ParsedRouterRequest,
call: GrpcRequest<GetFileRequest>,
callback: GrpcCallback<GetFileDataResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
await this._fileHandlers.getFileData(call);
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.getFileData(request);
callback(null, result as GetFileDataResponse);
}

async createFile(
call: GrpcRequest<CreateFileRequest>,
callback: GrpcCallback<FileResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.createFile(request);
const response = this.storageParamAdapter.getFileResponse(result);
callback(null, response);
}

async updateFile(
call: GrpcRequest<UpdateFileRequest>,
callback: GrpcCallback<FileResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.updateFile(request);
const response = this.storageParamAdapter.getFileResponse(result);
callback(null, response);
}

async deleteFile(
call: GrpcRequest<GetFileRequest>,
callback: GrpcResponse<DeleteFileResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.deleteFile(request);
callback(null, result as DeleteFileResponse);
}

async createFile(call: ParsedRouterRequest, callback: GrpcCallback<FileResponse>) {
async createFileByUrl(
call: GrpcRequest<CreateFileByUrlRequest>,
callback: GrpcResponse<FileByUrlResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
await this._fileHandlers.createFile(call);
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.createFileUploadUrl(request);
const response = this.storageParamAdapter.getFileByUrlResponse(result);
callback(null, response);
}

async updateFile(call: ParsedRouterRequest, callback: GrpcCallback<FileResponse>) {
async updateFileByUrl(
call: GrpcRequest<UpdateFileByUrlRequest>,
callback: GrpcResponse<FileByUrlResponse>,
) {
if (!this._fileHandlers)
return callback({
code: status.INTERNAL,
message: 'File handlers not initiated',
});
await this._fileHandlers.updateFile(call);
const request = this.storageParamAdapter.createParsedRouterRequest(call.request);
const result = await this._fileHandlers.updateFileUploadUrl(request);
const response = this.storageParamAdapter.getFileByUrlResponse(result);
callback(null, response);
}
}
54 changes: 54 additions & 0 deletions modules/storage/src/adapter/StorageParamAdapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
Context,
Cookies,
Indexable,
Params,
ParsedRouterRequest,
UnparsedRouterResponse,
} from '@conduitplatform/grpc-sdk';
import { FileByUrlResponse, FileResponse } from '../protoTypes/storage';

export class StorageParamAdapter {
constructor() {}

createParsedRouterRequest(
params: Params,
urlParams?: Params,
queryParams?: Params,
bodyParams?: Params,
path?: string,
headers?: Headers,
context?: Context,
cookies?: Cookies,
): ParsedRouterRequest {
return {
request: {
params,
urlParams: urlParams ?? {},
queryParams: queryParams ?? {},
bodyParams: bodyParams ?? {},
path: path ?? '',
headers: headers ?? {},
context: context ?? {},
cookies: cookies ?? {},
},
};
}

getFileResponse(response: UnparsedRouterResponse): FileResponse {
return {
id: (response as Indexable)._id,
url: (response as Indexable).url,
name: (response as Indexable).name,
};
}

getFileByUrlResponse(response: UnparsedRouterResponse): FileByUrlResponse {
return {
id: (response as Indexable)._id,
fileUrl: (response as Indexable).file.url,
name: (response as Indexable).name,
uploadUrl: (response as Indexable).url,
};
}
}
10 changes: 8 additions & 2 deletions modules/storage/src/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ export class AdminRoutes {
path: '/files/upload',
description: `Creates a new file and provides a URL to upload it to.`,
},
new ConduitRouteReturnDefinition('CreateFileByUrl', File.name),
new ConduitRouteReturnDefinition('CreateFileByUrl', {
file: File.getInstance().fields,
url: ConduitString.Required,
}),
this.fileHandlers.createFileUploadUrl.bind(this.fileHandlers),
);
this.routingManager.route(
Expand Down Expand Up @@ -133,7 +136,10 @@ export class AdminRoutes {
path: '/files/upload/:id',
description: `Updates a file and provides a URL to upload its data to.`,
},
new ConduitRouteReturnDefinition('PatchFileByUrl', 'String'),
new ConduitRouteReturnDefinition('PatchFileByUrl', {
file: File.getInstance().fields,
url: ConduitString.Required,
}),
this.fileHandlers.updateFileUploadUrl.bind(this.fileHandlers),
);
this.routingManager.route(
Expand Down
10 changes: 6 additions & 4 deletions modules/storage/src/handlers/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,12 @@ export class FileHandlers {
mimeType: string,
file: File,
size: number | undefined | null,
): Promise<string> {
): Promise<{ file: File; url: string }> {
let updatedFile;
const onlyDataUpdate =
name === file.name && folder === file.folder && container === file.container;
if (onlyDataUpdate) {
await File.getInstance().findByIdAndUpdate(file._id, {
updatedFile = await File.getInstance().findByIdAndUpdate(file._id, {
mimeType,
...{ size: size ?? file.size },
});
Expand All @@ -434,7 +435,7 @@ export class FileHandlers {
.container(container)
.getPublicUrl((folder === '/' ? '' : folder) + name)
: null;
await File.getInstance().findByIdAndUpdate(file._id, {
updatedFile = await File.getInstance().findByIdAndUpdate(file._id, {
name,
folder,
container,
Expand All @@ -444,9 +445,10 @@ export class FileHandlers {
});
}
if (!isNil(size)) this.updateFileMetrics(file.size, size!);
return (await this.storageProvider
const uploadUrl = (await this.storageProvider
.container(container)
.getUploadUrl((folder === '/' ? '' : folder) + name)) as string;
return { file: updatedFile!, url: uploadUrl };
}

private async _updateFile(
Expand Down
5 changes: 4 additions & 1 deletion modules/storage/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ export class StorageRoutes {
description: `Updates a file and provides a URL to upload its data to.`,
middlewares: ['authMiddleware'],
},
new ConduitRouteReturnDefinition('PatchFileByUrl', 'String'),
new ConduitRouteReturnDefinition('PatchFileByUrl', {
file: File.getInstance().fields,
url: ConduitString.Required,
}),
this.fileHandlers.updateFileUploadUrl.bind(this.fileHandlers),
);
this._routingManager.route(
Expand Down
Loading

0 comments on commit c799c5d

Please sign in to comment.