Tải lên Google Cloud Storage

Mô tả tổng quan

Tính năng tải lên Google Cloud Storage (GCS) cung cấp cách thức an toàn và hiệu quả để tải lên, tải xuống và quản lý tệp trong Google Cloud Storage. Tính năng này sử dụng URL có chữ ký để cho phép tải lên trực tiếp từ client đến GCS, giúp cải thiện hiệu suất bằng cách bỏ qua server ứng dụng cho việc chuyển tệp. Nó cũng cung cấp các phương thức để liệt kê, xóa và lấy URL truy cập tạm thời cho các tệp được lưu trữ trong GCS.

Liên kết Swagger

API: Tải lên Gcs

Sơ đồ hoạt động

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    Client[Ứng dụng Client]
    API[UploadGcsController]
    GCSService[GcsService]
    ImportService[ImportReviewService]
    GCS[(Google Cloud Storage)]

    Client --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>Yêu cầu URL có chữ ký</p>
        </div>
    ]
    Step1 --> API

    API --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>Tạo URL có chữ ký</p>
        </div>
    ]
    Step2 --> ImportService

    ImportService --- Step3[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
            <p style='margin-top: 8px'>Yêu cầu URL từ GCS</p>
        </div>
    ]
    Step3 --> GCSService

    GCSService --- Step4[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4</span>
            <p style='margin-top: 8px'>Trả về URL có chữ ký</p>
        </div>
    ]
    Step4 --> GCS

    GCS --- Step5[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
            <p style='margin-top: 8px'>Trả về URL cho client</p>
        </div>
    ]
    Step5 --> GCSService
    GCSService --> ImportService
    ImportService --> API
    API --> Client

    Client --- Step6[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6</span>
            <p style='margin-top: 8px'>Tải lên tệp trực tiếp</p>
        </div>
    ]
    Step6 --> GCS

    style Client fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style API fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style GCSService fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ImportService fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style GCS fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3 fill:transparent,stroke:transparent,stroke-width:1px
    style Step4 fill:transparent,stroke:transparent,stroke-width:1px
    style Step5 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6 fill:transparent,stroke:transparent,stroke-width:1px

Tài liệu trường hợp

Trường hợp 1: Tạo URL có chữ ký cho tải lên trực tiếp

Mô tả

Client yêu cầu URL có chữ ký để tải lên tệp trực tiếp lên Google Cloud Storage.

Sơ đồ tuần tự

sequenceDiagram
    participant Client as Client
    participant API as UploadGcsController
    participant Service as ImportReviewService
    participant GCSService as GcsService
    participant GCS as Google Cloud Storage

    Note over Client,GCS: Luồng tạo URL có chữ ký

    rect rgb(200, 255, 200)
    Note right of Client: Luồng thành công

    Client->>API: GET /api/v1/general/upload-file/gcs/get-signed-url

    rect rgb(200, 230, 255)
    Note right of API: Xác thực đầu vào
    API->>API: Xác thực tham số filename
    end

    rect rgb(200, 255, 255)
    Note right of API: Logic nghiệp vụ
    API->>Service: getSignedUrl(filename)
    Service->>Service: Tạo đường dẫn với cấu trúc nhóm và ngày
    Service->>GCSService: getSignedUrl(path, contentType, expiration)
    GCSService->>GCS: Tạo URL có chữ ký với phương thức PUT
    GCS-->>GCSService: Trả về URL có chữ ký
    GCSService-->>Service: Trả về dữ liệu URL, đường dẫn, thời hạn
    Service-->>API: Trả về dữ liệu URL
    end

    API-->>Client: 200 OK (URL có chữ ký và metadata)
    end

    rect rgb(255, 200, 200)
    Note right of Client: Xử lý lỗi
    rect rgb(255, 230, 230)
    alt Lỗi xác thực
        API-->>Client: 422 Lỗi xác thực
    else Lỗi GCS
        GCS-->>GCSService: Phản hồi lỗi
        GCSService-->>Service: Kết quả lỗi
        Service-->>API: Kết quả lỗi
        API-->>Client: 400 Bad Request
    end
    end
    end

Các bước

Bước 1: Yêu cầu URL có chữ ký

  • Mô tả: Client yêu cầu URL có chữ ký để tải lên tệp
  • Yêu cầu: GET /api/v1/general/upload-file/gcs/get-signed-url
  • Tham số:
    • filename: Tên tệp cần tải lên (bắt buộc)
  • Xác thực:
    • Tên tệp phải là chuỗi và không quá 255 ký tự

