Import AWS SDK for Kotlin
Ensure that Java 11 or a newer version and Gradle are installed.
Add the following code in the dependencies
block of your build.gradle.kts
file
dependencies {
implementation("aws.sdk.kotlin:s3:1.0.50")
implementation("aws.sdk.kotlin:sts:1.0.50")
}
Here's the complete example of the build.gradle.kts
file (Kotlin DSL version) with the com.sufy.s3.examples.App
package:
plugins {
id("org.jetbrains.kotlin.jvm") version "1.9.0"
application
}
repositories {
mavenCentral()
}
dependencies {
implementation("aws.sdk.kotlin:s3:1.0.50")
implementation("aws.sdk.kotlin:sts:1.0.50")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("com.google.guava:guava:32.1.1-jre")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
application {
mainClass.set("com.sufy.s3.examples.AppKt")
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
For each code example that follows,create the code under the app/src/main/kotlin/com/sufy/s3/examples/App.kt
,then execute
gradle run
UploadObject
Client-side upload
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.PutObjectRequest
import aws.sdk.kotlin.services.s3.presigners.presignPutObject
import aws.smithy.kotlin.runtime.net.url.Url
import kotlin.time.Duration.Companion.days
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val putObjectRequest = PutObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
}
val presignedRequest = s3Client.presignPutObject(putObjectRequest, 1.days)
println(presignedRequest.url)
}
This code will generate a pre-signed client-side upload URL, valid for 24 hours, which the client can use to send an PUT request and upload a file within the expiration time.
The following is an example of uploading a file using curl:
curl -X PUT --upload-file "<path/to/file>" "<presigned url>"
Server-side upload
PutObject(file)
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.PutObjectRequest
import aws.smithy.kotlin.runtime.content.ByteStream
import aws.smithy.kotlin.runtime.content.fromFile
import aws.smithy.kotlin.runtime.net.url.Url
import java.io.File
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val putObjectRequest = PutObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
body = ByteStream.fromFile(File("<path/to/upload>"))
}
val presignedResponse = s3Client.putObject(putObjectRequest)
println("ETag: ${presignedResponse.eTag}")
}
PutObject(stream)
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.PutObjectRequest
import aws.smithy.kotlin.runtime.content.ByteStream
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val putObjectRequest = PutObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
body = ByteStream.fromString("Hello from sufy S3!")
}
val presignedResponse = s3Client.putObject(putObjectRequest)
println("ETag: ${presignedResponse.eTag}")
}
MultipartUpload(file)
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.CompleteMultipartUploadRequest
import aws.sdk.kotlin.services.s3.model.CompletedPart
import aws.sdk.kotlin.services.s3.model.CreateMultipartUploadRequest
import aws.sdk.kotlin.services.s3.model.UploadPartRequest
import aws.smithy.kotlin.runtime.content.ByteStream
import aws.smithy.kotlin.runtime.net.url.Url
import java.io.File
import java.util.Vector
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val createMultipartUploadRequest = CreateMultipartUploadRequest {
bucket = "<Bucket>"
key = "<Key>"
}
val createMultipartUploadResponse = s3Client.createMultipartUpload(createMultipartUploadRequest)
val PART_SIZE = 5 * 1024 * 1024 // part size is 5 MB
val partBuf = ByteArray(PART_SIZE)
val completedParts: Vector<CompletedPart> = Vector()
// The example given here is a serial multipart upload. You can modify it to perform a parallel multipart upload to further improve the upload speed.
File("<path/to/upload>").inputStream().buffered().use { file ->
var pn = 1
while (true) {
val haveRead = file.read(partBuf)
if (haveRead <= 0) {
break
}
val uploadPartRequest = UploadPartRequest {
bucket = createMultipartUploadRequest.bucket
key = createMultipartUploadRequest.key
uploadId = createMultipartUploadResponse.uploadId
partNumber = pn
body = ByteStream.fromBytes(partBuf.copyOf(haveRead))
}
val uploadPartResponse = s3Client.uploadPart(uploadPartRequest)
completedParts.add(
CompletedPart {
eTag = uploadPartResponse.eTag
partNumber = pn
}
)
pn++
}
}
val completeMultipartUploadRequest = CompleteMultipartUploadRequest {
bucket = createMultipartUploadRequest.bucket
key = createMultipartUploadRequest.key
uploadId = createMultipartUploadResponse.uploadId
multipartUpload { parts = completedParts }
}
val completeMultipartUploadResponse =
s3Client.completeMultipartUpload(completeMultipartUploadRequest)
println("ETag: ${completeMultipartUploadResponse.eTag}")
}
GetObject
Client-side get object
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.GetObjectRequest
import aws.sdk.kotlin.services.s3.presigners.presignGetObject
import aws.smithy.kotlin.runtime.net.url.Url
import kotlin.time.Duration.Companion.days
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val getObjectRequest = GetObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
}
val presignedRequest = s3Client.presignGetObject(getObjectRequest, 1.days)
println(presignedRequest.url)
}
This code will generate a pre-signed client-side download URL, valid for 24 hours, which the client can use to send an GET request and download the file within the expiration time.
The following is an example of downloading a file using curl:
curl -o "<path/to/download>" "<presigned url>"
Server-side get object
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.GetObjectRequest
import aws.smithy.kotlin.runtime.content.writeToFile
import aws.smithy.kotlin.runtime.net.url.Url
import java.io.File
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val getObjectRequest = GetObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
}
s3Client.getObject(getObjectRequest) { resp ->
resp.body?.writeToFile(File("<path/to/download>"))
println("ETag: ${resp.eTag}")
}
}
ObjectOperations
HeadObject
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.HeadObjectRequest
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val headObjectRequest = HeadObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
}
val headObjectResponse = s3Client.headObject(headObjectRequest)
println("ETag: ${headObjectResponse.eTag}")
}
ChangeStorageClass
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.CopyObjectRequest
import aws.sdk.kotlin.services.s3.model.MetadataDirective
import aws.sdk.kotlin.services.s3.model.StorageClass
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val copyObjectRequest = CopyObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
copySource = "/<Bucket>/<Key>"
storageClass = StorageClass.Glacier
metadataDirective = MetadataDirective.Replace
}
s3Client.copyObject(copyObjectRequest)
println("Done")
}
CopyObject
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.CopyObjectRequest
import aws.sdk.kotlin.services.s3.model.MetadataDirective
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val copyObjectRequest = CopyObjectRequest {
bucket = "<ToBucket>"
key = "<ToKey>"
copySource = "/<FromBucket>/<FromKey>"
metadataDirective = MetadataDirective.Copy
}
s3Client.copyObject(copyObjectRequest)
println("Done")
}
CopyObject(> 5GB)
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.CompleteMultipartUploadRequest
import aws.sdk.kotlin.services.s3.model.CompletedPart
import aws.sdk.kotlin.services.s3.model.CreateMultipartUploadRequest
import aws.sdk.kotlin.services.s3.model.HeadObjectRequest
import aws.sdk.kotlin.services.s3.model.UploadPartCopyRequest
import aws.smithy.kotlin.runtime.net.url.Url
import java.util.Vector
import kotlin.math.min
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val headObjectRequest = HeadObjectRequest {
bucket = "<FromBucket>"
key = "<FromKey>"
}
val headObjectResponse = s3Client.headObject(headObjectRequest)
val createMultipartUploadRequest = CreateMultipartUploadRequest {
bucket = "<ToBucket>"
key = "<ToKey>"
}
val createMultipartUploadResponse = s3Client.createMultipartUpload(createMultipartUploadRequest)
val PART_SIZE = 5 * 1024 * 1024 // part size is 5 MB
val completedParts: Vector<CompletedPart> = Vector()
// The example given here is a serial multipart copy. You can modify it to perform a parallel multipart copy to further improve the copy speed.
var pn = 1
var copied: Long = 0
while (copied < headObjectResponse.contentLength) {
val partSize = min(headObjectResponse.contentLength - copied, PART_SIZE.toLong())
val uploadPartCopyRequest = UploadPartCopyRequest {
bucket = createMultipartUploadRequest.bucket
key = createMultipartUploadRequest.key
uploadId = createMultipartUploadResponse.uploadId
partNumber = pn
copySource = "/${headObjectRequest.bucket}/${headObjectRequest.key}"
copySourceRange = "bytes=${copied}-${copied+partSize}"
}
val uploadPartCopyResponse = s3Client.uploadPartCopy(uploadPartCopyRequest)
completedParts.add(
CompletedPart {
eTag = uploadPartCopyResponse.copyPartResult!!.eTag
partNumber = pn
}
)
pn++
copied += partSize
}
val completeMultipartUploadRequest = CompleteMultipartUploadRequest {
bucket = createMultipartUploadRequest.bucket
key = createMultipartUploadRequest.key
uploadId = createMultipartUploadResponse.uploadId
multipartUpload { parts = completedParts }
}
val completeMultipartUploadResponse =
s3Client.completeMultipartUpload(completeMultipartUploadRequest)
println("ETag: ${completeMultipartUploadResponse.eTag}")
}
DeleteObject
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.DeleteObjectRequest
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val deleteObjectRequest = DeleteObjectRequest {
bucket = "<Bucket>"
key = "<Key>"
}
s3Client.deleteObject(deleteObjectRequest)
println("Done")
}
ListObjects
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.ListObjectsV2Request
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val listObjectsV2Request = ListObjectsV2Request {
bucket = "<Bucket>"
prefix = "<KeyPrefix>"
}
val listObjectsV2Response = s3Client.listObjectsV2(listObjectsV2Request)
for (content in listObjectsV2Response.contents!!) {
println("Key: ${content.key}")
println("ETag: ${content.eTag}")
}
}
DeleteObjects
Create app/src/main/kotlin/com/sufy/s3/examples/App.kt
package com.sufy.s3.examples
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.model.DeleteObjectsRequest
import aws.sdk.kotlin.services.s3.model.ObjectIdentifier
import aws.smithy.kotlin.runtime.net.url.Url
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
val s3Client = S3Client {
credentialsProvider = StaticCredentialsProvider {
accessKeyId = "<AccessKey>"
secretAccessKey = "<SecretKey>"
}
region = "ap-southeast-2" // Asia Pacific (Hanoi) RegionID
endpointUrl = Url.parse("https://mos.ap-southeast-2.sufybkt.com") // Asia Pacific (Hanoi) Endpoint
}
val deleteObjectsRequest = DeleteObjectsRequest {
bucket = "<Bucket>"
delete {
objects =
listOf(
ObjectIdentifier { key = "<Key1>" },
ObjectIdentifier { key = "<Key2>" },
ObjectIdentifier { key = "<Key3>" }
)
}
}
s3Client.deleteObjects(deleteObjectsRequest)
println("Done")
}