Skip to content

faizulmushofa/storage-node-grpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Storage Node gRPC

Docker Image Spring Boot Java Version gRPC

Storage Node gRPC adalah microservice penyimpanan khusus (dedicated storage worker) berbasis Java Spring Boot dan gRPC. Proyek ini berfungsi sebagai pasangan/pendamping dari repositori backend utama Anda:

πŸ”— vps-personal-BE

Dengan memisahkan tugas I/O file berat (seperti upload chunk, perakitan file, dan streaming download) dari backend utama, arsitektur microservice ini memastikan penggunaan CPU, RAM, dan I/O disk pada VPS personal Anda tetap stabil, responsif, dan terisolasi dengan aman.


πŸ—οΈ Arsitektur Hubungan Sistem

Berikut adalah alur integrasi antara Client, Backend Utama, dan gRPC Storage Node:

graph TD
    Client["Client / Frontend"] -->|1. REST API Upload/Download| BE["vps-personal-BE"]
    BE -->|2. gRPC Stream Port 9090| SN["Storage Node gRPC"]
    SN -->|3. Simpan Fisik| FS["Physical Disk Storage"]
Loading

⚑ Fitur Utama

  • πŸ“¦ Chunked Uploads (UploadBatch): Menerima chunk file berukuran besar secara asinkron ke dalam direktori staging (storage/staging/{userId}/{fileId}) dan merakitnya secara otomatis setelah selesai.
  • πŸ“₯ Streaming Downloads (DownloadFile): Menyajikan file kembali dalam bentuk stream data berukuran 1MB secara buffered agar hemat memori RAM.
  • πŸ”’ gRPC Interceptor Security: Seluruh request gRPC divalidasi secara real-time menggunakan GrpcAuthServerInterceptor dengan skema Bearer token.
  • 🚦 Flow Control & Backpressure: Menggunakan Semaphore controller (limit: 20 antrean thread) untuk menjamin node tidak mengalami overload.
  • πŸ“ Isolasi Folder User: Penyimpanan file staging maupun final sepenuhnya dikelompokkan secara terisolasi berdasarkan parameter userId.

πŸš€ Penggunaan Cepat dengan Docker

Layanan ini sudah dipaketkan ke dalam image Docker Hub resmi di faizul20/storage-node.

1. Mode Standar (Dengan SSL/TLS - Direkomendasikan untuk Production)

Secara default, SSL/TLS diaktifkan menggunakan JKS keystore (keystore.p12) bawaan proyek:

docker run -d \
  --name storage-node-grpc \
  -p 9090:9090 \
  -e SERVICE_TOKEN="isi-token-rahasia-anda" \
  -v /path/di/vps/data:/app/Data \
  faizul20/storage-node:latest

2. Mode Tanpa SSL/TLS (Plaintext - Untuk Testing/Lokal)

Jika Anda ingin mematikan SSL/TLS agar backend utama (vps-personal-BE) dapat terhubung secara plaintext biasa (tanpa sertifikat SSL):

docker run -d \
  --name storage-node-grpc \
  -p 9090:9090 \
  -e SERVICE_TOKEN="isi-token-rahasia-anda" \
  -e SPRING_GRPC_SERVER_SSL_BUNDLE="" \
  -v /path/di/vps/data:/app/Data \
  faizul20/storage-node:latest

Important

Pastikan nilai SERVICE_TOKEN di atas sama dengan konfigurasi token gRPC client yang dipasang pada repositori vps-personal-BE agar komunikasi berjalan sukses.


βš™οΈ Variabel Lingkungan & Konfigurasi (Spring Boot & Docker)

Anda dapat mengonfigurasi aplikasi baik via file application.yaml maupun langsung melalui Environment Variable Docker:

Environment Variable Properti Spring Default Deskripsi
SERVICE_TOKEN spring.grpc.security.service-token Wajib Diisi Token rahasia penjamin keamanan autentikasi gRPC channel.
SPRING_GRPC_SERVER_PORT spring.grpc.server.port 9090 Port gRPC Server yang diekspos untuk komunikasi.
SPRING_GRPC_SERVER_ADDRESS spring.grpc.server.address 0.0.0.0 IP Address binding untuk gRPC Server listener.
SPRING_GRPC_SERVER_SSL_BUNDLE spring.grpc.server.ssl.bundle storage-ssl-bundle Menghubungkan SSL Bundle. Isi kosong "" untuk mematikan SSL.