Bước 2: Tạo URL có chữ ký

  • Mô tả: Hệ thống tạo URL có chữ ký cho tải lên trực tiếp
  • Hành động:
    • Tạo cấu trúc đường dẫn: temp/{group_id}/{date}/{filename}
    • Đặt content type là 'text/csv'
    • Yêu cầu URL có chữ ký từ Google Cloud Storage với phương thức PUT
    • Đặt thời hạn URL là 15 phút (900 giây)

Bước 3: Trả về URL cho client

  • Mô tả: Trả về URL có chữ ký và metadata cho client
  • Phản hồi:
    • Thành công: 200 OK (dữ liệu URL có chữ ký bao gồm cờ thành công, URL, đường dẫn, thời hạn, content type)
    • Lỗi: 400 Bad Request (thông báo lỗi)

Xử lý lỗi

  • Ghi log
    • Lỗi tạo URL được ghi vào log ứng dụng
  • Chi tiết lỗi:
    Mã trạng thái Thông báo lỗi Mô tả
    422 Lỗi xác thực Tham số filename không hợp lệ
    400 Không thể tạo URL có chữ ký GCS trả về lỗi hoặc service thất bại

Trường hợp 2: Tải lên tệp qua server

Mô tả

Client tải lên tệp lên server và server tải lên lên Google Cloud Storage.

Sơ đồ tuần tự

sequenceDiagram
    participant Client as Client
    participant API as UploadGcsController
    participant Service as GcsService
    participant GCS as Google Cloud Storage

    Note over Client,GCS: Luồng tải lên qua server

    rect rgb(200, 255, 200)
    Note right of Client: Luồng thành công

    Client->>API: POST /api/v1/general/upload-file/gcs/upload-file

    rect rgb(200, 230, 255)
    Note right of API: Xác thực đầu vào
    API->>API: Xác thực tệp và đường dẫn
    end

    rect rgb(200, 255, 255)
    Note right of API: Logic nghiệp vụ
    API->>Service: uploadFile(file, path)
    Service->>Service: Tạo tên tệp duy nhất
    Service->>GCS: Tải lên tệp
    GCS-->>Service: Xác nhận tải lên
    Service-->>API: Trả về đường dẫn tệp và URL
    end

    API-->>Client: 200 OK (đường dẫn tệp và URL)
    end

    rect rgb(255, 200, 200)
    Note right of Client: Xử lý lỗi
    rect rgb(255, 230, 230)
    alt Lỗi xác thực
        API-->>Client: 422 Lỗi xác thực
    else Lỗi tải lên
        GCS-->>Service: Phản hồi lỗi
        Service-->>API: Kết quả lỗi
        API-->>Client: 500 Lỗi server nội bộ
    end
    end
    end

Các bước

Bước 1: Yêu cầu tải lên tệp

  • Mô tả: Client tải lên tệp lên server
  • Yêu cầu: POST /api/v1/general/upload-file/gcs/upload-file
  • Tham số:
    • file: Tệp cần tải lên (bắt buộc)
    • path: Đường dẫn lưu trữ tệp (bắt buộc)
  • Xác thực:
    • Tệp phải tồn tại và không quá 10MB
    • Đường dẫn phải là chuỗi

Bước 2: Xử lý tải lên

  • Mô tả: Hệ thống tải lên tệp lên GCS
  • Hành động:
    • Thêm chuỗi ngẫu nhiên để đảm bảo tính duy nhất của đường dẫn
    • Đặt content type phù hợp dựa trên MIME type của tệp
    • Tải lên tệp lên GCS

Bước 3: Trả về kết quả

  • Mô tả: Trả về kết quả tải lên cho client
  • Phản hồi:
    • Thành công: 200 OK (đường dẫn tệp và URL công khai)
    • Lỗi: Mã lỗi và thông báo phù hợp

Xử lý lỗi

  • Ghi log
    • Lỗi tải lên được ghi vào log ứng dụng
  • Chi tiết lỗi:
    Mã trạng thái Thông báo lỗi Mô tả
    422 Lỗi xác thực Tham số tệp hoặc đường dẫn không hợp lệ
    500 Không thể tải lên tệp: {error} GCS trả về lỗi

Trường hợp 3: Liệt kê tệp trong thư mục

Mô tả

Client yêu cầu danh sách tệp trong thư mục cụ thể của Google Cloud Storage.

Sơ đồ tuần tự

