Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File Service Config Environments & Provider Types #166

Merged
merged 8 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions packages/api-gateway/src/models/file_provider.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IsNotEmpty } from 'class-validator';
import { IsNotEmpty, ValidateNested } from 'class-validator';

import { ApiProperty } from '@nestjs/swagger';
import { FileProviderProto } from 'juno-proto';
import { Transform, Type } from 'class-transformer';

class AccessKey {
@ApiProperty({
Expand All @@ -21,11 +22,12 @@ class AccessKey {

export class RegisterFileProviderModel {
@ApiProperty({
type: [AccessKey],
format: 'email',
type: AccessKey,
description: 'The access key to register with',
})
@IsNotEmpty()
@ValidateNested()
@Type(() => AccessKey)
accessKey: AccessKey;

@ApiProperty({
Expand All @@ -43,6 +45,15 @@ export class RegisterFileProviderModel {
})
@IsNotEmpty()
providerName: string;

@IsNotEmpty()
@Transform(toEnum)
@ApiProperty({
type: 'string',
description: 'File provider type (one of S3 or AZURE)',
example: 'S3',
})
type: FileProviderProto.ProviderType;
}

export class FileProviderResponse {
Expand All @@ -57,3 +68,16 @@ export class FileProviderResponse {
this.metadata = fileProvider.metadata;
}
}

function toEnum(params: {
value: string;
}): FileProviderProto.ProviderType | undefined {
switch (params.value) {
case 'S3':
return FileProviderProto.ProviderType.S3;
case 'AZURE':
return FileProviderProto.ProviderType.AZURE;
default:
return undefined;
}
UZ9 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { lastValueFrom } from 'rxjs';
import { FileBucketProto } from 'juno-proto';
import { AuthCommonProto, FileBucketProto } from 'juno-proto';
import {
ApiBearerAuth,
ApiOperation,
Expand All @@ -19,6 +19,7 @@ import {
RegisterFileBucketModel,
FileBucketResponse,
} from 'src/models/file_bucket.dto';
import { ApiKey } from 'src/decorators/api_key.decorator';

const { BUCKET_FILE_SERVICE_NAME } = FileBucketProto;

Expand Down Expand Up @@ -52,13 +53,15 @@ export class FileBucketController implements OnModuleInit {
type: FileBucketResponse,
})
async registerFileBucket(
@ApiKey() apiKey: AuthCommonProto.ApiKey,
@Body() params: RegisterFileBucketModel,
): Promise<FileBucketResponse> {
const grpcResponse = this.fileBucketService.registerBucket({
name: params.name,
configId: params.configId,
fileProviderName: params.fileProviderName,
FileServiceFile: params.FileServiceFile,
UZ9 marked this conversation as resolved.
Show resolved Hide resolved
configEnv: apiKey.environment,
});

const bucketData = await lastValueFrom(grpcResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { lastValueFrom } from 'rxjs';
import { FileProto } from 'juno-proto';
import { AuthCommonProto, FileProto } from 'juno-proto';
import {
ApiBearerAuth,
ApiOperation,
Expand All @@ -19,6 +19,7 @@ import {
DownloadFileModel,
DownloadFileResponse,
} from 'src/models/file_download.dto';
import { ApiKey } from 'src/decorators/api_key.decorator';

const { FILE_SERVICE_NAME } = FileProto;

Expand Down Expand Up @@ -56,9 +57,15 @@ export class FileDownloadController implements OnModuleInit {
type: DownloadFileResponse,
})
async downloadFile(
@ApiKey() apiKey: AuthCommonProto.ApiKey,
@Body('') params: DownloadFileModel,
): Promise<DownloadFileResponse> {
const res = await lastValueFrom(this.fileService.downloadFile(params));
const res = await lastValueFrom(
this.fileService.downloadFile({
configEnv: apiKey.environment,
...params,
}),
UZ9 marked this conversation as resolved.
Show resolved Hide resolved
);

return new DownloadFileResponse(res);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class FileProviderController implements OnModuleInit {
providerName: params.providerName,
privateAccessKey: params.accessKey.privateAccessKey,
publicAccessKey: params.accessKey.publicAccessKey,
type: params.type,
});

return new FileProviderResponse(await lastValueFrom(fileProvider));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { lastValueFrom } from 'rxjs';
import { FileProto } from 'juno-proto';
import { AuthCommonProto, FileProto } from 'juno-proto';
import {
ApiBearerAuth,
ApiOperation,
Expand All @@ -19,6 +19,7 @@ import {
UploadFileResponse,
UploadFileModel,
} from 'src/models/file_upload.dto';
import { ApiKey } from 'src/decorators/api_key.decorator';

const { FILE_SERVICE_NAME } = FileProto;

Expand Down Expand Up @@ -54,6 +55,7 @@ export class FileUploadController implements OnModuleInit {
type: UploadFileResponse,
})
async uploadFile(
@ApiKey() apiKey: AuthCommonProto.ApiKey,
@Body('') params: UploadFileModel,
): Promise<UploadFileResponse> {
const uploadFile = this.fileService.uploadFile({
Expand All @@ -62,6 +64,7 @@ export class FileUploadController implements OnModuleInit {
providerName: params.providerName,
configId: params.configId,
region: params.region,
configEnv: apiKey.environment,
});

return new UploadFileResponse(await lastValueFrom(uploadFile));
Expand Down
15 changes: 9 additions & 6 deletions packages/api-gateway/test/file_bucket.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { AppModule } from './../src/app.module';
import { Reflector } from '@nestjs/core';
import * as request from 'supertest';
import {
FileBucketProto,
ResetProtoFile,
FileProviderProtoFile,
FileProviderProto,
} from 'juno-proto';
import * as GRPC from '@grpc/grpc-js';
import * as ProtoLoader from '@grpc/proto-loader';
Expand All @@ -28,6 +28,8 @@ const secretAccessKey = process.env.secretAccessKey;
const baseURL = process.env.baseURL;
const providerName = 'backblazeb2-upload';

jest.setTimeout(10000);

async function APIKeyForProjectName(projectName: string): Promise<string> {
const key = await request(app.getHttpServer())
.post('/auth/key')
Expand Down Expand Up @@ -90,6 +92,7 @@ beforeAll(async () => {
}),
metadata: JSON.stringify({ endpoint: baseURL }),
bucket: [],
type: FileProviderProto.ProviderType.S3,
},
(err: any) => {
if (err) return reject(err);
Expand Down Expand Up @@ -118,7 +121,7 @@ describe('File Bucket Routes', () => {
});

it('Creating a bucket successfully', async () => {
const fileBucketBody: FileBucketProto.RegisterBucketRequest = {
const fileBucketBody = {
name: uniqueBucketName,
configId: 0,
fileProviderName: providerName,
Expand Down Expand Up @@ -146,7 +149,7 @@ describe('File Bucket Routes', () => {
});

it('Unsuccessful creation due to missing bucket name', async () => {
const fileBucketBody: FileBucketProto.RegisterBucketRequest = {
const fileBucketBody = {
name: '',
configId: 1,
fileProviderName: 'Test Provider',
Expand All @@ -161,7 +164,7 @@ describe('File Bucket Routes', () => {
});

it('Unsuccessful creation due to missing config ID', async () => {
const fileBucketBody: FileBucketProto.RegisterBucketRequest = {
const fileBucketBody = {
name: uniqueBucketName,
configId: undefined,
fileProviderName: 'Test Provider',
Expand All @@ -176,7 +179,7 @@ describe('File Bucket Routes', () => {
});

it('Unsuccessful creation due to missing file provider name', async () => {
const fileBucketBody: FileBucketProto.RegisterBucketRequest = {
const fileBucketBody = {
name: uniqueBucketName,
configId: 1,
fileProviderName: '',
Expand All @@ -191,7 +194,7 @@ describe('File Bucket Routes', () => {
});

it('Creating an existing bucket (should fail)', async () => {
const fileBucketBody: FileBucketProto.RegisterBucketRequest = {
const fileBucketBody = {
name: uniqueBucketName + '-duplicate',
configId: 0,
fileProviderName: providerName,
Expand Down
4 changes: 4 additions & 0 deletions packages/api-gateway/test/file_download.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
FileProviderProtoFile,
FileBucketProtoFile,
ResetProtoFile,
FileProviderProto,
} from 'juno-proto';
import * as GRPC from '@grpc/grpc-js';
import * as ProtoLoader from '@grpc/proto-loader';
Expand Down Expand Up @@ -84,6 +85,7 @@ beforeAll(async () => {
}),
metadata: JSON.stringify({ endpoint: baseURL }),
bucket: [],
type: FileProviderProto.ProviderType.S3,
},
() => {
resolve(0);
Expand All @@ -105,6 +107,7 @@ beforeAll(async () => {
name: bucketName,
configId: configId,
fileProviderName: providerName,
configEnv: 'prod',
files: [],
},
() => {
Expand All @@ -124,6 +127,7 @@ beforeAll(async () => {
fileId: {
bucketName: bucketName,
configId: configId,
configEnv: 'prod',
path: validFile,
},
metadata: '',
Expand Down
Loading