AWS SDK

AWS SDK

rev. 2493670155f3f484f4055f00c7816463c1a2ced2..d52e890343dc62eceaad006f54eea929ef91eb0f (ignoring whitespace)

Files changed:

tmp-codegen-diff/services/polly/e2eTest/src/PollyPresignerTest.kt

@@ -1,1 +45,46 @@
    4      4   
 */
    5      5   
package aws.sdk.kotlin.services.polly
    6      6   
    7      7   
import aws.sdk.kotlin.services.polly.model.OutputFormat
    8      8   
import aws.sdk.kotlin.services.polly.model.SynthesizeSpeechRequest
    9      9   
import aws.sdk.kotlin.services.polly.model.VoiceId
   10     10   
import aws.sdk.kotlin.services.polly.presigners.presignSynthesizeSpeech
   11     11   
import aws.sdk.kotlin.testing.withAllEngines
   12     12   
import aws.smithy.kotlin.runtime.http.SdkHttpClient
   13     13   
import aws.smithy.kotlin.runtime.http.complete
          14  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          15  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
   14     16   
import kotlinx.coroutines.runBlocking
   15         -
import org.junit.jupiter.api.TestInstance
   16     17   
import kotlin.test.Test
   17     18   
import kotlin.test.assertEquals
   18     19   
import kotlin.time.Duration.Companion.seconds
   19     20   
   20     21   
/**
   21     22   
 * Tests for presigner
   22     23   
 */
   23         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          24  +
@TestInstance(TestLifecycle.PER_CLASS)
   24     25   