πŸ“œ Kontrak Layanan & Cara Penggunaan (gRPC API Contract)

Karena layanan ini berkomunikasi menggunakan gRPC, klien (vps-personal-BE) harus menggunakan file .proto yang sama untuk men-generate gRPC Client.

1. Protobuf Definitions

πŸ“€ upload.proto

syntax = "proto3";
package upload;

service UploadService {
  // Mengunggah file dalam bentuk pecahan stream chunk
  rpc UploadBatch(stream UploadChunkRequest) returns (UploadBatchResponse);
  
  // Menginstruksikan perakitan akhir semua chunk menjadi satu file utuh
  rpc FinalizeUpload(FinalizeRequest) returns (FinalizeResponse);
  
  // Menghapus file fisik di storage node
  rpc DeleteFile(DeleteFileRequest) returns (DeleteFileResponse);
}

message UploadChunkRequest {
  string file_id = 1;
  int32 chunk_index = 2;
  int32 total_chunks = 3;
  bytes data = 4;
  string user_id = 5;
}

message UploadBatchResponse {
  string file_id = 1;
  bool success = 2;
  string message = 3;
}

message FinalizeRequest {
  string file_id = 1;
  int32 total_chunks = 2;
  string user_id = 3;
}

message FinalizeResponse {
  string file_id = 1;
  bool success = 2;
  string message = 3;
}

message DeleteFileRequest {
  string file_id = 1;
  string user_id = 2;
}

message DeleteFileResponse {
  string file_id = 1;
  bool success = 2;
  string message = 3;
}

πŸ“₯ download.proto

syntax = "proto3";
package download;

service DownloadService {
  // Mengunduh file secara streaming (chunk-by-chunk)
  rpc DownloadFile(DownloadRequest) returns (stream DownloadResponse);
}

message DownloadRequest {
  string file_id = 1;
  string user_id = 2;
}

message DownloadResponse {
  string file_id = 1;
  int32 chunk_index = 2;
  int32 total_chunks = 3;
  bytes data = 4;
}

2. Cara Integrasi Klien (Contoh pada vps-personal-BE / Node.js)

Agar vps-personal-BE dapat terhubung ke storage-node-grpc, klien wajib menyertakan token autentikasi di dalam metadata request gRPC.

Berikut adalah cuplikan kode integrasi client gRPC sederhana di Node.js:

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

// 1. Muat protobuf file
const packageDefinition = protoLoader.loadSync('upload.proto', {});
const uploadProto = grpc.loadPackageDefinition(packageDefinition).upload;

// 2. Hubungkan ke Storage Node (Plaintext/SSL)
const targetAddress = 'localhost:9090'; // IP VPS / Container
const client = new uploadProto.UploadService(
  targetAddress, 
  grpc.credentials.createInsecure() // Gunakan secure credentials jika SSL aktif
);

// 3. Wajib: Buat metadata dengan Authorization Header
const metadata = new grpc.Metadata();
metadata.add('Authorization', 'Bearer token-rahasia-anda-yang-sesuai-env');

// 4. Lakukan pemanggilan gRPC (Contoh: DeleteFile)
client.DeleteFile({
  fileId: 'file-12345',
  userId: 'user-789'
}, metadata, (error, response) => {
  if (error) {
    console.error('Gagal memanggil storage-node:', error.message);
    return;
  }
  console.log('Respons dari storage-node:', response.message); // "File deleted successfully"
});

πŸ› οΈ Langkah Menjalankan Secara Lokal (Development)

Prasyarat

  • Java Development Kit (JDK) 21 atau lebih tinggi
  • Maven 3+ (atau menggunakan ./mvnw wrapper bawaan)

1. Compile & Generate Protobuf Sources

./mvnw clean compile

2. Jalankan Unit Test

./mvnw test

3. Jalankan Aplikasi Secara Lokal

  • Linux / macOS:
    SERVICE_TOKEN="rahasia-anda" ./mvnw spring-boot:run
  • Windows (Command Prompt):
    set SERVICE_TOKEN=rahasia-anda
    mvnw spring-boot:run
  • Windows (PowerShell):
    $env:SERVICE_TOKEN="rahasia-anda"
    ./mvnw spring-boot:run

πŸ§‘β€πŸ’» Penulis

About

"Microservice storage berbasis gRPC untuk vps-personal-backend, menangani upload/download file secara aman, terisolasi, dan hemat resource VPS."

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors