Skip to content

Commit e0211b1

Browse files
committed
feat: s3 transfer manager
1 parent d276a08 commit e0211b1

File tree

6 files changed

+190
-0
lines changed

6 files changed

+190
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
kotlin {
2+
sourceSets {
3+
commonMain {
4+
dependencies {
5+
implementation(project(":aws-runtime:aws-http"))
6+
implementation(libs.smithy.kotlin.http.client.engine.crt)
7+
api(project(":services:s3"))
8+
}
9+
}
10+
}
11+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package aws.sdk.kotlin.hll.s3transfermanager
2+
3+
import aws.sdk.kotlin.services.s3.S3Client
4+
import aws.sdk.kotlin.services.s3.model.ChecksumAlgorithm
5+
import aws.smithy.kotlin.runtime.http.engine.crt.CrtHttpEngine
6+
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
7+
8+
public fun S3TransferManager(
9+
config: S3TransferManager.Config.Builder.() -> Unit = { },
10+
): S3TransferManager = S3TransferManagerImplementation(S3TransferManager.Config(config))
11+
12+
internal data class S3TransferManagerImplementation(
13+
override val config: S3TransferManager.Config,
14+
) : S3TransferManager {
15+
override fun uploadFile(input: UploadFileRequest): UploadFileResponse {
16+
// TODO: How would this change the config on the fly ?
17+
TODO("Not yet implemented")
18+
}
19+
20+
override fun downloadFile(input: DownloadFileRequest): DownloadFileResponse {
21+
TODO("Not yet implemented")
22+
}
23+
24+
override fun uploadDirectory(input: UploadDirectoryRequest): UploadDirectoryResponse {
25+
TODO("Not yet implemented")
26+
}
27+
28+
override fun downloadDirectory(input: DownloadDirectoryRequest): DownloadDirectoryResponse {
29+
TODO("Not yet implemented")
30+
}
31+
32+
override fun trackTransfer(input: TrackTransferRequest): TrackTransferResponse {
33+
TODO("Not yet implemented")
34+
}
35+
}
36+
37+
internal data class S3TransferManagerConfigImplementation(
38+
override val client: S3Client,
39+
override val interceptors: List<HttpInterceptor>,
40+
override val targetPartSizeBytes: Long,
41+
override val multipartUploadThresholdBytes: Long,
42+
override val checksumValidationEnabled: Boolean,
43+
override val checksumAlgorithm: ChecksumAlgorithm,
44+
override val multipartDownloadType: DownloadType,
45+
) : S3TransferManager.Config {
46+
override fun toBuilder(): S3TransferManager.Config.Builder = S3TransferManager.Config.Builder()
47+
}
48+
49+
internal class S3TransferManagerConfigBuilderImplementation : S3TransferManager.Config.Builder {
50+
override var client: S3Client = S3Client { httpClient = CrtHttpEngine() }
51+
override var interceptors: MutableList<HttpInterceptor> = mutableListOf()
52+
override var targetPartSizeBytes: Long = 8_000_000L
53+
override var multipartUploadThresholdBytes: Long = 16_000_000L
54+
override var checksumValidationEnabled: Boolean = true
55+
override var checksumAlgorithm: ChecksumAlgorithm = ChecksumAlgorithm.Crc32
56+
override var multipartDownloadType: DownloadType = DownloadType.PART
57+
58+
override fun build() = S3TransferManagerConfigImplementation(
59+
client = this.client,
60+
interceptors = this.interceptors,
61+
targetPartSizeBytes = this.targetPartSizeBytes,
62+
multipartUploadThresholdBytes = this.multipartUploadThresholdBytes,
63+
checksumValidationEnabled = this.checksumValidationEnabled,
64+
checksumAlgorithm = this.checksumAlgorithm,
65+
multipartDownloadType = this.multipartDownloadType,
66+
)
67+
}
68+
69+
70+
71+
72+
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
package aws.sdk.kotlin.hll.s3transfermanager
3+
4+
import aws.sdk.kotlin.services.s3.S3Client
5+
import aws.sdk.kotlin.services.s3.model.ChecksumAlgorithm
6+
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
7+
import aws.smithy.kotlin.runtime.io.Closeable
8+
9+
// TODO: Experimental API ?
10+
public interface S3TransferManager: Closeable {
11+
public val config: Config
12+
13+
public companion object {
14+
public fun Config(config: Config.Builder.() -> Unit = { }): Config =
15+
Config.Builder().apply(config).build()
16+
}
17+
18+
public interface Config {
19+
public companion object {
20+
public fun Builder(): Builder = S3TransferManagerConfigBuilderImplementation()
21+
}
22+
23+
public val client: S3Client
24+
public val interceptors: List<HttpInterceptor>
25+
public val targetPartSizeBytes: Long
26+
public val multipartUploadThresholdBytes: Long
27+
public val checksumValidationEnabled: Boolean
28+
public val checksumAlgorithm: ChecksumAlgorithm
29+
public val multipartDownloadType: DownloadType
30+
31+
public fun toBuilder(): Builder
32+
33+
public interface Builder {
34+
public var client: S3Client
35+
public var interceptors: MutableList<HttpInterceptor>
36+
public var targetPartSizeBytes: Long
37+
public var multipartUploadThresholdBytes: Long
38+
public var checksumValidationEnabled: Boolean
39+
public var checksumAlgorithm: ChecksumAlgorithm
40+
public var multipartDownloadType: DownloadType
41+
public fun build(): Config
42+
}
43+
}
44+
45+
// TODO: From environment
46+
47+
public fun uploadFile(input: UploadFileRequest) : UploadFileResponse
48+
public fun downloadFile(input: DownloadFileRequest) : DownloadFileResponse
49+
public fun uploadDirectory(input: UploadDirectoryRequest) : UploadDirectoryResponse
50+
public fun downloadDirectory(input: DownloadDirectoryRequest) : DownloadDirectoryResponse
51+
public fun trackTransfer(input: TrackTransferRequest) : TrackTransferResponse
52+
53+
override fun close() {
54+
config.client.close()
55+
}
56+
}
57+
58+
public enum class DownloadType {
59+
PART,
60+
RANGE,
61+
}
62+
63+
public interface UploadFileRequest
64+
public interface UploadFileResponse
65+
66+
public interface DownloadFileRequest
67+
public interface DownloadFileResponse
68+
69+
public interface UploadDirectoryRequest
70+
public interface UploadDirectoryResponse
71+
72+
public interface DownloadDirectoryRequest
73+
public interface DownloadDirectoryResponse
74+
75+
public interface TrackTransferRequest
76+
public interface TrackTransferResponse
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package aws.sdk.kotlin.hll.s3.transfermanager
2+
3+
class S3TransferManagerBenchmarks {
4+
// TODO: Look at existing benchmarks
5+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package aws.sdk.kotlin.hll.s3.transfermanager
2+
3+
import aws.sdk.kotlin.hll.s3transfermanager.DownloadType
4+
import aws.sdk.kotlin.hll.s3transfermanager.S3TransferManager
5+
import aws.sdk.kotlin.services.s3.S3Client
6+
import aws.sdk.kotlin.services.s3.model.ChecksumAlgorithm
7+
8+
class S3TransferManagerTest {
9+
private val x = S3TransferManager {
10+
client = S3Client {}
11+
interceptors = mutableListOf()
12+
checksumAlgorithm = ChecksumAlgorithm.Crc32
13+
multipartDownloadType = DownloadType.PART
14+
}.uploadFile(
15+
input = TODO()
16+
)
17+
18+
// TODO: Use different HTTP engines and config options
19+
// TODO: Look at tests defined in SEP
20+
}

settings.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ if ("dynamodb".isBootstrappedService) {
8585
logger.warn(":services:dynamodb is not bootstrapped, skipping :hll:dynamodb-mapper and subprojects")
8686
}
8787

88+
if ("s3".isBootstrappedService) {
89+
include(":hll:s3-transfer-manager")
90+
} else {
91+
logger.warn(":services:s3 is not bootstrapped, skipping :hll:s3-transfer-manager and subprojects")
92+
}
93+
8894
// Service benchmarks project
8995
val benchmarkServices = listOf(
9096
// keep this list in sync with tests/benchmarks/service-benchmarks/build.gradle.kts

0 commit comments

Comments
 (0)