sequenceDiagram
    participant Client as Client
    participant API as UploadGcsController
    participant Service as GcsService
    participant GCS as Google Cloud Storage

    Note over Client,GCS: Luồng liệt kê tệp

    rect rgb(200, 255, 200)
    Note right of Client: Luồng thành công

    Client->>API: GET /api/v1/general/upload-file/gcs/list-files

    rect rgb(200, 230, 255)
    Note right of API: Xác thực đầu vào
    API->>API: Xác thực thư mục và cờ đệ quy
    end

    rect rgb(200, 255, 255)
    Note right of API: Logic nghiệp vụ
    API->>Service: listFiles(directory, recursive)
    Service->>GCS: Liệt kê tệp trong thư mục
    GCS-->>Service: Trả về danh sách tệp
    Service-->>API: Trả về danh sách tệp và thư mục
    end

    API-->>Client: 200 OK (danh sách tệp)
    end

    rect rgb(255, 200, 200)
    Note right of Client: Xử lý lỗi
    rect rgb(255, 230, 230)
    alt Lỗi xác thực
        API-->>Client: 422 Lỗi xác thực
    else Lỗi GCS
        GCS-->>Service: Phản hồi lỗi
        Service-->>API: Kết quả lỗi
        API-->>Client: 500 Lỗi server nội bộ
    end
    end
    end

Các bước

Bước 1: Yêu cầu danh sách tệp

  • Mô tả: Client yêu cầu danh sách tệp trong thư mục
  • Yêu cầu: GET /api/v1/general/upload-file/gcs/list-files
  • Tham số:
    • directory: Thư mục để liệt kê tệp (tùy chọn, mặc định: root)
    • recursive: Có liệt kê tệp đệ quy hay không (tùy chọn, mặc định: false)
  • Xác thực:
    • Thư mục phải là chuỗi
    • Cờ đệ quy phải là boolean

Bước 2: Lấy danh sách tệp

  • Mô tả: Hệ thống lấy danh sách tệp từ GCS
  • Hành động:
    • Truy vấn tệp trong thư mục được chỉ định từ GCS
    • Bao gồm metadata tệp (kích thước, ngày cập nhật cuối, v.v.)
    • Trả về danh sách tệp được định dạng

Bước 3: Trả về danh sách tệp

  • Mô tả: Trả về danh sách tệp cho client
  • Phản hồi:
    • Thành công: 200 OK (danh sách tệp và thông tin thư mục)
    • Lỗi: Mã lỗi và thông báo phù hợp

Xử lý lỗi

  • Ghi log
    • Lỗi liệt kê tệp được ghi vào log ứng dụng
  • Chi tiết lỗi:
    Mã trạng thái Thông báo lỗi Mô tả
    422 Lỗi xác thực Tham số thư mục hoặc đệ quy không hợp lệ
    500 Không thể liệt kê tệp: {error} GCS trả về lỗi

Bảng và trường cơ sở dữ liệu liên quan

erDiagram
    review_upload_histories {
        bigint id PK
        bigint user_id FK "Tham chiếu đến bảng users"
        bigint group_id FK "Tham chiếu đến bảng groups"
        string file_name "Tên tệp đã tải lên"
        string gcs_path "Đường dẫn tệp được lưu trong Google Cloud Storage"
        tinyInteger status "Trạng thái tải lên: 0=Chưa xử lý, 1=Đang xử lý, 2=Thành công, 3=Thất bại"
        string error_reason "Thông báo lỗi khi tải lên thất bại (có thể null)"
        timestamp validated_at "Thời điểm tệp được xác thực (có thể null)"
        timestamp created_at
        timestamp updated_at
    }
    users {
        bigint id PK
        string name "Họ tên đầy đủ của người dùng"
        string email "Địa chỉ email của người dùng"
    }
    groups {
        bigint id PK
        string name "Tên nhóm"
    }

    review_upload_histories ||--o{ users : Thuộc về
    review_upload_histories ||--o{ groups : Thuộc về

Tính năng chính

  • Hỗ trợ tải lên trực tiếp: Tạo URL có chữ ký cho tải lên trực tiếp từ client đến GCS
  • Cấu trúc đường dẫn dựa trên nhóm: Tạo đường dẫn tự động dựa trên nhóm và ngày của người dùng
  • Hỗ trợ tệp CSV: Tối ưu hóa tải lên tệp CSV với xử lý content type phù hợp
  • Xử lý lỗi: Xử lý lỗi toàn diện với ghi log chi tiết
  • Bảo mật: URL có chữ ký với thời hạn có thể cấu hình
  • Quản lý tệp: Hỗ trợ liệt kê và thao tác quản lý tệp

Cân nhắc bảo mật

  • Phân tách nhóm: Tệp được lưu trong thư mục riêng biệt cho từng nhóm
  • Thời hạn URL có chữ ký: URL được tạo sẽ hết hạn sau 15 phút
  • Xác thực đầu vào: Tất cả endpoint đều có xác thực đầu vào toàn diện
  • Ghi log lỗi: Các thao tác thất bại được ghi log để giám sát và debug