diff --git a/build.gradle.kts b/build.gradle.kts index 6d30b75..2be3897 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { `java-library` `maven-publish` - id("org.jmailen.kotlinter") version "2.3.2" + id("org.jmailen.kotlinter") version "2.4.1" id("org.jetbrains.dokka") version "0.10.1" } @@ -19,17 +19,16 @@ repositories { dependencies { val kotlinVersion = "1.3.72" implementation(kotlin("stdlib-jdk8", kotlinVersion)) - implementation(kotlin("reflect", kotlinVersion)) implementation(kotlin("test", kotlinVersion)) implementation(kotlin("test-junit", kotlinVersion)) - val coroutineVersion = "1.3.7" + val coroutineVersion = "1.3.8" implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutineVersion") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutineVersion") - val awsVersion = "2.13.23" + val awsVersion = "[2.13,2.14[" implementation("software.amazon.awssdk:s3:$awsVersion") testImplementation("software.amazon.awssdk:sts:$awsVersion") diff --git a/src/main/kotlin/com/lapanthere/signals/S3InputStream.kt b/src/main/kotlin/com/lapanthere/signals/S3InputStream.kt index f4ea701..7973fa3 100644 --- a/src/main/kotlin/com/lapanthere/signals/S3InputStream.kt +++ b/src/main/kotlin/com/lapanthere/signals/S3InputStream.kt @@ -51,7 +51,8 @@ public class S3InputStream( .bucket(bucket) .key(key) .range("bytes=$begin-$end") - .build(), AsyncResponseTransformer.toBytes() + .build(), + AsyncResponseTransformer.toBytes() ).await().asInputStream() } }.toMutableList() diff --git a/src/main/kotlin/com/lapanthere/signals/S3OutputStream.kt b/src/main/kotlin/com/lapanthere/signals/S3OutputStream.kt index e1a5e16..b85c345 100644 --- a/src/main/kotlin/com/lapanthere/signals/S3OutputStream.kt +++ b/src/main/kotlin/com/lapanthere/signals/S3OutputStream.kt @@ -69,23 +69,26 @@ public class S3OutputStream( semaphore.acquire() partSize.next() val part = Part(uploadID, parts.size + 1, digest, buffer) - parts.add(scope.async(CoroutineName("part-${part.partNumber}")) { - val response = s3.uploadPart( - UploadPartRequest.builder() - .bucket(bucket) - .key(key) - .partNumber(part.partNumber) - .uploadId(uploadID) - .contentMD5(part.contentMD5) - .contentLength(part.buffer.size.toLong()) - .build(), AsyncRequestBody.fromBytes(part.buffer) - ).await() - if (response.eTag != part.eTag) { - throw IOException("mismatching checksum: ${response.eTag} != ${part.eTag}") + parts.add( + scope.async(CoroutineName("part-${part.partNumber}")) { + val response = s3.uploadPart( + UploadPartRequest.builder() + .bucket(bucket) + .key(key) + .partNumber(part.partNumber) + .uploadId(uploadID) + .contentMD5(part.contentMD5) + .contentLength(part.buffer.size.toLong()) + .build(), + AsyncRequestBody.fromBytes(part.buffer) + ).await() + if (response.eTag != part.eTag) { + throw IOException("mismatching checksum: ${response.eTag} != ${part.eTag}") + } + semaphore.release() + part.toCompletedPart() } - semaphore.release() - part.toCompletedPart() - }) + ) buffer.reset() } diff --git a/src/test/kotlin/com/lapanthere/signals/S3InputStreamTest.kt b/src/test/kotlin/com/lapanthere/signals/S3InputStreamTest.kt index 5dcdb1b..5c67596 100644 --- a/src/test/kotlin/com/lapanthere/signals/S3InputStreamTest.kt +++ b/src/test/kotlin/com/lapanthere/signals/S3InputStreamTest.kt @@ -38,7 +38,8 @@ class S3InputStreamTest { .bucket(bucket) .key(key) .range("bytes=0-5242879") - .build(), any>() + .build(), + any>() ) } returns CompletableFuture.completedFuture( ResponseBytes.fromByteArray(GetObjectResponse.builder().build(), ByteArray(32)) @@ -49,7 +50,8 @@ class S3InputStreamTest { .bucket(bucket) .key(key) .range("bytes=5242880-10489185") - .build(), any>() + .build(), + any>() ) } returns CompletableFuture.completedFuture( ResponseBytes.fromByteArray(GetObjectResponse.builder().build(), ByteArray(32)) @@ -77,7 +79,8 @@ class S3InputStreamTest { .bucket(bucket) .key(key) .range("bytes=0-5242879") - .build(), any>() + .build(), + any>() ) } verify(exactly = 1) { @@ -86,7 +89,8 @@ class S3InputStreamTest { .bucket(bucket) .key(key) .range("bytes=5242880-10489185") - .build(), any>() + .build(), + any>() ) } } @@ -99,7 +103,8 @@ class S3InputStreamTest { .bucket(bucket) .key(key) .range("bytes=0-5242879") - .build(), any>() + .build(), + any>() ) } throws SdkClientException.create("read timeout") diff --git a/src/test/kotlin/com/lapanthere/signals/S3OutputStreamTest.kt b/src/test/kotlin/com/lapanthere/signals/S3OutputStreamTest.kt index 384d6e2..15081bd 100644 --- a/src/test/kotlin/com/lapanthere/signals/S3OutputStreamTest.kt +++ b/src/test/kotlin/com/lapanthere/signals/S3OutputStreamTest.kt @@ -48,7 +48,8 @@ class S3OutputStreamTest { .contentLength(32) .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") .partNumber(1) - .build(), any() + .build(), + any() ) } returns CompletableFuture.completedFuture( UploadPartResponse.builder() @@ -103,29 +104,40 @@ class S3OutputStreamTest { } verify { - s3.createMultipartUpload(CreateMultipartUploadRequest.builder() - .bucket(bucket) - .key(key) - .build()) - s3.uploadPart(UploadPartRequest.builder() - .bucket(bucket) - .key(key) - .contentLength(32) - .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") - .partNumber(1) - .uploadId(uploadID) - .build(), any()) - s3.completeMultipartUpload(CompleteMultipartUploadRequest.builder() - .bucket(bucket) - .key(key) - .uploadId(uploadID) - .multipartUpload(CompletedMultipartUpload.builder() - .parts(CompletedPart.builder() - .eTag("70bc8f4b72a86921468bf8e8441dce51") - .partNumber(1) - .build()) - .build()) - .build()) + s3.createMultipartUpload( + CreateMultipartUploadRequest.builder() + .bucket(bucket) + .key(key) + .build() + ) + s3.uploadPart( + UploadPartRequest.builder() + .bucket(bucket) + .key(key) + .contentLength(32) + .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") + .partNumber(1) + .uploadId(uploadID) + .build(), + any() + ) + s3.completeMultipartUpload( + CompleteMultipartUploadRequest.builder() + .bucket(bucket) + .key(key) + .uploadId(uploadID) + .multipartUpload( + CompletedMultipartUpload.builder() + .parts( + CompletedPart.builder() + .eTag("70bc8f4b72a86921468bf8e8441dce51") + .partNumber(1) + .build() + ) + .build() + ) + .build() + ) } verify(exactly = 0) { @@ -152,7 +164,8 @@ class S3OutputStreamTest { .contentLength(32) .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") .partNumber(1) - .build(), any() + .build(), + any() ) } throws SdkClientException.create("write timeout") @@ -165,18 +178,23 @@ class S3OutputStreamTest { } verify { - s3.createMultipartUpload(CreateMultipartUploadRequest.builder() - .bucket(bucket) - .key(key) - .build()) - s3.uploadPart(UploadPartRequest.builder() - .bucket(bucket) - .key(key) - .contentLength(32) - .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") - .partNumber(1) - .uploadId(uploadID) - .build(), any()) + s3.createMultipartUpload( + CreateMultipartUploadRequest.builder() + .bucket(bucket) + .key(key) + .build() + ) + s3.uploadPart( + UploadPartRequest.builder() + .bucket(bucket) + .key(key) + .contentLength(32) + .contentMD5("cLyPS3KoaSFGi/joRB3OUQ==") + .partNumber(1) + .uploadId(uploadID) + .build(), + any() + ) } verify(exactly = 1) {