class PollyPresignerTest {
   25     26   
    @Test
   26     27   
    fun clientBasedPresign() = runBlocking {
   27     28   
        val unsignedRequest = SynthesizeSpeechRequest {
   28     29   
            voiceId = VoiceId.Salli
   29     30   
            outputFormat = OutputFormat.Pcm
   30     31   
            text = "hello world"
   31     32   
        }
   32     33   
   33     34   
        val client = PollyClient { region = "us-east-1" }
   34     35   
        val presignedRequest = client.presignSynthesizeSpeech(unsignedRequest, 10.seconds)
   35     36   
   36         -
        withAllEngines { engine ->
   37         -
            val httpClient = SdkHttpClient(engine)
          37  +
        withAllEngines { context ->
          38  +
            val httpClient = SdkHttpClient(context.engine)
   38     39   
   39     40   
            val call = httpClient.call(presignedRequest)
   40     41   
            call.complete()
   41     42   
   42         -
            assertEquals(200, call.response.status.value, "presigned polly request failed for engine: $engine")
          43  +
            assertEquals(200, call.response.status.value, "presigned Polly request failed for ${context.name} engine")
   43     44   
        }
   44     45   
    }
   45     46   
}

tmp-codegen-diff/services/polly/generated-src/main/kotlin/aws/sdk/kotlin/services/polly/PollyClient.kt

@@ -46,46 +106,106 @@
   66     66   
import aws.smithy.kotlin.runtime.telemetry.TelemetryConfig
   67     67   
import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider
   68     68   
import aws.smithy.kotlin.runtime.util.LazyAsyncValue
   69     69   
import kotlin.collections.List
   70     70   
import kotlin.jvm.JvmStatic
   71     71   
import kotlin.time.Duration
   72     72   
import kotlinx.coroutines.runBlocking
   73     73   
   74     74   
   75     75   
public const val ServiceId: String = "Polly"
   76         -
public const val SdkVersion: String = "1.6.48-SNAPSHOT"
          76  +
public const val SdkVersion: String = "1.6.60-SNAPSHOT"
   77     77   
public const val ServiceApiVersion: String = "2016-06-10"
   78     78   
   79     79   
/**
   80     80   
 * Amazon Polly is a web service that makes it easy to synthesize speech from text.
   81     81   
 *
   82     82   
 * The Amazon Polly service provides API operations for synthesizing high-quality speech from plain text and Speech Synthesis Markup Language (SSML), along with managing pronunciations lexicons that enable you to get the best results for your application domain.
   83     83   
 */
   84     84   
public interface PollyClient : SdkClient {
   85     85   
    /**
   86     86   
     * PollyClient's configuration

tmp-codegen-diff/services/s3/build/tmp/jvmJar/MANIFEST.MF

@@ -1,0 +2,0 @@
    1         -
Manifest-Version: 1.0
    2         -

tmp-codegen-diff/services/s3/e2eTest/src/ConnectionResetTest.kt

@@ -1,1 +79,80 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
package aws.sdk.kotlin.e2etest
    6      6   
    7         -
import aws.sdk.kotlin.services.s3.S3Client
    8      7   
import aws.sdk.kotlin.services.s3.model.PutObjectRequest
    9      8   
import aws.smithy.kotlin.runtime.content.ByteStream
   10      9   
import aws.smithy.kotlin.runtime.http.HttpException
   11         -
import aws.smithy.kotlin.runtime.util.Uuid
          10  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          11  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
          12  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          13  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
   12     14   
import kotlinx.coroutines.async
   13     15   
import kotlinx.coroutines.awaitAll
   14     16   
import kotlinx.coroutines.delay
   15         -
import kotlinx.coroutines.invoke
   16     17   
import kotlinx.coroutines.runBlocking
   17         -
import org.junit.jupiter.api.AfterAll
   18         -
import org.junit.jupiter.api.BeforeAll
   19         -
import org.junit.jupiter.api.TestInstance
   20     18   
import java.io.IOException
   21     19   
import kotlin.test.Test
   22     20   
import kotlin.time.Duration.Companion.seconds
   23     21   
   24     22   
/**
   25     23   
 * Reproduces "unexpected end of stream" errors as seen in https://github.com/aws/aws-sdk-kotlin/issues/1214
   26     24   
 * and ensures they are resolved by OkHttp's retryOnConnectionFailure option
   27     25   
 */
   28         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          26  +
@TestInstance(TestLifecycle.PER_CLASS)
   29     27   
class ConnectionResetTest {
   30         -
    private val client = S3Client {
   31         -
        region = S3TestUtils.DEFAULT_REGION
          28  +
    private val client = S3TestUtils.createClient()
          29  +
          30  +
    companion object {
          31  +
        private const val CONN_TEST_CONCURRENCY = 10
   32     32   
    }
   33     33   
   34     34   
    private lateinit var testBucket: String
   35     35   
   36     36   
    @BeforeAll
   37     37   
    fun createResources(): Unit = runBlocking {
   38         -
        testBucket = S3TestUtils.getTestBucket(client)
          38  +
        testBucket = S3TestUtils.createTestBucket(client, "conn-reset")
   39     39   
    }
   40     40   
   41     41   
    @AfterAll
   42     42   
    fun cleanup() = runBlocking {
   43         -
        S3TestUtils.deleteBucketAndAllContents(client, testBucket)
          43  +
        S3TestUtils.deleteBucket(client, testBucket)
          44  +
        client.close()
   44     45   
    }
   45     46   
   46     47   
    @Test
   47     48   
    fun testConnectionResetDoesntThrow(): Unit = runBlocking {
   48     49   
        // Launch multiple coroutines to populate connection pool
   49         -
        val jobs = (1..10).map {
   50         -
            async { client.putTestObject() }
          50  +
        val jobs = (1..CONN_TEST_CONCURRENCY).map { index ->
          51  +
            async { putTestObject(index) }
   51     52   
        }
   52     53   
        jobs.awaitAll()
   53     54   
        // Connections are now idle in the pool
   54     55   
   55     56   
        // Wait for S3 to close stale connections
   56     57   
        delay(7.seconds)
   57     58   
   58     59   
        // Try to re-use a connection
   59         -
        client.putTestObject()
          60  +
        putTestObject(CONN_TEST_CONCURRENCY + 1)
   60     61   
    }
   61     62   
   62         -
    suspend fun S3Client.putTestObject() {
          63  +
    suspend fun putTestObject(index: Int) {
   63     64   
        val putObjectRequest = PutObjectRequest {
   64     65   
            bucket = testBucket
   65         -
            key = Uuid.random().toString()
          66  +
            key = "conn-reset-test-object-$index"
   66     67   
            body = ByteStream.fromString("Content")
   67     68   
        }
   68     69   
   69     70   
        try {
   70     71   
            client.putObject(putObjectRequest)
   71     72   
        } catch (e: HttpException) {
   72     73   
            if (e.cause is IOException && e.cause?.message?.contains("unexpected end of stream") == true) {
   73     74   
                throw RetryOnConnectionFailureException("SDK unexpectedly threw java.io.IOException which should have been retried by OkHttp's retryOnConnectionFailure feature", e)
   74     75   
            }
   75     76   
        }

tmp-codegen-diff/services/s3/e2eTest/src/MultiRegionAccessPointTest.kt

@@ -1,1 +136,148 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
package aws.sdk.kotlin.e2etest
    6      6   
    7         -
import aws.sdk.kotlin.e2etest.S3TestUtils.deleteBucketAndAllContents
    8         -
import aws.sdk.kotlin.e2etest.S3TestUtils.getAccountId
    9         -
import aws.sdk.kotlin.e2etest.S3TestUtils.getBucketWithPrefix
   10      7   
import aws.sdk.kotlin.services.s3.S3Client
   11      8   
import aws.sdk.kotlin.services.s3.deleteObject
   12      9   
import aws.sdk.kotlin.services.s3.putObject
   13     10   
import aws.sdk.kotlin.services.s3.withConfig
   14         -
import aws.sdk.kotlin.services.s3control.S3ControlClient
   15         -
import aws.sdk.kotlin.services.s3control.createMultiRegionAccessPoint
   16         -
import aws.sdk.kotlin.services.s3control.deleteMultiRegionAccessPoint
   17         -
import aws.sdk.kotlin.services.s3control.describeMultiRegionAccessPointOperation
   18         -
import aws.sdk.kotlin.services.s3control.getMultiRegionAccessPoint
          11  +
import aws.sdk.kotlin.services.s3control.*
   19     12   
import aws.sdk.kotlin.services.s3control.model.Region
   20         -
import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigner
          13  +
import aws.sdk.kotlin.services.s3control.paginators.listMultiRegionAccessPointsPaginated
   21     14   
import aws.smithy.kotlin.runtime.auth.awssigning.DefaultAwsSigner
   22     15   
import aws.smithy.kotlin.runtime.auth.awssigning.crt.CrtAwsSigner
   23     16   
import aws.smithy.kotlin.runtime.http.auth.SigV4AsymmetricAuthScheme
          17  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          18  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
          19  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          20  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
          21  +
import aws.smithy.kotlin.runtime.testing.parameterized
   24     22   
import kotlinx.coroutines.delay
          23  +
import kotlinx.coroutines.flow.toList
   25     24   
import kotlinx.coroutines.runBlocking
   26     25   
import kotlinx.coroutines.withTimeout
   27         -
import org.junit.jupiter.api.AfterAll
   28         -
import org.junit.jupiter.api.BeforeAll
   29         -
import org.junit.jupiter.api.TestInstance
   30         -
import org.junit.jupiter.params.ParameterizedTest
   31         -
import org.junit.jupiter.params.provider.Arguments
   32         -
import org.junit.jupiter.params.provider.MethodSource
   33         -
import java.util.stream.Stream
   34         -
import kotlin.random.Random
          26  +
import kotlin.test.Test
   35     27   
import kotlin.time.Duration
   36     28   
import kotlin.time.Duration.Companion.minutes
   37     29   
import kotlin.time.Duration.Companion.seconds
   38     30   
   39         -
private const val MRAP_BUCKET_PREFIX = "s3-mrap-test-bucket-"
   40         -
private val MULTI_REGION_ACCESS_POINT_NAME = "aws-sdk-for-kotlin-mrap-${Random.nextInt(0, 9999)}"
   41     31   
private const val TEST_OBJECT_KEY = "test.txt"
   42     32   
   43         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
   44         -
class MutliRegionAccessPointTest {
          33  +
@TestInstance(TestLifecycle.PER_CLASS)
          34  +
class MultiRegionAccessPointTest {
   45     35   
    private lateinit var s3West: S3Client
   46     36   
    private lateinit var s3East: S3Client
   47     37   
    private lateinit var s3Control: S3ControlClient
   48     38   
   49     39   
    private lateinit var accountId: String
          40  +
    private lateinit var multiRegionAccessPointName: String
   50     41   
    private lateinit var multiRegionAccessPointArn: String
   51     42   
    private lateinit var usWestBucket: String
   52     43   
    private lateinit var usEastBucket: String
   53     44   
   54     45   
    @BeforeAll
   55     46   
    fun setup(): Unit = runBlocking {
   56         -
        s3West = S3Client { region = "us-west-2" }
   57         -
        s3East = S3Client { region = "us-east-2" }
          47  +
        s3West = S3TestUtils.createClient { region = "us-west-2" }
          48  +
        s3East = S3TestUtils.createClient { region = "us-east-2" }
   58     49   
        s3Control = S3ControlClient { region = "us-west-2" }
   59     50   
   60         -
        accountId = getAccountId()
   61         -
        usWestBucket = getBucketWithPrefix(s3West, MRAP_BUCKET_PREFIX, "us-west-2", accountId)
   62         -
        usEastBucket = getBucketWithPrefix(s3East, MRAP_BUCKET_PREFIX, "us-east-2", accountId)
          51  +
        accountId = S3TestUtils.getAccountId()
          52  +
        usWestBucket = S3TestUtils.createTestBucket(s3West, "mrap-west")
          53  +
        usEastBucket = S3TestUtils.createTestBucket(s3East, "mrap-east")
   63     54   
          55  +
        multiRegionAccessPointName = "s3-test-mrap-${S3TestUtils.testRunId}"
   64     56   
        multiRegionAccessPointArn = s3Control.createMultiRegionAccessPoint(
   65         -
            MULTI_REGION_ACCESS_POINT_NAME,
          57  +
            multiRegionAccessPointName,
   66     58   
            accountId,
   67     59   
            listOf(usWestBucket, usEastBucket),
   68     60   
        )
   69     61   
    }
   70     62   
   71     63   
    @AfterAll
   72     64   
    fun cleanup(): Unit = runBlocking {
   73         -
        s3Control.deleteMultiRegionAccessPoint(MULTI_REGION_ACCESS_POINT_NAME, accountId)
          65  +
        s3Control.deleteMultiRegionAccessPoint(multiRegionAccessPointName, accountId)
   74     66   
   75         -
        deleteBucketAndAllContents(s3West, usWestBucket)
   76         -
        deleteBucketAndAllContents(s3East, usEastBucket)
          67  +
        val resp = s3Control.listMultiRegionAccessPointsPaginated {
          68  +
            accountId = this@MultiRegionAccessPointTest.accountId
          69  +
        }.toList().flatMap { it.accessPoints.orEmpty() }
          70  +
          71  +
        val mrapManifest = buildString {
          72  +
            appendLine("Existing multi-region access points for account ID $accountId (${resp.size}):")
          73  +
            resp.forEach { accessPoint ->
          74  +
                appendLine("* ${accessPoint.name}:")
          75  +
                appendLine("  * Alias: ${accessPoint.alias}")
          76  +
                appendLine("  * Created: ${accessPoint.createdAt}")
          77  +
                appendLine("  * Status: ${accessPoint.status}")
          78  +
          79  +
                val regions = accessPoint.regions.orEmpty()
          80  +
                appendLine("  * Regions (${regions.size}):")
          81  +
          82  +
                regions.forEach { region ->
          83  +
                    appendLine("    * ${region.region}: ${region.bucket} (account ID ${region.bucketAccountId})")
          84  +
                }
          85  +
            }
          86  +
        }
          87  +
        print(mrapManifest)
          88  +
          89  +
        S3TestUtils.deleteBucket(s3West, usWestBucket)
          90  +
        S3TestUtils.deleteBucket(s3East, usEastBucket)
   77     91   
   78     92   
        s3West.close()
   79     93   
        s3East.close()
   80     94   
        s3Control.close()
   81     95   
    }
   82     96   
   83         -
    @ParameterizedTest
   84         -
    @MethodSource("signerProvider")
   85         -
    fun testMultiRegionAccessPointOperation(signer: AwsSigner): Unit = runBlocking {
          97  +
    @Test
          98  +
    fun testMultiRegionAccessPointOperation(): Unit = parameterized(
          99  +
        listOf(DefaultAwsSigner, CrtAwsSigner),
         100  +
    ) { signer ->
         101  +
        runBlocking {
   86    102   
            println("Testing multi-region access point operations with $signer")
   87    103   
   88    104   
            val s3SigV4a = s3West.withConfig {
   89    105   
                authSchemes = listOf(SigV4AsymmetricAuthScheme(signer))
   90    106   
            }
   91    107   
   92    108   
            s3SigV4a.putObject {
   93    109   
                bucket = multiRegionAccessPointArn
   94    110   
                key = TEST_OBJECT_KEY
   95    111   
            }
   96    112   
   97    113   
            s3SigV4a.deleteObject {
   98    114   
                bucket = multiRegionAccessPointArn
   99    115   
                key = TEST_OBJECT_KEY
  100    116   
            }
  101    117   
        }
  102         -
  103         -
    fun signerProvider(): Stream<Arguments> = Stream.of(
  104         -
        Arguments.of(DefaultAwsSigner),
  105         -
        Arguments.of(CrtAwsSigner),
  106         -
    )
         118  +
    }
  107    119   
}
  108    120   
  109    121   
/**
  110    122   
 * Create a multi-region access point named [name] in account [accountId] with [buckets] buckets.
  111    123   
 * @return the ARN of the multi-region access point that was created
  112    124   
 */
  113    125   
private suspend fun S3ControlClient.createMultiRegionAccessPoint(
  114    126   
    name: String,
  115    127   
    accountId: String,
  116    128   
    buckets: List<String>,

tmp-codegen-diff/services/s3/e2eTest/src/PaginatorTest.kt

@@ -1,1 +70,69 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
package aws.sdk.kotlin.e2etest
    6      6   
    7         -
import aws.sdk.kotlin.services.s3.S3Client
    8      7   
import aws.sdk.kotlin.services.s3.abortMultipartUpload
    9      8   
import aws.sdk.kotlin.services.s3.createMultipartUpload
   10      9   
import aws.sdk.kotlin.services.s3.model.CompletedPart
   11     10   
import aws.sdk.kotlin.services.s3.paginators.listPartsPaginated
   12     11   
import aws.sdk.kotlin.services.s3.uploadPart
   13     12   
import aws.smithy.kotlin.runtime.content.ByteStream
          13  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          14  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
          15  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          16  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
   14     17   
import kotlinx.coroutines.flow.toList
   15     18   
import kotlinx.coroutines.flow.transform
   16     19   
import kotlinx.coroutines.runBlocking
   17     20   
import kotlinx.coroutines.withTimeout
   18         -
import org.junit.jupiter.api.AfterAll
   19         -
import org.junit.jupiter.api.BeforeAll
   20         -
import org.junit.jupiter.api.Test
   21         -
import org.junit.jupiter.api.TestInstance
          21  +
import kotlin.test.Test
   22     22   
import kotlin.test.assertContentEquals
   23     23   
import kotlin.time.Duration.Companion.seconds
   24     24   
   25         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          25  +
@TestInstance(TestLifecycle.PER_CLASS)
   26     26   
class PaginatorTest {
   27         -
    private val client = S3Client {
   28         -
        region = S3TestUtils.DEFAULT_REGION
   29         -
    }
          27  +
    private val client = S3TestUtils.createClient()
   30     28   
   31     29   
    private lateinit var testBucket: String
   32     30   
   33     31   
    @BeforeAll
   34     32   
    fun createResources(): Unit = runBlocking {
   35         -
        testBucket = S3TestUtils.getTestBucket(client)
          33  +
        testBucket = S3TestUtils.createTestBucket(client, "pagination")
   36     34   
    }
   37     35   
   38     36   
    @AfterAll
   39     37   
    fun cleanup() = runBlocking {
   40         -
        S3TestUtils.deleteBucketAndAllContents(client, testBucket)
          38  +
        S3TestUtils.deleteBucket(client, testBucket)
          39  +
        client.close()
   41     40   
    }
   42     41   
   43     42   
    // ListParts has a strange pagination termination condition via [IsTerminated]. Verify it actually works correctly.
   44     43   
    @Test
   45     44   
    fun testListPartsPagination() = runBlocking {
   46     45   
        val chunk = "!".repeat(5 * 1024 * 1024).encodeToByteArray() // Parts must be at least 5MB
   47     46   
        val expectedParts = (1..10).toList()
   48     47   
   49     48   
        val id = client.createMultipartUpload {
   50     49   
            bucket = testBucket

tmp-codegen-diff/services/s3/e2eTest/src/S3ChecksumTest.kt

@@ -1,1 +198,197 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
    6      6   
package aws.sdk.kotlin.e2etest
    7      7   
    8         -
import aws.sdk.kotlin.e2etest.S3TestUtils.deleteBucketContents
    9         -
import aws.sdk.kotlin.e2etest.S3TestUtils.deleteMultiPartUploads
   10         -
import aws.sdk.kotlin.e2etest.S3TestUtils.getAccountId
   11         -
import aws.sdk.kotlin.e2etest.S3TestUtils.getTestBucket
   12         -
import aws.sdk.kotlin.e2etest.S3TestUtils.responseCodeFromPut
   13      8   
import aws.sdk.kotlin.services.s3.*
   14      9   
import aws.sdk.kotlin.services.s3.model.*
   15     10   
import aws.sdk.kotlin.services.s3.presigners.presignPutObject
   16     11   
import aws.smithy.kotlin.runtime.content.*
   17     12   
import aws.smithy.kotlin.runtime.hashing.crc32
          13  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          14  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
   18     15   
import aws.smithy.kotlin.runtime.testing.RandomTempFile
          16  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          17  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
          18  +
import kotlinx.coroutines.async
          19  +
import kotlinx.coroutines.awaitAll
   19     20   
import kotlinx.coroutines.runBlocking
   20         -
import org.junit.jupiter.api.*
   21     21   
import java.io.File
   22     22   
import java.io.FileInputStream
   23     23   
import java.util.*
          24  +
import kotlin.test.Test
   24     25   
import kotlin.test.assertEquals
   25     26   
import kotlin.test.assertFalse
   26     27   
import kotlin.test.assertTrue
   27     28   
import kotlin.time.Duration.Companion.seconds
   28     29   
   29         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          30  +
@TestInstance(TestLifecycle.PER_CLASS)
   30     31   
class S3ChecksumTest {
   31         -
    private val client = S3Client { region = "us-west-2" }
          32  +
    private val client = S3TestUtils.createClient()
   32     33   
    private lateinit var testBucket: String
   33         -
    private fun testKey(): String = "test-object" + UUID.randomUUID()
          34  +
    private fun testKey(suffix: String): String = "test-object-$suffix"
   34     35   
   35     36   
    @BeforeAll
   36     37   
    private fun setUp(): Unit = runBlocking {
   37         -
        val accountId = getAccountId()
   38         -
        testBucket = getTestBucket(client, "us-west-2", accountId)
          38  +
        testBucket = S3TestUtils.createTestBucket(client, "checksums")
   39     39   
    }
   40     40   
   41     41   
    @AfterAll
   42     42   
    private fun cleanUp(): Unit = runBlocking {
   43         -
        deleteMultiPartUploads(client, testBucket)
   44         -
        deleteBucketContents(client, testBucket)
          43  +
        S3TestUtils.deleteBucket(client, testBucket)
   45     44   
        client.close()
   46     45   
    }
   47     46   
   48     47   
    @Test
   49     48   
    fun testPutObject(): Unit = runBlocking {
   50     49   
        val testBody = "Hello World"
   51         -
        val testKey = testKey()
          50  +
        val testKey = testKey("basic")
   52     51   
   53     52   
        client.putObject {
   54     53   
            bucket = testBucket
   55     54   
            key = testKey
   56     55   
            body = ByteStream.fromString(testBody)
   57     56   
        }
   58     57   
   59     58   
        client.getObject(
   60     59   
            GetObjectRequest {
   61     60   
                bucket = testBucket
   62     61   
                key = testKey
   63     62   
            },
   64     63   
        ) { actual ->
   65     64   
            assertEquals(testBody, actual.body?.decodeToString() ?: "")
   66     65   
        }
   67     66   
    }
   68     67   
   69     68   
    @Test
   70     69   
    fun testPutObjectWithEmptyBody(): Unit = runBlocking {
   71         -
        val testKey = testKey()
          70  +
        val testKey = testKey("empty")
   72     71   
        val testBody = ""
   73     72   
   74     73   
        client.putObject {
   75     74   
            bucket = testBucket
   76     75   
            key = testKey
   77     76   
        }
   78     77   
   79     78   
        client.getObject(
   80     79   
            GetObjectRequest {
   81     80   
                bucket = testBucket
   82     81   
                key = testKey
   83     82   
            },
   84     83   
        ) { actual ->
   85     84   
            assertEquals(testBody, actual.body?.decodeToString() ?: "")
   86     85   
        }
   87     86   
    }
   88     87   
   89     88   
    @Test
   90     89   
    fun testPutObjectAwsChunkedEncoded(): Unit = runBlocking {
   91         -
        val testKey = testKey()
          90  +
        val testKey = testKey("chunked")
   92     91   
        val testBody = "Hello World"
   93     92   
   94     93   
        val tempFile = File.createTempFile("test", ".txt").also {
   95     94   
            it.writeText(testBody)
   96     95   
            it.deleteOnExit()
   97     96   
        }
   98     97   
        val inputStream = FileInputStream(tempFile)
   99     98   
  100     99   
        client.putObject {
  101    100   
            bucket = testBucket
  102    101   
            key = testKey
  103    102   
            body = ByteStream.fromInputStream(inputStream, testBody.length.toLong())
  104    103   
        }
  105    104   
  106    105   
        client.getObject(
  107    106   
            GetObjectRequest {
  108    107   
                bucket = testBucket
  109    108   
                key = testKey
  110    109   
            },
  111    110   
        ) { actual ->
  112    111   
            assertEquals(testBody, actual.body?.decodeToString() ?: "")
  113    112   
        }
  114    113   
    }
  115    114   
  116    115   
    @Test
  117    116   
    fun testMultiPartUpload(): Unit = runBlocking {
  118         -
        val testKey = testKey()
         117  +
        val testKey = testKey("multipart")
  119    118   
  120    119   
        val partSize = 5 * 1024 * 1024 // 5 MB - min part size
  121    120   
        val contentSize: Long = 8 * 1024 * 1024 // 2 parts
  122    121   
        val file = RandomTempFile(sizeInBytes = contentSize)
  123    122   
  124    123   
        val expectedChecksum = file.readBytes().crc32()
  125    124   
  126    125   
        val testUploadId = client.createMultipartUpload {
  127    126   
            bucket = testBucket
  128    127   
            key = testKey
  129    128   
        }.uploadId
  130    129   
  131         -
        val uploadedParts = file.chunk(partSize).mapIndexed { index, chunk ->
         130  +
        val uploadedParts = file.chunk(partSize).toList().mapIndexed { index, chunk ->
  132    131   
            val adjustedIndex = index + 1 // index starts from 0 but partNumber needs to start from 1
  133    132   
  134         -
            runBlocking {
         133  +
            async {
  135    134   
                client.uploadPart {
  136    135   
                    bucket = testBucket
  137    136   
                    key = testKey
  138    137   
                    partNumber = adjustedIndex
  139    138   
                    uploadId = testUploadId
  140    139   
                    body = file.asByteStream(chunk)
  141    140   
                }.let {
  142    141   
                    CompletedPart {
  143    142   
                        partNumber = adjustedIndex
  144    143   
                        eTag = it.eTag
  145    144   
                    }
  146    145   
                }
  147    146   
            }
  148         -
        }.toList()
         147  +
        }.awaitAll()
  149    148   
  150    149   
        client.completeMultipartUpload {
  151    150   
            bucket = testBucket
  152    151   
            key = testKey
  153    152   
            uploadId = testUploadId
  154    153   
            multipartUpload = CompletedMultipartUpload {
  155    154   
                parts = uploadedParts
  156    155   
            }
  157    156   
        }
  158    157   
  159    158   
        client.getObject(
  160    159   
            GetObjectRequest {
  161    160   
                bucket = testBucket
  162    161   
                key = testKey
  163    162   
            },
  164    163   
        ) { actual ->
  165    164   
            val actualChecksum = actual.body!!.toByteArray().crc32()
  166    165   
            assertEquals(actualChecksum, expectedChecksum)
  167    166   
        }
  168    167   
    }
  169    168   
  170    169   
    @Test
  171    170   
    fun testPresignedUrlNoDefault() = runBlocking {
  172    171   
        val contents = "presign-test"
  173    172   
  174    173   
        val unsignedPutRequest = PutObjectRequest {
  175    174   
            bucket = testBucket
  176         -
            key = testKey()
         175  +
            key = testKey("presigned-auto-checksum")
  177    176   
        }
  178    177   
        val presignedPutRequest = client.presignPutObject(unsignedPutRequest, 60.seconds)
  179    178   
  180    179   
        assertFalse(presignedPutRequest.url.toString().contains("x-amz-checksum-crc32"))
  181         -
        assertTrue(responseCodeFromPut(presignedPutRequest, contents) in 200..299)
         180  +
        assertTrue(S3TestUtils.responseCodeFromPut(presignedPutRequest, contents) in 200..299)
  182    181   
    }
  183    182   
  184    183   
    @Test
  185    184   
    fun testPresignedUrlChecksumValue() = runBlocking {
  186    185   
        val contents = "presign-test"
  187    186   
  188    187   
        val unsignedPutRequest = PutObjectRequest {
  189    188   
            bucket = testBucket
  190         -
            key = testKey()
         189  +
            key = testKey("presigned-provided-checksum")
  191    190   
            checksumCrc32 = "dBBx+Q=="
  192    191   
        }
  193    192   
        val presignedPutRequest = client.presignPutObject(unsignedPutRequest, 60.seconds)
  194    193   
  195    194   
        assertTrue(presignedPutRequest.url.toString().contains("x-amz-checksum-crc32"))
  196         -
        assertTrue(responseCodeFromPut(presignedPutRequest, contents) in 200..299)
         195  +
        assertTrue(S3TestUtils.responseCodeFromPut(presignedPutRequest, contents) in 200..299)
  197    196   
    }
  198    197   
}

tmp-codegen-diff/services/s3/e2eTest/src/S3ExpressTest.kt

@@ -1,1 +169,166 @@
    6      6   
    7      7   
import aws.sdk.kotlin.services.s3.*
    8      8   
import aws.sdk.kotlin.services.s3.express.S3_EXPRESS_SESSION_TOKEN_HEADER
    9      9   
import aws.sdk.kotlin.services.s3.model.*
   10     10   
import aws.sdk.kotlin.services.s3.presigners.presignPutObject
   11     11   
import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
   12     12   
import aws.smithy.kotlin.runtime.content.ByteStream
   13     13   
import aws.smithy.kotlin.runtime.content.decodeToString
   14     14   
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
   15     15   
import aws.smithy.kotlin.runtime.http.request.HttpRequest
          16  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          17  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
          18  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          19  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
   16     20   
import kotlinx.coroutines.runBlocking
   17         -
import kotlinx.coroutines.test.runTest
   18         -
import org.junit.jupiter.api.AfterAll
   19         -
import org.junit.jupiter.api.BeforeAll
   20         -
import org.junit.jupiter.api.TestInstance
   21     21   
import kotlin.test.*
   22     22   
import kotlin.time.Duration.Companion.minutes
   23     23   
   24     24   
/**
   25     25   
 * Tests for S3 Express operations
   26     26   
 */
   27         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          27  +
@TestInstance(TestLifecycle.PER_CLASS)
   28     28   
class S3ExpressTest {
   29         -
    private val client = S3Client {
   30         -
        region = S3TestUtils.DEFAULT_REGION
          29  +
    companion object {
          30  +
        private const val AVAILABILITY_ZONE = "usw2-az1" // us-west-2 availability zone 1
   31     31   
    }
   32     32   
   33         -
    private val testBuckets: MutableList<String> = mutableListOf()
          33  +
    private val client = S3TestUtils.createClient()
          34  +
          35  +
    private lateinit var testBuckets: List<String>
   34     36   
   35     37   
    @BeforeAll
   36     38   
    fun setup(): Unit = runBlocking {
   37         -
        val suffix = "--usw2-az1--x-s3" // us-west-2 availability zone 1
   38         -
   39     39   
        // create a few test buckets to test the credentials cache
   40         -
        testBuckets.add(S3TestUtils.getTestDirectoryBucket(client, suffix))
   41         -
        testBuckets.add(S3TestUtils.getTestDirectoryBucket(client, suffix))
   42         -
        testBuckets.add(S3TestUtils.getTestDirectoryBucket(client, suffix))
          40  +
        testBuckets = (1..3).map { index ->
          41  +
            S3TestUtils.createTestDirectoryBucket(client, AVAILABILITY_ZONE, index.toString())
          42  +
        }
   43     43   
    }
   44     44   
   45     45   
    @AfterAll
   46     46   
    fun cleanup(): Unit = runBlocking {
   47         -
        testBuckets.forEach { bucket ->
   48         -
            S3TestUtils.deleteMultiPartUploads(client, bucket)
   49         -
            S3TestUtils.deleteBucketAndAllContents(client, bucket)
   50         -
        }
          47  +
        testBuckets.forEach { bucket -> S3TestUtils.deleteBucket(client, bucket) }
   51     48   
        client.close()
   52     49   
    }
   53     50   
   54     51   
    @Test
   55         -
    fun testPutObject() = runTest {
          52  +
    fun testPutObject() = runBlocking {
   56     53   
        val content = "30 minutes, or it's free!"
   57     54   
        val keyName = "express.txt"
   58     55   
   59     56   
        testBuckets.forEach { bucketName ->
   60     57   
            val trackingInterceptor = S3ExpressInvocationTrackingInterceptor()
   61     58   
            client.withConfig {
   62     59   
                interceptors += trackingInterceptor
   63     60   
            }.use { trackingClient ->
   64     61   
                trackingClient.putObject {
   65     62   
                    bucket = bucketName
   66     63   
                    key = keyName
   67     64   
                    body = ByteStream.fromString(content)
   68     65   
                }
   69     66   
   70     67   
                val req = GetObjectRequest {
   71     68   
                    bucket = bucketName
   72     69   
                    key = keyName
   73     70   
                }
   74     71   
   75     72   
                val respContent = client.getObject(req) {
   76     73   
                    it.body?.decodeToString()
   77     74   
                }
   78     75   
   79     76   
                assertEquals(content, respContent)
   80     77   
                assertEquals(1, trackingInterceptor.s3ExpressInvocations)
   81     78   
            }
   82     79   
        }
   83     80   
    }
   84     81   
   85     82   
    @Ignore
   86     83   
    @Test
   87         -
    fun testPresignedPutObject() = runTest {
          84  +
    fun testPresignedPutObject() = runBlocking {
   88     85   
        val content = "Presign this!"
   89     86   
        val keyName = "express-presigned.txt"
   90     87   
   91     88   
        testBuckets.forEach { bucketName ->
   92     89   
            val presigned = client.presignPutObject(
   93     90   
                PutObjectRequest {
   94     91   
                    bucket = bucketName
   95     92   
                    key = keyName
   96     93   
                    body = ByteStream.fromString(content)
   97     94   
                },
   98     95   
                5.minutes,
   99     96   
            )
  100     97   
  101     98   
            // FIXME Presigned requests should use S3 Express Auth Scheme resulting in `X-Amz-S3session-Token`
  102     99   
            // https://github.com/awslabs/aws-sdk-kotlin/issues/1236
  103    100   
            assertTrue(presigned.url.parameters.decodedParameters.contains(S3_EXPRESS_SESSION_TOKEN_HEADER))
  104    101   
        }
  105    102   
    }
  106    103   
  107    104   
    @Test
  108         -
    fun testChecksums() = runTest {
         105  +
    fun testChecksums() = runBlocking {
  109    106   
        val bucketName = testBuckets.first() // only need one bucket for this test
  110    107   
  111    108   
        val keysToDelete = listOf("checksums.txt", "delete-me.txt", "dont-forget-about-me.txt")
  112    109   
        keysToDelete.forEach {
  113    110   
            client.putObject {
  114    111   
                bucket = bucketName
  115    112   
                key = it
  116    113   
                body = ByteStream.fromString("Check out these sums!")
  117    114   
            }
  118    115   
        }
  119    116   
  120    117   
        client.withConfig {
  121    118   
            interceptors += CRC32ChecksumValidatingInterceptor()
  122    119   
        }.use { validatingClient ->
  123    120   
            // s3:DeleteObjects requires a checksum, even if the user doesn't specify one.
  124    121   
            // normally the SDK would default to MD5, but S3 Express must default to CRC32 instead.
  125    122   
            val req = DeleteObjectsRequest {
  126    123   
                bucket = bucketName
  127    124   
                delete = Delete {
  128    125   
                    objects = keysToDelete.map {
  129    126   
                        ObjectIdentifier { key = it }
  130    127   
                    }
  131    128   
                }
  132    129   
            }
  133    130   
  134    131   
            validatingClient.deleteObjects(req)
  135    132   
        }
  136    133   
    }
  137    134   
  138    135   
    @Test
  139         -
    fun testUploadPartContainsCRC32Checksum() = runTest {
         136  +
    fun testUploadPartContainsCRC32Checksum() = runBlocking {
  140    137   
        val testBucket = testBuckets.first()
  141    138   
        val testObject = "I-will-be-uploaded-in-parts-!"
  142    139   
  143    140   
        // Parts need to be at least 5 MB
  144    141   
        val partOne = "Hello".repeat(1_048_576)
  145    142   
        val partTwo = "World".repeat(1_048_576)
  146    143   
  147    144   
        val testUploadId = client.createMultipartUpload {
  148    145   
            bucket = testBucket
  149    146   
            key = testObject

tmp-codegen-diff/services/s3/e2eTest/src/S3IntegrationTest.kt

@@ -1,1 +83,79 @@
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
package aws.sdk.kotlin.e2etest
    6      6   
    7      7   
import aws.sdk.kotlin.services.s3.*
    8      8   
import aws.sdk.kotlin.services.s3.model.*
    9      9   
import aws.sdk.kotlin.testing.PRINTABLE_CHARS
   10     10   
import aws.sdk.kotlin.testing.withAllEngines
   11     11   
import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
   12         -
import aws.smithy.kotlin.runtime.content.ByteStream
   13         -
import aws.smithy.kotlin.runtime.content.asByteStream
   14         -
import aws.smithy.kotlin.runtime.content.decodeToString
   15         -
import aws.smithy.kotlin.runtime.content.fromFile
   16         -
import aws.smithy.kotlin.runtime.content.toByteArray
   17         -
import aws.smithy.kotlin.runtime.content.toByteStream
          12  +
import aws.smithy.kotlin.runtime.content.*
   18     13   
import aws.smithy.kotlin.runtime.hashing.sha256
   19     14   
import aws.smithy.kotlin.runtime.http.HttpException
   20     15   
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
   21     16   
import aws.smithy.kotlin.runtime.http.request.HttpRequest
          17  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          18  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
   22     19   
import aws.smithy.kotlin.runtime.testing.RandomTempFile
          20  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          21  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
   23     22   
import aws.smithy.kotlin.runtime.text.encoding.encodeToHex
   24         -
import kotlinx.coroutines.*
          23  +
import kotlinx.coroutines.async
          24  +
import kotlinx.coroutines.awaitAll
   25     25   
import kotlinx.coroutines.flow.flow
   26         -
import kotlinx.coroutines.flow.toList
   27         -
import org.junit.jupiter.api.AfterAll
   28         -
import org.junit.jupiter.api.BeforeAll
   29         -
import org.junit.jupiter.api.TestInstance
          26  +
import kotlinx.coroutines.runBlocking
          27  +
import kotlinx.coroutines.withTimeout
   30     28   
import java.io.File
   31         -
import java.util.UUID
          29  +
import java.util.*
   32     30   
import kotlin.test.*
   33     31   
import kotlin.time.Duration.Companion.seconds
   34     32   
   35     33   
/**
   36     34   
 * Tests for bucket operations and presigner
   37     35   
 */
   38         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          36  +
@TestInstance(TestLifecycle.PER_CLASS)
   39     37   
class S3BucketOpsIntegrationTest {
   40         -
    private val client = S3Client {
   41         -
        region = S3TestUtils.DEFAULT_REGION
   42         -
    }
          38  +
    private val client = S3TestUtils.createClient()
   43     39   
   44     40   
    private lateinit var testBucket: String
   45     41   
   46     42   
    @BeforeAll
   47     43   
    fun createResources(): Unit = runBlocking {
   48         -
        testBucket = S3TestUtils.getTestBucket(client)
          44  +
        testBucket = S3TestUtils.createTestBucket(client, "integ-ops")
   49     45   
    }
   50     46   
   51     47   
    @AfterAll
   52     48   
    fun cleanup() = runBlocking {
   53         -
        S3TestUtils.deleteBucketAndAllContents(client, testBucket)
          49  +
        S3TestUtils.deleteBucket(client, testBucket)
   54     50   
    }
   55     51   
   56     52   
    @Test
   57     53   
    fun testPutObjectFromMemory(): Unit = runBlocking {
   58     54   
        val contents = """
   59     55   
            A lep is a ball.
   60     56   
            A tay is a hammer.
   61     57   
            A korf is a tiger.
   62     58   
            A flix is a comb.
   63     59   
            A wogsin is a gift.
@@ -119,115 +253,250 @@
  139    135   
    }
  140    136   
  141    137   
    @Test
  142    138   
    fun testQueryParameterEncoding(): Unit = runBlocking {
  143    139   
        // see: https://github.com/awslabs/aws-sdk-kotlin/issues/448
  144    140   
  145    141   
        // this is mostly a stress test of signing w.r.t query parameter encoding (since
  146    142   
        // delimiter is bound via @httpQuery) and the ability of an HTTP engine to keep
  147    143   
        // the same encoding going out on the wire (e.g. not double percent encoding)
  148    144   
  149         -
        s3WithAllEngines { s3 ->
         145  +
        s3WithAllEngines { _, s3 ->
  150    146   
            s3.listObjects {
  151    147   
                bucket = testBucket
  152    148   
                delimiter = PRINTABLE_CHARS
  153    149   
                prefix = null
  154    150   
            }
  155    151   
            // only care that request is accepted, not the results
  156    152   
        }
  157    153   
    }
  158    154   
  159    155   
    @Test
  160    156   
    fun testPathEncoding(): Unit = runBlocking {
  161    157   
        // this is mostly a stress test of signing w.r.t path encoding (since key is bound
  162    158   
        // via @httpLabel) and the ability of an HTTP engine to keep the same encoding going
  163    159   
        // out on the wire (e.g. not double percent encoding)
  164    160   
  165    161   
        // NOTE: S3 provides guidance on choosing object key names: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
  166    162   
        // This test includes all printable chars (including ones S3 recommends avoiding). Users should
  167    163   
        // strive to fall within the guidelines given by S3 though
  168    164   
  169         -
        s3WithAllEngines { s3 ->
  170         -
            val objKey = "foo$PRINTABLE_CHARS"
         165  +
        s3WithAllEngines { engineName, s3 ->
         166  +
            val objKey = "test-printable-$engineName-$PRINTABLE_CHARS"
  171    167   
            val content = "hello rfc3986"
  172    168   
  173    169   
            s3.putObject {
  174    170   
                bucket = testBucket
  175    171   
                key = objKey
  176    172   
                body = ByteStream.fromString(content)
  177    173   
            }
  178    174   
  179    175   
            val req = GetObjectRequest {
  180    176   
                bucket = testBucket
  181    177   
                key = objKey
  182    178   
            }
  183    179   
  184    180   
            s3.getObject(req) { resp ->
  185    181   
                val actual = resp.body!!.decodeToString()
  186    182   
                assertEquals(content, actual)
  187    183   
            }
  188    184   
        }
  189    185   
    }
  190    186   
  191    187   
    @Test
  192    188   
    fun testMultipartUpload(): Unit = runBlocking {
  193         -
        s3WithAllEngines { s3 ->
  194         -
            val objKey = "test-multipart-${UUID.randomUUID()}"
         189  +
        s3WithAllEngines { engineName, s3 ->
         190  +
            val objKey = "test-multipart-$engineName"
  195    191   
            val contentSize: Long = 8 * 1024 * 1024 // 2 parts
  196    192   
            val file = RandomTempFile(sizeInBytes = contentSize)
  197    193   
            val partSize = 5 * 1024 * 1024 // 5 MB - min part size
  198    194   
  199    195   
            val expectedSha256 = file.readBytes().sha256().encodeToHex()
  200    196   
  201    197   
            val resp = s3.createMultipartUpload {
  202    198   
                bucket = testBucket
  203    199   
                key = objKey
  204    200   
            }
  205    201   
  206         -
            val completedParts = file.chunk(partSize)
         202  +
            val completedParts = file
         203  +
                .chunk(partSize)
         204  +
                .toList()
  207    205   
                .mapIndexed { idx, chunk ->
  208    206   
                    async {
  209    207   
                        val uploadResp = s3.uploadPart {
  210    208   
                            bucket = testBucket
  211    209   
                            key = objKey
  212    210   
                            uploadId = resp.uploadId
  213    211   
                            body = file.asByteStream(chunk)
  214    212   
                            partNumber = idx + 1
  215    213   
                        }
  216    214   
  217    215   
                        CompletedPart {
  218    216   
                            partNumber = idx + 1
  219    217   
                            eTag = uploadResp.eTag
  220    218   
                        }
  221    219   
                    }
  222    220   
                }
  223         -
                .toList()
  224    221   
                .awaitAll()
  225    222   
  226    223   
            s3.completeMultipartUpload {
  227    224   
                bucket = testBucket
  228    225   
                key = objKey
  229    226   
                uploadId = resp.uploadId
  230    227   
                multipartUpload {
  231    228   
                    parts = completedParts
  232    229   
                }
  233    230   
            }
@@ -309,306 +0,355 @@
  329    326   
        assertContains(ex.message, "Service returned error code 403: Forbidden")
  330    327   
        assertEquals("403: Forbidden", ex.sdkErrorMetadata.errorCode!!)
  331    328   
    }
  332    329   
}
  333    330   
  334    331   
// generate sequence of "chunks" where each range defines the inclusive start and end bytes
  335    332   
internal fun File.chunk(partSize: Int): Sequence<LongRange> = (0 until length() step partSize.toLong()).asSequence().map {
  336    333   
    it until minOf(it + partSize, length())
  337    334   
}
  338    335   
  339         -
internal suspend fun s3WithAllEngines(block: suspend (S3Client) -> Unit) {
  340         -
    withAllEngines { engine ->
  341         -
        S3Client {
  342         -
            region = S3TestUtils.DEFAULT_REGION
  343         -
            httpClient = engine
  344         -
        }.use {
         336  +
internal suspend fun s3WithAllEngines(block: suspend (String, S3Client) -> Unit) {
         337  +
    withAllEngines { context ->
         338  +
        S3TestUtils.createClient {
         339  +
            httpClient = context.engine
         340  +
        }.use { engine ->
  345    341   
            try {
  346         -
                block(it)
         342  +
                block(s3SafeName(context.name), engine)
  347    343   
            } catch (ex: Exception) {
  348         -
                println("test failed for engine $engine")
         344  +
                println("test failed for ${context.name} engine")
  349    345   
                throw ex
  350    346   
            }
  351    347   
        }
  352    348   
    }
  353    349   
}
         350  +
         351  +
private val s3SafeNameReplacementPattern = "[^a-z0-9-]".toRegex()
         352  +
         353  +
private fun s3SafeName(originalName: String): String = originalName
         354  +
    .lowercase()
         355  +
    .replace(s3SafeNameReplacementPattern, "-")

tmp-codegen-diff/services/s3/e2eTest/src/S3PresignerTest.kt

@@ -1,1 +104,97 @@
   10     10   
import aws.sdk.kotlin.services.s3.model.PutObjectRequest
   11     11   
import aws.sdk.kotlin.services.s3.presigners.presignDeleteObject
   12     12   
import aws.sdk.kotlin.services.s3.presigners.presignGetObject
   13     13   
import aws.sdk.kotlin.services.s3.presigners.presignPutObject
   14     14   
import aws.sdk.kotlin.testing.PRINTABLE_CHARS
   15     15   
import aws.sdk.kotlin.testing.withAllEngines
   16     16   
import aws.smithy.kotlin.runtime.content.decodeToString
   17     17   
import aws.smithy.kotlin.runtime.http.SdkHttpClient
   18     18   
import aws.smithy.kotlin.runtime.http.complete
   19     19   
import aws.smithy.kotlin.runtime.http.toByteStream
   20         -
import kotlinx.coroutines.*
   21         -
import kotlinx.coroutines.test.runTest
   22         -
import org.junit.jupiter.api.AfterAll
   23         -
import org.junit.jupiter.api.BeforeAll
   24         -
import org.junit.jupiter.api.TestInstance
          20  +
import aws.smithy.kotlin.runtime.testing.AfterAll
          21  +
import aws.smithy.kotlin.runtime.testing.BeforeAll
          22  +
import aws.smithy.kotlin.runtime.testing.TestInstance
          23  +
import aws.smithy.kotlin.runtime.testing.TestLifecycle
          24  +
import kotlinx.coroutines.runBlocking
   25     25   
import kotlin.test.Test
   26     26   
import kotlin.test.assertEquals
   27     27   
import kotlin.time.Duration.Companion.seconds
   28     28   
   29         -
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
          29  +
@TestInstance(TestLifecycle.PER_CLASS)
   30     30   
class S3PresignerTest {
   31         -
    private val client = S3Client {
   32         -
        region = S3TestUtils.DEFAULT_REGION
   33         -
    }
          31  +
    private val client = S3TestUtils.createClient()
   34     32   
   35     33   
    private lateinit var testBucket: String
   36     34   
   37     35   
    @BeforeAll
   38     36   
    fun createResources(): Unit = runBlocking {
   39         -
        testBucket = S3TestUtils.getTestBucket(client)
          37  +
        testBucket = S3TestUtils.createTestBucket(client, "presigning")
   40     38   
    }
   41     39   
   42     40   
    @AfterAll
   43     41   
    fun cleanup(): Unit = runBlocking {
   44         -
        S3TestUtils.deleteBucketAndAllContents(client, testBucket)
          42  +
        S3TestUtils.deleteBucket(client, testBucket)
   45     43   
        client.close()
   46     44   
    }
   47     45   
   48     46   
    private suspend fun testPresign(client: S3Client) {
   49     47   
        val contents = "presign-test"
   50     48   
        val keyName = "foo$PRINTABLE_CHARS"
   51     49   
   52         -
        withAllEngines { engine ->
   53         -
            val httpClient = SdkHttpClient(engine)
          50  +
        withAllEngines { context ->
          51  +
            val httpClient = SdkHttpClient(context.engine)
   54     52   
   55     53   
            // PUT
   56     54   
            val unsignedPutRequest = PutObjectRequest {
   57     55   
                bucket = testBucket
   58     56   
                key = keyName
   59     57   
            }
   60     58   
            val presignedPutRequest = client.presignPutObject(unsignedPutRequest, 60.seconds)
   61     59   
   62     60   
            S3TestUtils.responseCodeFromPut(presignedPutRequest, contents)
   63     61   
   64     62   
            // GET
   65     63   
            val unsignedGetRequest = GetObjectRequest {
   66     64   
                bucket = testBucket
   67     65   
                key = keyName
   68     66   
            }
   69     67   
            val presignedGetRequest = client.presignGetObject(unsignedGetRequest, 60.seconds)
   70     68   
   71     69   
            val call = httpClient.call(presignedGetRequest)
   72     70   
            val body = call.response.body.toByteStream()?.decodeToString()
   73     71   
            call.complete()
   74     72   
            assertEquals(200, call.response.status.value)
   75     73   
            assertEquals(contents, body)
   76     74   
   77     75   
            // DELETE
   78     76   
            val unsignedDeleteRequest = DeleteObjectRequest {
   79     77   
                bucket = testBucket
   80     78   
                key = keyName
   81     79   
            }
   82     80   
            val presignedDeleteObject = client.presignDeleteObject(unsignedDeleteRequest, 60.seconds)
   83     81   
   84     82   
            val deleteCall = httpClient.call(presignedDeleteObject)
   85     83   
            deleteCall.complete()
   86     84   
            assertEquals(204, deleteCall.response.status.value)
   87     85   
        }
   88     86   
    }
   89     87   
   90     88   
    @Test
   91         -
    fun testPresignNormal() = runTest {
   92         -
        S3Client {
   93         -
            region = S3TestUtils.DEFAULT_REGION
   94         -
        }.use { testPresign(it) }
          89  +
    fun testPresignNormal() = runBlocking {
          90  +
        S3TestUtils.createClient().use { testPresign(it) }
   95     91   
    }
   96     92   
   97     93   
    @Test
   98     94   
    fun testPresignWithForcePathStyle() = runBlocking {
   99         -
        S3Client {
  100         -
            region = S3TestUtils.DEFAULT_REGION
  101         -
            forcePathStyle = true
  102         -
        }.use { testPresign(it) }
          95  +
        S3TestUtils.createClient { forcePathStyle = true }.use { testPresign(it) }
  103     96   
    }
  104     97   
}

tmp-codegen-diff/services/s3/e2eTest/src/S3TestUtils.kt

@@ -1,1 +221,214 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
package aws.sdk.kotlin.e2etest
    6      6   
    7      7   
import aws.sdk.kotlin.services.s3.*
    8         -
import aws.sdk.kotlin.services.s3.S3Client
    9      8   
import aws.sdk.kotlin.services.s3.model.*
   10      9   
import aws.sdk.kotlin.services.s3.model.BucketLocationConstraint
   11     10   
import aws.sdk.kotlin.services.s3.model.ExpirationStatus
   12     11   
import aws.sdk.kotlin.services.s3.model.LifecycleRule
   13     12   
import aws.sdk.kotlin.services.s3.paginators.listObjectsV2Paginated
   14     13   
import aws.sdk.kotlin.services.s3.waiters.waitUntilBucketExists
   15     14   
import aws.sdk.kotlin.services.s3.waiters.waitUntilBucketNotExists
   16     15   
import aws.sdk.kotlin.services.s3control.*
   17     16   
import aws.sdk.kotlin.services.s3control.model.*
   18     17   
import aws.sdk.kotlin.services.sts.StsClient
   19     18   
import aws.smithy.kotlin.runtime.http.request.HttpRequest
   20         -
import aws.smithy.kotlin.runtime.text.ensurePrefix
          19  +
import aws.smithy.kotlin.runtime.time.Instant
          20  +
import aws.smithy.kotlin.runtime.time.TimestampFormat
          21  +
import aws.smithy.kotlin.runtime.util.asyncLazy
   21     22   
import kotlinx.coroutines.*
   22     23   
import kotlinx.coroutines.flow.*
   23         -
import kotlinx.coroutines.withTimeout
   24     24   
import java.io.OutputStreamWriter
   25     25   
import java.net.URL
   26     26   
import java.util.*
   27     27   
import javax.net.ssl.HttpsURLConnection
   28     28   
import kotlin.time.Duration.Companion.seconds
   29     29   
   30     30   
object S3TestUtils {
   31         -
   32     31   
    const val DEFAULT_REGION = "us-west-2"
   33     32   
   34     33   
    // The E2E test account only has permission to operate on buckets with the prefix "s3-test-bucket-"
   35         -
    private const val TEST_BUCKET_PREFIX = "s3-test-bucket-"
          34  +
    private const val TEST_BUCKET_PREFIX = "s3-test-bucket"
          35  +
          36  +
    private const val S3_EXPRESS_DIRECTORY_BUCKET_SUFFIX = "x-s3"
   36     37   
   37         -
    private const val S3_MAX_BUCKET_NAME_LENGTH = 63 // https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
   38         -
    private const val S3_EXPRESS_DIRECTORY_BUCKET_SUFFIX = "--x-s3"
          38  +
    val testRunId by lazy {
          39  +
        Instant
          40  +
            .now()
          41  +
            .format(TimestampFormat.ISO_8601_CONDENSED)
          42  +
            .lowercase()
          43  +
            .also { println("Starting test run ID $it") }
          44  +
    }
   39     45   
   40         -
    suspend fun getTestBucket(
          46  +
    suspend fun createTestBucket(
   41     47   
        client: S3Client,
   42         -
        region: String? = null,
   43         -
        accountId: String? = null,
   44         -
    ): String = getBucketWithPrefix(client, TEST_BUCKET_PREFIX, region, accountId)
          48  +
        suffix: String,
          49  +
        region: String = client.config.region!!,
          50  +
    ): String = createBucket(client, TEST_BUCKET_PREFIX, suffix, region)
   45     51   
   46         -
    suspend fun getBucketWithPrefix(
          52  +
    suspend fun createBucket(
   47     53   
        client: S3Client,
   48     54   
        prefix: String,
   49         -
        region: String? = null,
   50         -
        accountId: String? = null,
          55  +
        suffix: String,
          56  +
        region: String = client.config.region!!,
   51     57   
    ): String = withTimeout(60.seconds) {
   52         -
        val buckets = client.listBuckets()
   53         -
            .buckets
   54         -
            ?.mapNotNull { it.name }
   55         -
   56         -
        var testBucket = buckets?.firstOrNull { bucketName ->
   57         -
            bucketName.startsWith(prefix) &&
   58         -
                region?.let {
   59         -
                    client.getBucketLocation {
   60         -
                        bucket = bucketName
   61         -
                        expectedBucketOwner = accountId
   62         -
                    }.locationConstraint?.value == region
   63         -
                } ?: true
   64         -
        }
   65         -
   66         -
        if (testBucket == null) {
   67         -
            testBucket = prefix + UUID.randomUUID()
   68         -
            println("Creating S3 bucket: $testBucket")
          58  +
        val bucketName = "$prefix-$testRunId-$suffix"
          59  +
        println("Creating S3 bucket: $bucketName")
   69     60   
   70     61   
        client.createBucket {
   71         -
                bucket = testBucket
          62  +
            bucket = bucketName
   72     63   
            createBucketConfiguration {
   73         -
                    locationConstraint = BucketLocationConstraint.fromValue(region ?: client.config.region!!)
          64  +
                locationConstraint = BucketLocationConstraint.fromValue(region)
   74     65   
            }
   75     66   
        }
   76     67   
   77         -
            client.waitUntilBucketExists { bucket = testBucket }
   78         -
        } else {
   79         -
            println("Using existing S3 bucket: $testBucket")
   80         -
        }
          68  +
        client.waitUntilBucketExists { bucket = bucketName }
   81     69   
   82     70   
        client.putBucketLifecycleConfiguration {
   83         -
            bucket = testBucket
          71  +
            bucket = bucketName
   84     72   
            lifecycleConfiguration {
   85     73   
                rules = listOf(
   86     74   
                    LifecycleRule {
   87     75   
                        expiration { days = 1 }
   88     76   
                        filter { this.prefix = "" }
   89     77   
                        status = ExpirationStatus.Enabled
   90     78   
                        id = "delete-old"
   91     79   
                    },
   92     80   
                )
   93     81   
            }
   94     82   
        }
   95     83   
   96         -
        testBucket
          84  +
        bucketName
   97     85   
    }
   98     86   
   99         -
    suspend fun getTestDirectoryBucket(client: S3Client, suffix: String) = withTimeout(60.seconds) {
  100         -
        var testBucket = client.listBuckets()
  101         -
            .buckets
  102         -
            ?.mapNotNull { it.name }
  103         -
            ?.firstOrNull { it.startsWith(TEST_BUCKET_PREFIX) && it.endsWith(S3_EXPRESS_DIRECTORY_BUCKET_SUFFIX) }
  104         -
  105         -
        if (testBucket == null) {
  106         -
            // Adding S3 Express suffix surpasses the bucket name length limit... trim the UUID if needed
  107         -
            testBucket = TEST_BUCKET_PREFIX +
  108         -
                UUID.randomUUID().toString().subSequence(0 until (S3_MAX_BUCKET_NAME_LENGTH - TEST_BUCKET_PREFIX.length - suffix.ensurePrefix("--").length)) +
  109         -
                suffix.ensurePrefix("--")
  110         -
  111         -
            println("Creating S3 Express directory bucket: $testBucket")
          87  +
    suspend fun createTestDirectoryBucket(
          88  +
        client: S3Client,
          89  +
        availabilityZone: String,
          90  +
        suffix: String,
          91  +
    ) = createDirectoryBucket(client, TEST_BUCKET_PREFIX, availabilityZone, suffix)
  112     92   
  113         -
            val availabilityZone = testBucket // s3-test-bucket-UUID--use1-az4--x-s3
  114         -
                .removeSuffix(S3_EXPRESS_DIRECTORY_BUCKET_SUFFIX) // s3-test-bucket-UUID--use1-az4
  115         -
                .substringAfterLast("--") // use1-az4
          93  +
    suspend fun createDirectoryBucket(
          94  +
        client: S3Client,
          95  +
        prefix: String,
          96  +
        availabilityZone: String,
          97  +
        suffix: String,
          98  +
    ) = withTimeout(60.seconds) {
          99  +
        val bucketName = "$prefix-$testRunId-$suffix--$availabilityZone--$S3_EXPRESS_DIRECTORY_BUCKET_SUFFIX"
         100  +
        println("Creating S3 Express directory bucket: $bucketName")
  116    101   
  117    102   
        client.createBucket {
  118         -
                bucket = testBucket
         103  +
            bucket = bucketName
  119    104   
            createBucketConfiguration {
  120    105   
                location = LocationInfo {
  121    106   
                    type = LocationType.AvailabilityZone
  122    107   
                    name = availabilityZone
  123    108   
                }
  124    109   
                bucket = BucketInfo {
  125    110   
                    type = BucketType.Directory
  126    111   
                    dataRedundancy = DataRedundancy.SingleAvailabilityZone
  127    112   
                }
  128    113   
            }
  129    114   
        }
  130         -
        }
  131         -
        testBucket
         115  +
         116  +
        bucketName
  132    117   
    }
  133    118   
  134         -
    suspend fun deleteBucketAndAllContents(client: S3Client, bucketName: String): Unit = coroutineScope {
         119  +
    suspend fun deleteBucket(client: S3Client, bucketName: String): Unit = coroutineScope {
  135    120   
        deleteBucketContents(client, bucketName)
         121  +
        deleteMultiPartUploads(client, bucketName)
  136    122   
  137    123   
        try {
  138    124   
            client.deleteBucket { bucket = bucketName }
  139    125   
  140    126   
            client.waitUntilBucketNotExists {
  141    127   
                bucket = bucketName
  142    128   
            }
  143    129   
        } catch (ex: Exception) {
  144    130   
            println("Failed to delete bucket: $bucketName")
  145    131   
            throw ex
  146    132   
        }
  147    133   
    }
  148    134   
  149         -
    suspend fun deleteBucketContents(client: S3Client, bucketName: String): Unit = coroutineScope {
         135  +
    private suspend fun deleteBucketContents(client: S3Client, bucketName: String): Unit = coroutineScope {
  150    136   
        val scope = this
  151    137   
  152    138   
        try {
  153    139   
            println("Deleting S3 buckets contents: $bucketName")
  154    140   
            val dispatcher = Dispatchers.Default.limitedParallelism(64)
  155    141   
            val jobs = mutableListOf<Job>()
  156    142   
  157    143   
            client.listObjectsV2Paginated { bucket = bucketName }
  158    144   
                .mapNotNull { it.contents }
  159    145   
                .collect { contents ->
  160    146   
                    val job = scope.launch(dispatcher) {
  161    147   
                        client.deleteObjects {
  162    148   
                            bucket = bucketName
  163    149   
                            delete {
  164    150   
                                objects = contents.mapNotNull(Object::key).map { ObjectIdentifier { key = it } }
  165    151   
                            }
  166    152   
                        }
  167    153   
                    }
  168    154   
                    jobs.add(job)
  169    155   
                }
  170    156   
  171    157   
            jobs.joinAll()
  172    158   
        } catch (ex: Exception) {
  173    159   
            println("Failed to delete buckets contents: $bucketName")
  174    160   
            throw ex
  175    161   
        }
  176    162   
    }
  177    163   
         164  +
    private suspend fun deleteMultiPartUploads(client: S3Client, bucketName: String) {
         165  +
        client.listMultipartUploads {
         166  +
            bucket = bucketName
         167  +
        }.uploads?.forEach { upload ->
         168  +
            client.abortMultipartUpload {
         169  +
                bucket = bucketName
         170  +
                key = upload.key
         171  +
                uploadId = upload.uploadId
         172  +
            }
         173  +
        }
         174  +
    }
         175  +
  178    176   
    fun responseCodeFromPut(presignedRequest: HttpRequest, content: String): Int {
  179    177   
        val url = URL(presignedRequest.url.toString())
  180    178   
        val connection: HttpsURLConnection = url.openConnection() as HttpsURLConnection
  181    179   
        presignedRequest.headers.forEach { key, values ->
  182    180   
            connection.setRequestProperty(key, values.first())
  183    181   
        }
  184    182   
  185    183   
        connection.doOutput = true
  186    184   
        connection.requestMethod = "PUT"
  187    185   
        val out = OutputStreamWriter(connection.outputStream)
  188    186   
        out.write(content)
  189    187   
        out.close()
  190    188   
  191    189   
        if (connection.errorStream != null) {
  192    190   
            error("request failed: ${connection.errorStream?.bufferedReader()?.readText()}")
  193    191   
        }
  194    192   
  195    193   
        return connection.responseCode
  196    194   
    }
  197    195   
  198         -
    internal suspend fun getAccountId(): String {
         196  +
    private val accountId = asyncLazy {
  199    197   
        println("Getting account ID")
  200    198   
  201         -
        val accountId = StsClient {
  202         -
            region = "us-west-2"
  203         -
        }.use {
  204         -
            it.getCallerIdentity().account
         199  +
        val accountId = StsClient { region = DEFAULT_REGION }.use { sts ->
         200  +
            sts.getCallerIdentity().account
  205    201   
        }
  206    202   
  207         -
        return checkNotNull(accountId) { "Unable to get AWS account ID" }
         203  +
        checkNotNull(accountId) { "Unable to get AWS account ID" }
  208    204   
    }
  209    205   
  210         -
    internal suspend fun deleteMultiPartUploads(client: S3Client, bucketName: String) {
  211         -
        client.listMultipartUploads {
  212         -
            bucket = bucketName
  213         -
        }.uploads?.forEach { upload ->
  214         -
            client.abortMultipartUpload {
  215         -
                bucket = bucketName
  216         -
                key = upload.key
  217         -
                uploadId = upload.uploadId
  218         -
            }
  219         -
        }
         206  +
    internal suspend fun getAccountId(): String = accountId.get()
         207  +
         208  +
    fun createClient(builder: S3Client.Config.Builder.() -> Unit = { }): S3Client = S3Client {
         209  +
        region = DEFAULT_REGION
         210  +
         211  +
        // Apply builder block after setting default region in case of overrides
         212  +
        builder()
  220    213   
    }
  221    214   
}

tmp-codegen-diff/services/s3/generated-src/main/kotlin/aws/sdk/kotlin/services/s3/DefaultS3Client.kt

@@ -988,988 +1047,1049 @@
 1008   1008   
 1009   1009   
    /**
 1010   1010   
     * This operation is not supported for directory buckets.
 1011   1011   
     *
 1012   1012   
     * Deletes an S3 Inventory configuration (identified by the inventory ID) from the bucket.
 1013   1013   
     *
 1014   1014   
     * To use this operation, you must have permissions to perform the `s3:PutInventoryConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
 1015   1015   
     *
 1016   1016   
     * For information about the Amazon S3 inventory feature, see [Amazon S3 Inventory](https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html).
 1017   1017   
     *
        1018  +
     * After deleting a configuration, Amazon S3 might still deliver one additional inventory report during a brief transition period while the system processes the deletion.
        1019  +
     *
 1018   1020   
     * Operations related to `DeleteBucketInventoryConfiguration` include:
 1019   1021   
     * + [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html)
 1020   1022   
     * + [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html)
 1021   1023   
     * + [ListBucketInventoryConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html)
 1022   1024   
     *
 1023   1025   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 1024   1026   
     */
 1025   1027   
    override suspend fun deleteBucketInventoryConfiguration(input: DeleteBucketInventoryConfigurationRequest): DeleteBucketInventoryConfigurationResponse {
 1026   1028   
        val op = SdkHttpOperation.build<DeleteBucketInventoryConfigurationRequest, DeleteBucketInventoryConfigurationResponse> {
 1027   1029   
            serializeWith = DeleteBucketInventoryConfigurationOperationSerializer()
@@ -1210,1212 +1274,1282 @@
 1230   1232   
        if (config.credentialsProvider is StaticCredentialsProvider) {
 1231   1233   
            op.context.emitBusinessMetric(AwsBusinessMetric.Credentials.CREDENTIALS_CODE)
 1232   1234   
        }
 1233   1235   
        op.install(UserAgent(awsUserAgentMetadata))
 1234   1236   
        op.install(RecursionDetection())
 1235   1237   
        op.interceptors.addAll(config.interceptors)
 1236   1238   
        return op.roundTrip(client, input)
 1237   1239   
    }
 1238   1240   
 1239   1241   
    /**
 1240         -
     * This operation is not supported for directory buckets.
 1241         -
     *
 1242   1242   
     * Deletes a metrics configuration for the Amazon CloudWatch request metrics (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 1243   1243   
     *
        1244  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        1245  +
     *
        1246  +
     * ## Permissions
 1244   1247   
     *  To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        1248  +
     * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        1249  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        1250  +
     *
        1251  +
     * ## HTTP Host header syntax
        1252  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 1245   1253   
     *
 1246   1254   
     * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 1247   1255   
     *
 1248   1256   
     * The following operations are related to `DeleteBucketMetricsConfiguration`:
 1249   1257   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 1250   1258   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 1251   1259   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 1252   1260   
     * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 1253   1261   
     *
 1254   1262   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -2556,2564 +2620,2634 @@
 2576   2584   
        if (config.credentialsProvider is StaticCredentialsProvider) {
 2577   2585   
            op.context.emitBusinessMetric(AwsBusinessMetric.Credentials.CREDENTIALS_CODE)
 2578   2586   
        }
 2579   2587   
        op.install(UserAgent(awsUserAgentMetadata))
 2580   2588   
        op.install(RecursionDetection())
 2581   2589   
        op.interceptors.addAll(config.interceptors)
 2582   2590   
        return op.roundTrip(client, input)
 2583   2591   
    }
 2584   2592   
 2585   2593   
    /**
 2586         -
     * This operation is not supported for directory buckets.
 2587         -
     *
 2588   2594   
     * Gets a metrics configuration (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 2589   2595   
     *
        2596  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        2597  +
     *
        2598  +
     * ## Permissions
 2590   2599   
     *  To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        2600  +
     * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        2601  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        2602  +
     *
        2603  +
     * ## HTTP Host header syntax
        2604  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 2591   2605   
     *
 2592   2606   
     *  For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 2593   2607   
     *
 2594   2608   
     * The following operations are related to `GetBucketMetricsConfiguration`:
 2595   2609   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 2596   2610   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 2597   2611   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 2598   2612   
     * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 2599   2613   
     *
 2600   2614   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -4031,4045 +4097,4117 @@
 4051   4065   
        if (config.credentialsProvider is StaticCredentialsProvider) {
 4052   4066   
            op.context.emitBusinessMetric(AwsBusinessMetric.Credentials.CREDENTIALS_CODE)
 4053   4067   
        }
 4054   4068   
        op.install(UserAgent(awsUserAgentMetadata))
 4055   4069   
        op.install(RecursionDetection())
 4056   4070   
        op.interceptors.addAll(config.interceptors)
 4057   4071   
        return op.roundTrip(client, input)
 4058   4072   
    }
 4059   4073   
 4060   4074   
    /**
 4061         -
     * This operation is not supported for directory buckets.
 4062         -
     *
 4063   4075   
     * Lists the metrics configurations for the bucket. The metrics configurations are only for the request metrics of the bucket and do not provide information on daily storage metrics. You can have up to 1,000 configurations per bucket.
 4064   4076   
     *
        4077  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        4078  +
     *
 4065   4079   
     * This action supports list pagination and does not return more than 100 configurations at a time. Always check the `IsTruncated` element in the response. If there are no more configurations to list, `IsTruncated` is set to false. If there are more configurations to list, `IsTruncated` is set to true, and there is a value in `NextContinuationToken`. You use the `NextContinuationToken` value to continue the pagination of the list by passing the value in `continuation-token` in the request to `GET` the next page.
 4066   4080   
     *
        4081  +
     * ## Permissions
 4067   4082   
     * To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        4083  +
     * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        4084  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        4085  +
     *
        4086  +
     * ## HTTP Host header syntax
        4087  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 4068   4088   
     *
 4069   4089   
     * For more information about metrics configurations and CloudWatch request metrics, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 4070   4090   
     *
 4071   4091   
     * The following operations are related to `ListBucketMetricsConfigurations`:
 4072   4092   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 4073   4093   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 4074   4094   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 4075   4095   
     *
 4076   4096   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 4077   4097   
     */
@@ -5349,5369 +5413,5439 @@
 5369   5389   
        if (config.credentialsProvider is StaticCredentialsProvider) {
 5370   5390   
            op.context.emitBusinessMetric(AwsBusinessMetric.Credentials.CREDENTIALS_CODE)
 5371   5391   
        }
 5372   5392   
        op.install(UserAgent(awsUserAgentMetadata))
 5373   5393   
        op.install(RecursionDetection())
 5374   5394   
        op.interceptors.addAll(config.interceptors)
 5375   5395   
        return op.roundTrip(client, input)
 5376   5396   
    }
 5377   5397   
 5378   5398   
    /**
 5379         -
     * This operation is not supported for directory buckets.
 5380         -
     *
 5381   5399   
     * Sets a metrics configuration (specified by the metrics configuration ID) for the bucket. You can have up to 1,000 metrics configurations per bucket. If you're updating an existing metrics configuration, note that this is a full replacement of the existing metrics configuration. If you don't include the elements you want to keep, they are erased.
 5382   5400   
     *
        5401  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        5402  +
     *
        5403  +
     * ## Permissions
 5383   5404   
     * To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        5405  +
     * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        5406  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        5407  +
     *
        5408  +
     * ## HTTP Host header syntax
        5409  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 5384   5410   
     *
 5385   5411   
     * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 5386   5412   
     *
 5387   5413   
     * The following operations are related to `PutBucketMetricsConfiguration`:
 5388   5414   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 5389   5415   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 5390   5416   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 5391   5417   
     *
 5392   5418   
     * `PutBucketMetricsConfiguration` has the following special error:
 5393   5419   
     * + Error code: `TooManyConfigurations`

tmp-codegen-diff/services/s3/generated-src/main/kotlin/aws/sdk/kotlin/services/s3/S3Client.kt

@@ -249,249 +309,309 @@
  269    269   
import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider
  270    270   
import aws.smithy.kotlin.runtime.util.LazyAsyncValue
  271    271   
import kotlin.collections.List
  272    272   
import kotlin.collections.Set
  273    273   
import kotlin.jvm.JvmStatic
  274    274   
import kotlin.time.Duration
  275    275   
import kotlinx.coroutines.runBlocking
  276    276   
  277    277   
  278    278   
public const val ServiceId: String = "S3"
  279         -
public const val SdkVersion: String = "1.6.48-SNAPSHOT"
         279  +
public const val SdkVersion: String = "1.6.60-SNAPSHOT"
  280    280   
public const val ServiceApiVersion: String = "2006-03-01"
  281    281   
  282    282   
/**
  283    283   
 *
  284    284   
 */
  285    285   
public interface S3Client : SdkClient {
  286    286   
    /**
  287    287   
     * S3Client's configuration
  288    288   
     */
  289    289   
    public override val config: Config
@@ -996,996 +1055,1057 @@
 1016   1016   
 1017   1017   
    /**
 1018   1018   
     * This operation is not supported for directory buckets.
 1019   1019   
     *
 1020   1020   
     * Deletes an S3 Inventory configuration (identified by the inventory ID) from the bucket.
 1021   1021   
     *
 1022   1022   
     * To use this operation, you must have permissions to perform the `s3:PutInventoryConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
 1023   1023   
     *
 1024   1024   
     * For information about the Amazon S3 inventory feature, see [Amazon S3 Inventory](https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html).
 1025   1025   
     *
        1026  +
     * After deleting a configuration, Amazon S3 might still deliver one additional inventory report during a brief transition period while the system processes the deletion.
        1027  +
     *
 1026   1028   
     * Operations related to `DeleteBucketInventoryConfiguration` include:
 1027   1029   
     * + [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html)
 1028   1030   
     * + [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html)
 1029   1031   
     * + [ListBucketInventoryConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html)
 1030   1032   
     *
 1031   1033   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 1032   1034   
     */
 1033   1035   
    public suspend fun deleteBucketInventoryConfiguration(input: DeleteBucketInventoryConfigurationRequest): DeleteBucketInventoryConfigurationResponse
 1034   1036   
 1035   1037   
    /**
@@ -1070,1072 +1134,1142 @@
 1090   1092   
     *
 1091   1093   
     * The following operations are related to `DeleteBucketMetadataTableConfiguration`:
 1092   1094   
     * + [CreateBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataTableConfiguration.html)
 1093   1095   
     * + [GetBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetadataTableConfiguration.html)
 1094   1096   
     *
 1095   1097   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 1096   1098   
     */
 1097   1099   
    public suspend fun deleteBucketMetadataTableConfiguration(input: DeleteBucketMetadataTableConfigurationRequest): DeleteBucketMetadataTableConfigurationResponse
 1098   1100   
 1099   1101   
    /**
 1100         -
     * This operation is not supported for directory buckets.
 1101         -
     *
 1102   1102   
     * Deletes a metrics configuration for the Amazon CloudWatch request metrics (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 1103   1103   
     *
        1104  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        1105  +
     *
        1106  +
     * ## Permissions
 1104   1107   
     *  To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        1108  +
     * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        1109  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        1110  +
     *
        1111  +
     * ## HTTP Host header syntax
        1112  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 1105   1113   
     *
 1106   1114   
     * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 1107   1115   
     *
 1108   1116   
     * The following operations are related to `DeleteBucketMetricsConfiguration`:
 1109   1117   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 1110   1118   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 1111   1119   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 1112   1120   
     * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 1113   1121   
     *
 1114   1122   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -1554,1562 +1618,1632 @@
 1574   1582   
     *
 1575   1583   
     * The following operations are related to `GetBucketMetadataTableConfiguration`:
 1576   1584   
     * + [CreateBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataTableConfiguration.html)
 1577   1585   
     * + [DeleteBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetadataTableConfiguration.html)
 1578   1586   
     *
 1579   1587   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 1580   1588   
     */
 1581   1589   
    public suspend fun getBucketMetadataTableConfiguration(input: GetBucketMetadataTableConfigurationRequest): GetBucketMetadataTableConfigurationResponse
 1582   1590   
 1583   1591   
    /**
 1584         -
     * This operation is not supported for directory buckets.
 1585         -
     *
 1586   1592   
     * Gets a metrics configuration (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 1587   1593   
     *
        1594  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        1595  +
     *
        1596  +
     * ## Permissions
 1588   1597   
     *  To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        1598  +
     * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        1599  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        1600  +
     *
        1601  +
     * ## HTTP Host header syntax
        1602  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 1589   1603   
     *
 1590   1604   
     *  For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 1591   1605   
     *
 1592   1606   
     * The following operations are related to `GetBucketMetricsConfiguration`:
 1593   1607   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 1594   1608   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 1595   1609   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 1596   1610   
     * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 1597   1611   
     *
 1598   1612   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -2131,2145 +2197,2217 @@
 2151   2165   
     * The following operations are related to `ListBucketInventoryConfigurations`:
 2152   2166   
     * + [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html)
 2153   2167   
     * + [DeleteBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html)
 2154   2168   
     * + [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html)
 2155   2169   
     *
 2156   2170   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 2157   2171   
     */
 2158   2172   
    public suspend fun listBucketInventoryConfigurations(input: ListBucketInventoryConfigurationsRequest): ListBucketInventoryConfigurationsResponse
 2159   2173   
 2160   2174   
    /**
 2161         -
     * This operation is not supported for directory buckets.
 2162         -
     *
 2163   2175   
     * Lists the metrics configurations for the bucket. The metrics configurations are only for the request metrics of the bucket and do not provide information on daily storage metrics. You can have up to 1,000 configurations per bucket.
 2164   2176   
     *
        2177  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        2178  +
     *
 2165   2179   
     * This action supports list pagination and does not return more than 100 configurations at a time. Always check the `IsTruncated` element in the response. If there are no more configurations to list, `IsTruncated` is set to false. If there are more configurations to list, `IsTruncated` is set to true, and there is a value in `NextContinuationToken`. You use the `NextContinuationToken` value to continue the pagination of the list by passing the value in `continuation-token` in the request to `GET` the next page.
 2166   2180   
     *
        2181  +
     * ## Permissions
 2167   2182   
     * To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        2183  +
     * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        2184  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        2185  +
     *
        2186  +
     * ## HTTP Host header syntax
        2187  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 2168   2188   
     *
 2169   2189   
     * For more information about metrics configurations and CloudWatch request metrics, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 2170   2190   
     *
 2171   2191   
     * The following operations are related to `ListBucketMetricsConfigurations`:
 2172   2192   
     * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 2173   2193   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 2174   2194   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 2175   2195   
     *
 2176   2196   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 2177   2197   
     */
@@ -2678,2698 +2742,2768 @@
 2698   2718   
     * + [CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)
 2699   2719   
     * + [GetBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html)
 2700   2720   
     *
 2701   2721   
     * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 2702   2722   
     *
 2703   2723   
     * @sample aws.sdk.kotlin.services.s3.samples.PutBucketLogging.sample
 2704   2724   
     */
 2705   2725   
    public suspend fun putBucketLogging(input: PutBucketLoggingRequest): PutBucketLoggingResponse
 2706   2726   
 2707   2727   
    /**
 2708         -
     * This operation is not supported for directory buckets.
 2709         -
     *
 2710   2728   
     * Sets a metrics configuration (specified by the metrics configuration ID) for the bucket. You can have up to 1,000 metrics configurations per bucket. If you're updating an existing metrics configuration, note that this is a full replacement of the existing metrics configuration. If you don't include the elements you want to keep, they are erased.
 2711   2729   
     *
        2730  +
     * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        2731  +
     *
        2732  +
     * ## Permissions
 2712   2733   
     * To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        2734  +
     * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        2735  +
     * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        2736  +
     *
        2737  +
     * ## HTTP Host header syntax
        2738  +
     * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 2713   2739   
     *
 2714   2740   
     * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 2715   2741   
     *
 2716   2742   
     * The following operations are related to `PutBucketMetricsConfiguration`:
 2717   2743   
     * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 2718   2744   
     * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 2719   2745   
     * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 2720   2746   
     *
 2721   2747   
     * `PutBucketMetricsConfiguration` has the following special error:
 2722   2748   
     * + Error code: `TooManyConfigurations`
@@ -3904,3930 +3963,3991 @@
 3924   3950   
 3925   3951   
/**
 3926   3952   
 * This operation is not supported for directory buckets.
 3927   3953   
 *
 3928   3954   
 * Deletes an S3 Inventory configuration (identified by the inventory ID) from the bucket.
 3929   3955   
 *
 3930   3956   
 * To use this operation, you must have permissions to perform the `s3:PutInventoryConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
 3931   3957   
 *
 3932   3958   
 * For information about the Amazon S3 inventory feature, see [Amazon S3 Inventory](https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html).
 3933   3959   
 *
        3960  +
 * After deleting a configuration, Amazon S3 might still deliver one additional inventory report during a brief transition period while the system processes the deletion.
        3961  +
 *
 3934   3962   
 * Operations related to `DeleteBucketInventoryConfiguration` include:
 3935   3963   
 * + [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html)
 3936   3964   
 * + [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html)
 3937   3965   
 * + [ListBucketInventoryConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html)
 3938   3966   
 *
 3939   3967   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 3940   3968   
 */
 3941   3969   
public suspend inline fun S3Client.deleteBucketInventoryConfiguration(crossinline block: DeleteBucketInventoryConfigurationRequest.Builder.() -> Unit): DeleteBucketInventoryConfigurationResponse = deleteBucketInventoryConfiguration(DeleteBucketInventoryConfigurationRequest.Builder().apply(block).build())
 3942   3970   
 3943   3971   
/**
@@ -3978,4006 +4042,4076 @@
 3998   4026   
 *
 3999   4027   
 * The following operations are related to `DeleteBucketMetadataTableConfiguration`:
 4000   4028   
 * + [CreateBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataTableConfiguration.html)
 4001   4029   
 * + [GetBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetadataTableConfiguration.html)
 4002   4030   
 *
 4003   4031   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 4004   4032   
 */
 4005   4033   
public suspend inline fun S3Client.deleteBucketMetadataTableConfiguration(crossinline block: DeleteBucketMetadataTableConfigurationRequest.Builder.() -> Unit): DeleteBucketMetadataTableConfigurationResponse = deleteBucketMetadataTableConfiguration(DeleteBucketMetadataTableConfigurationRequest.Builder().apply(block).build())
 4006   4034   
 4007   4035   
/**
 4008         -
 * This operation is not supported for directory buckets.
 4009         -
 *
 4010   4036   
 * Deletes a metrics configuration for the Amazon CloudWatch request metrics (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 4011   4037   
 *
        4038  +
 * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        4039  +
 *
        4040  +
 * ## Permissions
 4012   4041   
 *  To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        4042  +
 * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        4043  +
 * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        4044  +
 *
        4045  +
 * ## HTTP Host header syntax
        4046  +
 * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 4013   4047   
 *
 4014   4048   
 * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 4015   4049   
 *
 4016   4050   
 * The following operations are related to `DeleteBucketMetricsConfiguration`:
 4017   4051   
 * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 4018   4052   
 * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 4019   4053   
 * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 4020   4054   
 * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 4021   4055   
 *
 4022   4056   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -4462,4496 +4526,4566 @@
 4482   4516   
 *
 4483   4517   
 * The following operations are related to `GetBucketMetadataTableConfiguration`:
 4484   4518   
 * + [CreateBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataTableConfiguration.html)
 4485   4519   
 * + [DeleteBucketMetadataTableConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetadataTableConfiguration.html)
 4486   4520   
 *
 4487   4521   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 4488   4522   
 */
 4489   4523   
public suspend inline fun S3Client.getBucketMetadataTableConfiguration(crossinline block: GetBucketMetadataTableConfigurationRequest.Builder.() -> Unit): GetBucketMetadataTableConfigurationResponse = getBucketMetadataTableConfiguration(GetBucketMetadataTableConfigurationRequest.Builder().apply(block).build())
 4490   4524   
 4491   4525   
/**
 4492         -
 * This operation is not supported for directory buckets.
 4493         -
 *
 4494   4526   
 * Gets a metrics configuration (specified by the metrics configuration ID) from the bucket. Note that this doesn't include the daily storage metrics.
 4495   4527   
 *
        4528  +
 * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        4529  +
 *
        4530  +
 * ## Permissions
 4496   4531   
 *  To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        4532  +
 * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        4533  +
 * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        4534  +
 *
        4535  +
 * ## HTTP Host header syntax
        4536  +
 * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 4497   4537   
 *
 4498   4538   
 *  For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 4499   4539   
 *
 4500   4540   
 * The following operations are related to `GetBucketMetricsConfiguration`:
 4501   4541   
 * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 4502   4542   
 * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 4503   4543   
 * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 4504   4544   
 * + [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html)
 4505   4545   
 *
 4506   4546   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
@@ -4964,5004 +5030,5076 @@
 4984   5024   
 * The following operations are related to `ListBucketInventoryConfigurations`:
 4985   5025   
 * + [GetBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketInventoryConfiguration.html)
 4986   5026   
 * + [DeleteBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html)
 4987   5027   
 * + [PutBucketInventoryConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html)
 4988   5028   
 *
 4989   5029   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 4990   5030   
 */
 4991   5031   
public suspend inline fun S3Client.listBucketInventoryConfigurations(crossinline block: ListBucketInventoryConfigurationsRequest.Builder.() -> Unit): ListBucketInventoryConfigurationsResponse = listBucketInventoryConfigurations(ListBucketInventoryConfigurationsRequest.Builder().apply(block).build())
 4992   5032   
 4993   5033   
/**
 4994         -
 * This operation is not supported for directory buckets.
 4995         -
 *
 4996   5034   
 * Lists the metrics configurations for the bucket. The metrics configurations are only for the request metrics of the bucket and do not provide information on daily storage metrics. You can have up to 1,000 configurations per bucket.
 4997   5035   
 *
        5036  +
 * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        5037  +
 *
 4998   5038   
 * This action supports list pagination and does not return more than 100 configurations at a time. Always check the `IsTruncated` element in the response. If there are no more configurations to list, `IsTruncated` is set to false. If there are more configurations to list, `IsTruncated` is set to true, and there is a value in `NextContinuationToken`. You use the `NextContinuationToken` value to continue the pagination of the list by passing the value in `continuation-token` in the request to `GET` the next page.
 4999   5039   
 *
        5040  +
 * ## Permissions
 5000   5041   
 * To use this operation, you must have permissions to perform the `s3:GetMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        5042  +
 * + **General purpose bucket permissions** - The `s3:GetMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        5043  +
 * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:GetMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        5044  +
 *
        5045  +
 * ## HTTP Host header syntax
        5046  +
 * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 5001   5047   
 *
 5002   5048   
 * For more information about metrics configurations and CloudWatch request metrics, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 5003   5049   
 *
 5004   5050   
 * The following operations are related to `ListBucketMetricsConfigurations`:
 5005   5051   
 * + [PutBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html)
 5006   5052   
 * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 5007   5053   
 * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 5008   5054   
 *
 5009   5055   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 5010   5056   
 */
@@ -5511,5557 +5575,5627 @@
 5531   5577   
 * + [CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)
 5532   5578   
 * + [GetBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html)
 5533   5579   
 *
 5534   5580   
 * You must URL encode any signed header values that contain spaces. For example, if your header value is `my file.txt`, containing two spaces after `my`, you must URL encode this value to `my%20%20file.txt`.
 5535   5581   
 *
 5536   5582   
 * @sample aws.sdk.kotlin.services.s3.samples.PutBucketLogging.sample
 5537   5583   
 */
 5538   5584   
public suspend inline fun S3Client.putBucketLogging(crossinline block: PutBucketLoggingRequest.Builder.() -> Unit): PutBucketLoggingResponse = putBucketLogging(PutBucketLoggingRequest.Builder().apply(block).build())
 5539   5585   
 5540   5586   
/**
 5541         -
 * This operation is not supported for directory buckets.
 5542         -
 *
 5543   5587   
 * Sets a metrics configuration (specified by the metrics configuration ID) for the bucket. You can have up to 1,000 metrics configurations per bucket. If you're updating an existing metrics configuration, note that this is a full replacement of the existing metrics configuration. If you don't include the elements you want to keep, they are erased.
 5544   5588   
 *
        5589  +
 * **Directory buckets ** - For directory buckets, you must make requests for this API operation to the Regional endpoint. These endpoints support path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. For more information about endpoints in Availability Zones, see [Regional and Zonal endpoints for directory buckets in Availability Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/endpoint-directory-buckets-AZ.html) in the *Amazon S3 User Guide*. For more information about endpoints in Local Zones, see [Concepts for directory buckets in Local Zones](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-lzs-for-directory-buckets.html) in the *Amazon S3 User Guide*.
        5590  +
 *
        5591  +
 * ## Permissions
 5545   5592   
 * To use this operation, you must have permissions to perform the `s3:PutMetricsConfiguration` action. The bucket owner has this permission by default. The bucket owner can grant this permission to others. For more information about permissions, see [Permissions Related to Bucket Subresource Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources) and [Managing Access Permissions to Your Amazon S3 Resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html).
        5593  +
 * + **General purpose bucket permissions** - The `s3:PutMetricsConfiguration` permission is required in a policy. For more information about general purpose buckets permissions, see [Using Bucket Policies and User Policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html) in the *Amazon S3 User Guide*.
        5594  +
 * + **Directory bucket permissions** - To grant access to this API operation, you must have the `s3express:PutMetricsConfiguration` permission in an IAM identity-based policy instead of a bucket policy. Cross-account access to this API operation isn't supported. This operation can only be performed by the Amazon Web Services account that owns the resource. For more information about directory bucket policies and permissions, see [Amazon Web Services Identity and Access Management (IAM) for S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-security-iam.html) in the *Amazon S3 User Guide*.
        5595  +
 *
        5596  +
 * ## HTTP Host header syntax
        5597  +
 * **Directory buckets ** - The HTTP Host header syntax is `s3express-control.<i>region-code</i>.amazonaws.com`.
 5546   5598   
 *
 5547   5599   
 * For information about CloudWatch request metrics for Amazon S3, see [Monitoring Metrics with Amazon CloudWatch](https://docs.aws.amazon.com/AmazonS3/latest/dev/cloudwatch-monitoring.html).
 5548   5600   
 *
 5549   5601   
 * The following operations are related to `PutBucketMetricsConfiguration`:
 5550   5602   
 * + [DeleteBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html)
 5551   5603   
 * + [GetBucketMetricsConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetricsConfiguration.html)
 5552   5604   
 * + [ListBucketMetricsConfigurations](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html)
 5553   5605   
 *
 5554   5606   
 * `PutBucketMetricsConfiguration` has the following special error:
 5555   5607   
 * + Error code: `TooManyConfigurations`

tmp-codegen-diff/services/s3/generated-src/main/kotlin/aws/sdk/kotlin/services/s3/endpoints/internal/EndpointResolverAdapter.kt

@@ -678,678 +737,738 @@
  698    698   
    @Suppress("UNCHECKED_CAST")
  699    699   
    val input = request.context[HttpOperationContext.OperationInput] as ListBucketInventoryConfigurationsRequest
  700    700   
    builder.bucket = input.bucket
  701    701   
    builder.useS3ExpressControlEndpoint = true
  702    702   
}
  703    703   
  704    704   
private fun bindListBucketMetricsConfigurationsEndpointContext(builder: S3EndpointParameters.Builder, request: ResolveEndpointRequest): Unit {
  705    705   
    @Suppress("UNCHECKED_CAST")
  706    706   
    val input = request.context[HttpOperationContext.OperationInput] as ListBucketMetricsConfigurationsRequest
  707    707   
    builder.bucket = input.bucket
         708  +
    builder.useS3ExpressControlEndpoint = true
  708    709   
}
  709    710   
  710    711   
private fun bindListDirectoryBucketsEndpointContext(builder: S3EndpointParameters.Builder, request: ResolveEndpointRequest): Unit {
  711    712   
    builder.useS3ExpressControlEndpoint = true
  712    713   
}
  713    714   
  714    715   
private fun bindListMultipartUploadsEndpointContext(builder: S3EndpointParameters.Builder, request: ResolveEndpointRequest): Unit {
  715    716   
    @Suppress("UNCHECKED_CAST")
  716    717   
    val input = request.context[HttpOperationContext.OperationInput] as ListMultipartUploadsRequest
  717    718   
    builder.bucket = input.bucket

tmp-codegen-diff/services/s3/generated-src/main/kotlin/aws/sdk/kotlin/services/s3/model/BucketLocationConstraint.kt

@@ -1,1 +109,129 @@
   15     15   
    public object AfSouth1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   16     16   
        override val value: kotlin.String = "af-south-1"
   17     17   
        override fun toString(): kotlin.String = "AfSouth1"
   18     18   
    }
   19     19   
   20     20   
    public object ApEast1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   21     21   
        override val value: kotlin.String = "ap-east-1"
   22     22   
        override fun toString(): kotlin.String = "ApEast1"
   23     23   
    }
   24     24   
          25  +
    public object ApEast2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
          26  +
        override val value: kotlin.String = "ap-east-2"
          27  +
        override fun toString(): kotlin.String = "ApEast2"
          28  +
    }
          29  +
   25     30   
    public object ApNortheast1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   26     31   
        override val value: kotlin.String = "ap-northeast-1"
   27     32   
        override fun toString(): kotlin.String = "ApNortheast1"
   28     33   
    }
   29     34   
   30     35   
    public object ApNortheast2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   31     36   
        override val value: kotlin.String = "ap-northeast-2"
   32     37   
        override fun toString(): kotlin.String = "ApNortheast2"
   33     38   
    }
   34     39   
   35     40   
    public object ApNortheast3 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   36     41   
        override val value: kotlin.String = "ap-northeast-3"
   37     42   
        override fun toString(): kotlin.String = "ApNortheast3"
   38     43   
    }
   39     44   
   40     45   
    public object ApSouth1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   41     46   
        override val value: kotlin.String = "ap-south-1"
   42     47   
        override fun toString(): kotlin.String = "ApSouth1"
   43     48   
    }
   44     49   
   45     50   
    public object ApSouth2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   46     51   
        override val value: kotlin.String = "ap-south-2"
   47     52   
        override fun toString(): kotlin.String = "ApSouth2"
   48     53   
    }
   49     54   
   50     55   
    public object ApSoutheast1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   51     56   
        override val value: kotlin.String = "ap-southeast-1"
   52     57   
        override fun toString(): kotlin.String = "ApSoutheast1"
   53     58   
    }
   54     59   
   55     60   
    public object ApSoutheast2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   56     61   
        override val value: kotlin.String = "ap-southeast-2"
   57     62   
        override fun toString(): kotlin.String = "ApSoutheast2"
   58     63   
    }
   59     64   
   60     65   
    public object ApSoutheast3 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   61     66   
        override val value: kotlin.String = "ap-southeast-3"
   62     67   
        override fun toString(): kotlin.String = "ApSoutheast3"
   63     68   
    }
   64     69   
   65     70   
    public object ApSoutheast4 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   66     71   
        override val value: kotlin.String = "ap-southeast-4"
   67     72   
        override fun toString(): kotlin.String = "ApSoutheast4"
   68     73   
    }
   69     74   
   70     75   
    public object ApSoutheast5 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   71     76   
        override val value: kotlin.String = "ap-southeast-5"
   72     77   
        override fun toString(): kotlin.String = "ApSoutheast5"
   73     78   
    }
   74     79   
          80  +
    public object ApSoutheast6 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
          81  +
        override val value: kotlin.String = "ap-southeast-6"
          82  +
        override fun toString(): kotlin.String = "ApSoutheast6"
          83  +
    }
          84  +
          85  +
    public object ApSoutheast7 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
          86  +
        override val value: kotlin.String = "ap-southeast-7"
          87  +
        override fun toString(): kotlin.String = "ApSoutheast7"
          88  +
    }
          89  +
   75     90   
    public object CaCentral1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   76     91   
        override val value: kotlin.String = "ca-central-1"
   77     92   
        override fun toString(): kotlin.String = "CaCentral1"
   78     93   
    }
   79     94   
          95  +
    public object CaWest1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
          96  +
        override val value: kotlin.String = "ca-west-1"
          97  +
        override fun toString(): kotlin.String = "CaWest1"
          98  +
    }
          99  +
   80    100   
    public object CnNorth1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   81    101   
        override val value: kotlin.String = "cn-north-1"
   82    102   
        override fun toString(): kotlin.String = "CnNorth1"
   83    103   
    }
   84    104   
   85    105   
    public object CnNorthwest1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
   86    106   
        override val value: kotlin.String = "cn-northwest-1"
   87    107   
        override fun toString(): kotlin.String = "CnNorthwest1"
   88    108   
    }
   89    109   
@@ -115,135 +261,296 @@
  135    155   
    public object MeCentral1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  136    156   
        override val value: kotlin.String = "me-central-1"
  137    157   
        override fun toString(): kotlin.String = "MeCentral1"
  138    158   
    }
  139    159   
  140    160   
    public object MeSouth1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  141    161   
        override val value: kotlin.String = "me-south-1"
  142    162   
        override fun toString(): kotlin.String = "MeSouth1"
  143    163   
    }
  144    164   
         165  +
    public object MxCentral1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
         166  +
        override val value: kotlin.String = "mx-central-1"
         167  +
        override fun toString(): kotlin.String = "MxCentral1"
         168  +
    }
         169  +
  145    170   
    public object SaEast1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  146    171   
        override val value: kotlin.String = "sa-east-1"
  147    172   
        override fun toString(): kotlin.String = "SaEast1"
  148    173   
    }
  149    174   
  150    175   
    public object UsEast2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  151    176   
        override val value: kotlin.String = "us-east-2"
  152    177   
        override fun toString(): kotlin.String = "UsEast2"
  153    178   
    }
  154    179   
  155    180   
    public object UsGovEast1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  156    181   
        override val value: kotlin.String = "us-gov-east-1"
  157    182   
        override fun toString(): kotlin.String = "UsGovEast1"
  158    183   
    }
  159    184   
  160    185   
    public object UsGovWest1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  161    186   
        override val value: kotlin.String = "us-gov-west-1"
  162    187   
        override fun toString(): kotlin.String = "UsGovWest1"
  163    188   
    }
  164    189   
  165    190   
    public object UsWest1 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  166    191   
        override val value: kotlin.String = "us-west-1"
  167    192   
        override fun toString(): kotlin.String = "UsWest1"
  168    193   
    }
  169    194   
  170    195   
    public object UsWest2 : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  171    196   
        override val value: kotlin.String = "us-west-2"
  172    197   
        override fun toString(): kotlin.String = "UsWest2"
  173    198   
    }
  174    199   
  175    200   
    public data class SdkUnknown(override val value: kotlin.String) : aws.sdk.kotlin.services.s3.model.BucketLocationConstraint() {
  176    201   
        override fun toString(): kotlin.String = "SdkUnknown($value)"
  177    202   
    }
  178    203   
  179    204   
    public companion object {
  180    205   
        /**
  181    206   
         * Convert a raw value to one of the sealed variants or [SdkUnknown]
  182    207   
         */
  183    208   
        public fun fromValue(value: kotlin.String): aws.sdk.kotlin.services.s3.model.BucketLocationConstraint = when (value) {
  184    209   
            "EU" -> Eu
  185    210   
            "af-south-1" -> AfSouth1
  186    211   
            "ap-east-1" -> ApEast1
         212  +
            "ap-east-2" -> ApEast2
  187    213   
            "ap-northeast-1" -> ApNortheast1
  188    214   
            "ap-northeast-2" -> ApNortheast2
  189    215   
            "ap-northeast-3" -> ApNortheast3
  190    216   
            "ap-south-1" -> ApSouth1
  191    217   
            "ap-south-2" -> ApSouth2
  192    218   
            "ap-southeast-1" -> ApSoutheast1
  193    219   
            "ap-southeast-2" -> ApSoutheast2
  194    220   
            "ap-southeast-3" -> ApSoutheast3
  195    221   
            "ap-southeast-4" -> ApSoutheast4
  196    222   
            "ap-southeast-5" -> ApSoutheast5
         223  +
            "ap-southeast-6" -> ApSoutheast6
         224  +
            "ap-southeast-7" -> ApSoutheast7
  197    225   
            "ca-central-1" -> CaCentral1
         226  +
            "ca-west-1" -> CaWest1
  198    227   
            "cn-north-1" -> CnNorth1
  199    228   
            "cn-northwest-1" -> CnNorthwest1
  200    229   
            "eu-central-1" -> EuCentral1
  201    230   
            "eu-central-2" -> EuCentral2
  202    231   
            "eu-north-1" -> EuNorth1
  203    232   
            "eu-south-1" -> EuSouth1
  204    233   
            "eu-south-2" -> EuSouth2
  205    234   
            "eu-west-1" -> EuWest1
  206    235   
            "eu-west-2" -> EuWest2
  207    236   
            "eu-west-3" -> EuWest3
  208    237   
            "il-central-1" -> IlCentral1
  209    238   
            "me-central-1" -> MeCentral1
  210    239   
            "me-south-1" -> MeSouth1
         240  +
            "mx-central-1" -> MxCentral1
  211    241   
            "sa-east-1" -> SaEast1
  212    242   
            "us-east-2" -> UsEast2
  213    243   
            "us-gov-east-1" -> UsGovEast1
  214    244   
            "us-gov-west-1" -> UsGovWest1
  215    245   
            "us-west-1" -> UsWest1
  216    246   
            "us-west-2" -> UsWest2
  217    247   
            else -> SdkUnknown(value)
  218    248   
        }
  219    249   
  220    250   
        /**
  221    251   
         * Get a list of all possible variants
  222    252   
         */
  223    253   
        public fun values(): kotlin.collections.List<aws.sdk.kotlin.services.s3.model.BucketLocationConstraint> = values
  224    254   
  225    255   
        private val values: kotlin.collections.List<aws.sdk.kotlin.services.s3.model.BucketLocationConstraint> = listOf(
  226    256   
            Eu,
  227    257   
            AfSouth1,
  228    258   
            ApEast1,
         259  +
            ApEast2,
  229    260   
            ApNortheast1,
  230    261   
            ApNortheast2,
  231    262   
            ApNortheast3,
  232    263   
            ApSouth1,
  233    264   
            ApSouth2,
  234    265   
            ApSoutheast1,
  235    266   
            ApSoutheast2,
  236    267   
            ApSoutheast3,
  237    268   
            ApSoutheast4,
  238    269   
            ApSoutheast5,
         270  +
            ApSoutheast6,
         271  +
            ApSoutheast7,
  239    272   
            CaCentral1,
         273  +
            CaWest1,
  240    274   
            CnNorth1,
  241    275   
            CnNorthwest1,
  242    276   
            EuCentral1,
  243    277   
            EuCentral2,
  244    278   
            EuNorth1,
  245    279   
            EuSouth1,
  246    280   
            EuSouth2,
  247    281   
            EuWest1,
  248    282   
            EuWest2,
  249    283   
            EuWest3,
  250    284   
            IlCentral1,
  251    285   
            MeCentral1,
  252    286   
            MeSouth1,
         287  +
            MxCentral1,
  253    288   
            SaEast1,
  254    289   
            UsEast2,
  255    290   
            UsGovEast1,
  256    291   
            UsGovWest1,
  257    292   
            UsWest1,
  258    293   
            UsWest2,
  259    294   
        )
  260    295   
    }
  261    296   
}

tmp-codegen-diff/services/s3/generated-src/main/kotlin/aws/sdk/kotlin/services/s3/model/DeleteBucketMetricsConfigurationRequest.kt

@@ -1,1 +87,95 @@
    1      1   
// Code generated by smithy-kotlin codegen. DO NOT EDIT!
    2      2   
    3      3   
package aws.sdk.kotlin.services.s3.model
    4      4   
    5      5   
import aws.smithy.kotlin.runtime.SdkDsl
    6      6   
    7      7   
    8      8   
public class DeleteBucketMetricsConfigurationRequest private constructor(builder: Builder) {
    9      9   
    /**
   10     10   
     * The name of the bucket containing the metrics configuration to delete.
          11  +
     *
          12  +
     * **Directory buckets ** - When you use this operation with a directory bucket, you must use path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. Directory bucket names must be unique in the chosen Zone (Availability Zone or Local Zone). Bucket names must also follow the format ` <i>bucket-base-name</i>--<i>zone-id</i>--x-s3` (for example, ` <i>DOC-EXAMPLE-BUCKET</i>--<i>usw2-az1</i>--x-s3`). For information about bucket naming restrictions, see [Directory bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-bucket-naming-rules.html) in the *Amazon S3 User Guide*
   11     13   
     */
   12     14   
    public val bucket: kotlin.String? = builder.bucket
   13     15   
    /**
   14     16   
     * The account ID of the expected bucket owner. If the account ID that you provide does not match the actual owner of the bucket, the request fails with the HTTP status code `403 Forbidden` (access denied).
          17  +
     *
          18  +
     * For directory buckets, this header is not supported in this API operation. If you specify this header, the request fails with the HTTP status code `501 Not Implemented`.
   15     19   
     */
   16     20   
    public val expectedBucketOwner: kotlin.String? = builder.expectedBucketOwner
   17     21   
    /**
   18     22   
     * The ID used to identify the metrics configuration. The ID has a 64 character limit and can only contain letters, numbers, periods, dashes, and underscores.
   19     23   
     */
   20     24   
    public val id: kotlin.String? = builder.id
   21     25   
   22     26   
    public companion object {
   23     27   
        public operator fun invoke(block: Builder.() -> kotlin.Unit): aws.sdk.kotlin.services.s3.model.DeleteBucketMetricsConfigurationRequest = Builder().apply(block).build()
   24     28   
    }
   25     29   
   26     30   
    override fun toString(): kotlin.String = buildString {
   27     31   
        append("DeleteBucketMetricsConfigurationRequest(")
   28     32   
        append("bucket=$bucket,")
   29     33   
        append("expectedBucketOwner=$expectedBucketOwner,")
   30     34   
        append("id=$id")
   31     35   
        append(")")
   32     36   
    }
   33     37   
   34     38   
    override fun hashCode(): kotlin.Int {
   35     39   
        var result = bucket?.hashCode() ?: 0
   36     40   
        result = 31 * result + (this.expectedBucketOwner?.hashCode() ?: 0)
   37     41   
        result = 31 * result + (this.id?.hashCode() ?: 0)
   38     42   
        return result
   39     43   
    }
   40     44   
   41     45   
    override fun equals(other: kotlin.Any?): kotlin.Boolean {
   42     46   
        if (this === other) return true
   43     47   
        if (other == null || this::class != other::class) return false
   44     48   
   45     49   
        other as DeleteBucketMetricsConfigurationRequest
   46     50   
   47     51   
        if (bucket != other.bucket) return false
   48     52   
        if (expectedBucketOwner != other.expectedBucketOwner) return false
   49     53   
        if (id != other.id) return false
   50     54   
   51     55   
        return true
   52     56   
    }
   53     57   
   54     58   
    public inline fun copy(block: Builder.() -> kotlin.Unit = {}): aws.sdk.kotlin.services.s3.model.DeleteBucketMetricsConfigurationRequest = Builder(this).apply(block).build()
   55     59   
   56     60   
    @SdkDsl
   57     61   
    public class Builder {
   58     62   
        /**
   59     63   
         * The name of the bucket containing the metrics configuration to delete.
          64  +
         *
          65  +
         * **Directory buckets ** - When you use this operation with a directory bucket, you must use path-style requests in the format `https://s3express-control.<i>region-code</i>.amazonaws.com/<i>bucket-name</i> `. Virtual-hosted-style requests aren't supported. Directory bucket names must be unique in the chosen Zone (Availability Zone or Local Zone). Bucket names must also follow the format ` <i>bucket-base-name</i>--<i>zone-id</i>--x-s3` (for example, ` <i>DOC-EXAMPLE-BUCKET</i>--<i>usw2-az1</i>--x-s3`). For information about bucket naming restrictions, see [Directory bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/directory-bucket-naming-rules.html) in the *Amazon S3 User Guide*
   60     66   
         */
   61     67   
        public var bucket: kotlin.String? = null
   62     68   
        /**
   63     69   
         * The account ID of the expected bucket owner. If the account ID that you provide does not match the actual owner of the bucket, the request fails with the HTTP status code `403 Forbidden` (access denied).
          70  +
         *
          71  +
         * For directory buckets, this header is not supported in this API operation. If you specify this header, the request fails with the HTTP status code `501 Not Implemented`.
   64     72   
         */
   65     73   
        public var expectedBucketOwner: kotlin.String? = null
   66     74   
        /**
   67     75   
         * The ID used to identify the metrics configuration. The ID has a 64 character limit and can only contain letters, numbers, periods, dashes, and underscores.
   68     76   
         */
   69     77   
        public var id: kotlin.String? = null
   70     78   
   71     79   
        @PublishedApi
   72     80   
        internal constructor()
   73     81   
        @PublishedApi