diff --git a/docs/source-2.0/aws/aws-iam.rst b/docs/source-2.0/aws/aws-iam.rst index f6e4f1a13c9..6b0ea2997d5 100644 --- a/docs/source-2.0/aws/aws-iam.rst +++ b/docs/source-2.0/aws/aws-iam.rst @@ -392,6 +392,48 @@ deviates from the :ref:`shape name of the shape ID ` of the resource. } } +.. smithy-trait:: aws.iam#actionName +.. _aws.iam#actionName-trait: + +---------------------------- +``aws.iam#actionName`` trait +---------------------------- + +Summary + Provides a custom IAM action name. +Trait selector + ``operation`` +Value type + ``string`` + +Operations not annotated with the ``actionName`` trait, default to the +:ref:`shape name of the shape ID ` of the targeted operation. + +The following example defines two operations: + +* ``OperationA`` is not annotated with the ``actionName`` trait, and + resolves the action name of ``OperationA``. +* ``OperationB`` has the ``actionName`` trait, so has the action + name ``OverridingActionName``. + +.. code-block:: smithy + + $version: "2" + + namespace smithy.example + + use aws.iam#actionName + + service MyService { + version: "2020-07-02" + operations: [OperationA, OperationB] + } + + operation OperationA {} + + @actionName("OverridingActionName") + operation OperationB {} + .. _deriving-condition-keys: diff --git a/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ActionNameTrait.java b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ActionNameTrait.java new file mode 100644 index 00000000000..da8e0936cb1 --- /dev/null +++ b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ActionNameTrait.java @@ -0,0 +1,30 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.aws.iam.traits; + +import software.amazon.smithy.model.FromSourceLocation; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.traits.StringTrait; + +public final class ActionNameTrait extends StringTrait { + + public static final ShapeId ID = ShapeId.from("aws.iam#actionName"); + + private ActionNameTrait(String action) { + super(ID, action, SourceLocation.NONE); + } + + private ActionNameTrait(String action, FromSourceLocation sourceLocation) { + super(ID, action, sourceLocation); + } + + public static final class Provider extends StringTrait.Provider { + public Provider() { + super(ID, ActionNameTrait::new); + } + } +} diff --git a/smithy-aws-iam-traits/src/main/resources/META-INF/services/software.amazon.smithy.model.traits.TraitService b/smithy-aws-iam-traits/src/main/resources/META-INF/services/software.amazon.smithy.model.traits.TraitService index 2a7e55f614d..2b8be5d132b 100644 --- a/smithy-aws-iam-traits/src/main/resources/META-INF/services/software.amazon.smithy.model.traits.TraitService +++ b/smithy-aws-iam-traits/src/main/resources/META-INF/services/software.amazon.smithy.model.traits.TraitService @@ -5,3 +5,4 @@ software.amazon.smithy.aws.iam.traits.DisableConditionKeyInferenceTrait$Provider software.amazon.smithy.aws.iam.traits.RequiredActionsTrait$Provider software.amazon.smithy.aws.iam.traits.SupportedPrincipalTypesTrait$Provider software.amazon.smithy.aws.iam.traits.IamResourceTrait$Provider +software.amazon.smithy.aws.iam.traits.ActionNameTrait$Provider diff --git a/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.json b/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.json index 1e27fc5af0d..62008770e52 100644 --- a/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.json +++ b/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.json @@ -264,6 +264,18 @@ "smithy.api#private": {}, "smithy.api#documentation": "An IAM policy principal type." } + }, + "aws.iam#actionName": { + "type": "string", + "member": { + "target": "aws.iam#IamIdentifier" + }, + "traits": { + "smithy.api#trait": { + "selector": "operation" + }, + "smithy.api#documentation": "Provides a custom IAM action name. By default, the action name is the same as the operation name." + } } } } diff --git a/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ActionNameTraitTest.java b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ActionNameTraitTest.java new file mode 100644 index 00000000000..0b39e3b1cd4 --- /dev/null +++ b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ActionNameTraitTest.java @@ -0,0 +1,29 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.aws.iam.traits; + +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +public class ActionNameTraitTest { + @Test + public void loadsFromModel() { + Model result = Model.assembler() + .discoverModels(getClass().getClassLoader()) + .addImport(getClass().getResource("actionname-override.smithy")) + .assemble() + .unwrap(); + + Shape shape = result.expectShape(ShapeId.from("smithy.example#Echo")); + ActionNameTrait trait = shape.expectTrait(ActionNameTrait.class); + assertThat(trait.getValue(), equalTo("overridingActionName")); + } +} diff --git a/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/actionname-override.smithy b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/actionname-override.smithy new file mode 100644 index 00000000000..d4ddbb65528 --- /dev/null +++ b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/actionname-override.smithy @@ -0,0 +1,16 @@ +$version: "2.0" +namespace smithy.example + +@aws.iam#actionName("overridingActionName") +operation Echo {} + +operation GetResource2 { + input: GetResource2Input +} + +structure GetResource2Input { + id1: String, + + @required + id2: String +}