UploadFileChunk.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { inject, injectable } from 'inversify'
  2. import { Logger } from 'winston'
  3. import TYPES from '../../../Bootstrap/Types'
  4. import { UseCaseInterface } from '../UseCaseInterface'
  5. import { UploadFileChunkDTO } from './UploadFileChunkDTO'
  6. import { UploadFileChunkResponse } from './UploadFileChunkResponse'
  7. import { FileUploaderInterface } from '../../Services/FileUploaderInterface'
  8. import { UploadRepositoryInterface } from '../../Upload/UploadRepositoryInterface'
  9. @injectable()
  10. export class UploadFileChunk implements UseCaseInterface {
  11. constructor(
  12. @inject(TYPES.Files_FileUploader) private fileUploader: FileUploaderInterface,
  13. @inject(TYPES.Files_UploadRepository) private uploadRepository: UploadRepositoryInterface,
  14. @inject(TYPES.Files_Logger) private logger: Logger,
  15. ) {}
  16. async execute(dto: UploadFileChunkDTO): Promise<UploadFileChunkResponse> {
  17. try {
  18. if (!dto.data.byteLength || dto.data.byteLength === 0) {
  19. this.logger.debug(
  20. `Skipping upload file chunk ${dto.chunkId} with 0 bytes for resource: ${dto.resourceRemoteIdentifier}`,
  21. )
  22. return {
  23. success: false,
  24. message: 'Empty file chunk',
  25. }
  26. }
  27. this.logger.debug(
  28. `Starting upload file chunk ${dto.chunkId} with ${dto.data.byteLength} bytes for resource: ${dto.resourceRemoteIdentifier}`,
  29. )
  30. const filePath = `${dto.userUuid}/${dto.resourceRemoteIdentifier}`
  31. const uploadId = await this.uploadRepository.retrieveUploadSessionId(filePath)
  32. if (uploadId === undefined) {
  33. this.logger.warn(`Could not find upload session for file path: ${filePath}`)
  34. return {
  35. success: false,
  36. message: 'Could not find upload session',
  37. }
  38. }
  39. const uploadFileChunkETag = await this.fileUploader.uploadFileChunk({
  40. uploadId,
  41. data: dto.data,
  42. chunkId: dto.chunkId,
  43. filePath,
  44. unencryptedFileSize: dto.resourceUnencryptedFileSize,
  45. })
  46. await this.uploadRepository.storeUploadChunkResult(uploadId, {
  47. tag: uploadFileChunkETag,
  48. chunkId: dto.chunkId,
  49. chunkSize: dto.data.byteLength,
  50. })
  51. return {
  52. success: true,
  53. }
  54. } catch (error) {
  55. this.logger.error(
  56. `Could not upload file chunk for resource: ${dto.resourceRemoteIdentifier} - ${(error as Error).message}`,
  57. )
  58. return {
  59. success: false,
  60. message: 'Could not upload file chunk',
  61. }
  62. }
  63. }
  64. }