MultipartOperations.kt
package io.github.lishangbu.avalon.s3.facade
import software.amazon.awssdk.core.sync.RequestBody
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.AbortMultipartUploadRequest
import software.amazon.awssdk.services.s3.model.AbortMultipartUploadResponse
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadResponse
import software.amazon.awssdk.services.s3.model.CompletedPart
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse
import software.amazon.awssdk.services.s3.model.ListPartsRequest
import software.amazon.awssdk.services.s3.model.ListPartsResponse
import software.amazon.awssdk.services.s3.model.UploadPartRequest
import software.amazon.awssdk.services.s3.model.UploadPartResponse
/** Multipart 上传 facade。 */
class MultipartOperations(
private val s3Client: S3Client,
private val bucketNameResolver: (String) -> String,
) {
/** 创建 multipart 上传。 */
fun create(request: CreateMultipartUploadRequest): CreateMultipartUploadResponse = s3Client.createMultipartUpload(request)
/** 基于桶和 key 创建 multipart 上传。 */
fun create(
bucketName: String,
key: String,
contentType: String? = null,
): CreateMultipartUploadResponse =
create(
CreateMultipartUploadRequest
.builder()
.bucket(resolveBucket(bucketName))
.key(key)
.contentType(contentType)
.build(),
)
/** 上传 part。 */
fun uploadPart(
request: UploadPartRequest,
requestBody: RequestBody,
): UploadPartResponse = s3Client.uploadPart(request, requestBody)
/** 基于桶和 key 上传 part。 */
fun uploadPart(
bucketName: String,
key: String,
uploadId: String,
partNumber: Int,
content: ByteArray,
): UploadPartResponse =
uploadPart(
UploadPartRequest
.builder()
.bucket(resolveBucket(bucketName))
.key(key)
.uploadId(uploadId)
.partNumber(partNumber)
.contentLength(content.size.toLong())
.build(),
RequestBody.fromBytes(content),
)
/** 列出已上传 part。 */
fun listParts(request: ListPartsRequest): ListPartsResponse = s3Client.listParts(request)
/** 列出已上传 part。 */
fun listParts(
bucketName: String,
key: String,
uploadId: String,
): ListPartsResponse =
listParts(
ListPartsRequest
.builder()
.bucket(resolveBucket(bucketName))
.key(key)
.uploadId(uploadId)
.build(),
)
/** 完成 multipart 上传。 */
fun complete(request: CompleteMultipartUploadRequest): CompleteMultipartUploadResponse = s3Client.completeMultipartUpload(request)
/** 基于桶和 key 完成 multipart 上传。 */
fun complete(
bucketName: String,
key: String,
uploadId: String,
completedParts: List<CompletedPart>,
): CompleteMultipartUploadResponse =
complete(
CompleteMultipartUploadRequest
.builder()
.bucket(resolveBucket(bucketName))
.key(key)
.uploadId(uploadId)
.multipartUpload { upload -> upload.parts(completedParts) }
.build(),
)
/** 中止 multipart 上传。 */
fun abort(request: AbortMultipartUploadRequest): AbortMultipartUploadResponse = s3Client.abortMultipartUpload(request)
/** 基于桶和 key 中止 multipart 上传。 */
fun abort(
bucketName: String,
key: String,
uploadId: String,
): AbortMultipartUploadResponse =
abort(
AbortMultipartUploadRequest
.builder()
.bucket(resolveBucket(bucketName))
.key(key)
.uploadId(uploadId)
.build(),
)
private fun resolveBucket(bucketName: String): String = bucketNameResolver(bucketName)
}