Unverified Commit 8676d8dc authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Customize S3 `Size` to use correct integer size (#679)

* Clean up `sync-models.py`

* Add hack to `sync-models.py` to correct the S3 model

* Add disabled S3 customization

* Run S3 model through `jq .` to make diffing nicer

* Sync S3 model

* Add integration test for the customization

* Update changelog
parent 8c268fe1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ vNext (Month Day, Year)
- Add support for shared configuration between multiple services (#673)
- Update AWS SDK models (#677)
- :bug: Fix sigv4 signing when request ALPN negotiates to HTTP/2. (#674)
- :bug: Fix integer size on S3 `Size` (#679, aws-sdk-rust#209)

**Internal Changes**
- Add NowOrLater future to smithy-async (#672)
+24 −0
Original line number Diff line number Diff line
@@ -6,8 +6,12 @@
package software.amazon.smithy.rustsdk.customize.s3

import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.IntegerShape
import software.amazon.smithy.model.shapes.LongShape
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.asType
@@ -54,6 +58,11 @@ class S3Decorator : RustCodegenDecorator {
            it + S3PubUse()
        }
    }

    // TODO: Uncomment once https://github.com/awslabs/smithy/pull/900 is merged and
    // the latest Smithy is pulled in.
    // override fun transformModel(service: ServiceShape, model: Model): Model =
    //     S3CorrectSizeIntegerType().transform(model)
}

class S3(protocolConfig: ProtocolConfig) : RestXml(protocolConfig) {
@@ -100,3 +109,18 @@ class S3PubUse : LibRsCustomization() {
        else -> emptySection
    }
}

/** `com.amazonaws.s3#Size` is modeled as `integer`, which is too small for file sizes */
class S3CorrectSizeIntegerType {
    companion object {
        val SIZE_SHAPE_ID = ShapeId.from("com.amazonaws.s3#Size")
    }

    fun transform(model: Model): Model = ModelTransformer.create().mapShapes(model) { shape ->
        if (shape is IntegerShape && shape.id == SIZE_SHAPE_ID) {
            LongShape.builder().id(shape.id).source(shape.sourceLocation).traits(shape.allTraits.values).build()
        } else {
            shape
        }
    }
}
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

package software.amazon.smithy.rustsdk.customize.s3

import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel

class S3DecoratorTest {
    @Nested
    inner class S3CorrectSizeIntegerTypeTest {
        // TODO: Re-enable test below once https://github.com/awslabs/smithy/pull/900 is merged and
        // the latest Smithy is pulled in.
        @Disabled
        @Test
        fun `it should make Size a Long`() {
            val model = """
                namespace com.amazonaws.s3

                // The actual model doesn't have traits, but make sure we copy them to stay future-proof
                @range(min: 0)
                integer Size

                structure Object {
                    size: Size,
                }
            """.asSmithyModel()

            // Precondition: make sure the test model is correct
            val oldSize = model.expectShape(S3CorrectSizeIntegerType.SIZE_SHAPE_ID)

            val transformed = S3CorrectSizeIntegerType().transform(model)
            val newSize = transformed.expectShape(S3CorrectSizeIntegerType.SIZE_SHAPE_ID)
            newSize.isLongShape shouldBe true
            newSize.allTraits shouldBe oldSize.allTraits
            newSize.sourceLocation shouldBe oldSize.sourceLocation

            transformed.expectShape(ShapeId.from("com.amazonaws.s3#Object")).members().first().isLongShape shouldBe true
        }
    }
}
+13217 −13217
Original line number Diff line number Diff line
@@ -12101,7 +12101,7 @@
      "type": "boolean"
    },
    "com.amazonaws.s3#Size": {
            "type": "integer"
      "type": "long"
    },
    "com.amazonaws.s3#SourceSelectionCriteria": {
      "type": "structure",
+16 −0
Original line number Diff line number Diff line
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use aws_sdk_s3::model::Object;

// Tests that `com.amazonaws.s3#Size` is correctly customized to be a long instead of an int.
#[test]
fn size_type() {
    let size = i64::MAX;

    // Should only compile if the type is correctly customized
    let object = Object::builder().size(size).build();
    assert_eq!(size, object.size);
}
Loading