Cloud Storage is a service for storing your objects in Google Cloud. An object is an immutable piece of data consisting of a file of any format. You store objects in containers called buckets. All buckets are associated with a project, and you can group your projects under an organization.
To implement GCS (Google Cloud Storage) in Micronaut we can use the guide from google itself in this link. Previously we try to use Micronaut GCP integration to wrap the credential but it didn’t work.
Here are the steps to implement GCS using google cloud client library:
Install client library (Gradle)
implementation(platform("com.google.cloud:libraries-bom:25.3.0")) implementation("com.google.cloud:google-cloud-storage")
Prepare GCP credential (In this case using service account, download the json key and store it)
To use the service account json file for GCS credential, simply add the credential file path to environment variable
GOOGLE_APPLICATION_CREDENTIALS
.
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
Then we can use the client library and the credential will automatically resolved.
This code example below will show the attempt to upload an image to GCS bucket
test-safi-dev
and also get signed URL.
package com.safi.cardmanager.service.impl import com.google.cloud.storage.BlobId import com.google.cloud.storage.BlobInfo import com.google.cloud.storage.Storage import com.google.cloud.storage.StorageOptions import com.safi.cardmanager.service.GoogleService import jakarta.inject.Singleton import java.net.URL import java.util.concurrent.TimeUnit @Singleton open class GoogleServiceImpl : GoogleService { private lateinit var storageService: Storage private fun getStorageService(): Storage { if (!::storageService.isInitialized) { val projectId = "acquired-badge-348405" storageService = StorageOptions.newBuilder().setProjectId(projectId).build().service } return storageService } override fun uploadImage(filename: String, fileData: ByteArray) { val bucketName = "test-safi-dev" val storage = getStorageService() val blobId = BlobId.of(bucketName, filename) val blobInfo = BlobInfo.newBuilder(blobId).build() storage.create(blobInfo, fileData) println("File $filename uploaded to bucket $bucketName as $filename") } override fun getImageSignedUrl(filename: String): URL { val bucketName = "test-safi-dev" val storage = getStorageService() val blobId = BlobId.of(bucketName, filename) val blobInfo = BlobInfo.newBuilder(blobId).build() val url = storage.signUrl(blobInfo, 15, TimeUnit.MINUTES, Storage.SignUrlOption.withV4Signature()) println("Generated GET signed URL:"); println(url); println("You can use this URL with any user agent, for example:"); println("curl '$url'"); return url } }