From 33f0010ea18847154c0b3420a6b12a7b959e8a86 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Tue, 22 Apr 2025 15:04:30 -0700 Subject: [PATCH 1/6] Duplicate all eventstream event shapes + add new legacy event modes --- .../DefaultCustomizationProcessor.java | 1 + .../EventStreamSharedEventProcessor.java | 71 ++++++ ...eLegacyEventGenerationSchemeProcessor.java | 19 +- .../customization/CustomizationConfig.java | 7 +- .../LegacyEventGenerationMode.java | 25 ++ .../poet/model/EventStreamSpecHelper.java | 12 +- ...acyEventGenerationSchemeProcessorTest.java | 10 +- .../happy-case-customization.config | 2 +- .../multiple-event-types-same-shape.config | 5 +- .../poet/client/c2j/cbor/customization.config | 12 +- .../poet/client/c2j/json/customization.config | 16 +- .../client/c2j/rest-json/customization.config | 12 +- .../poet/eventstream/customization.config | 13 + .../codegen/poet/model/customization.config | 13 +- .../poet/model/sharedstream/eventstream.java | 2 +- .../{person.java => personeventstream.java} | 33 +-- .../personstreambirthsinputeventstream.java | 240 ++++++++++++++++++ .../personstreamdeathsinputeventstream.java | 240 ++++++++++++++++++ .../poet/model/sharedstream/service-2.json | 54 ++++ .../streambirthsinputeventstream.java | 79 ++++++ .../streambirthsinputrequest.java | 139 ++++++++++ .../streambirthsinputresponse.java | 118 +++++++++ .../streamdeathsinputeventstream.java | 79 ++++++ .../streamdeathsinputrequest.java | 139 ++++++++++ .../streamdeathsinputresponse.java | 118 +++++++++ .../poet/transform/customization.config | 9 + .../codegen-resources/customization.config | 2 +- .../codegen-resources/customization.config | 6 +- 28 files changed, 1423 insertions(+), 53 deletions(-) create mode 100644 codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java create mode 100644 codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/LegacyEventGenerationMode.java rename codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/{person.java => personeventstream.java} (87%) create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreambirthsinputeventstream.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreamdeathsinputeventstream.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputeventstream.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputrequest.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputresponse.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputeventstream.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputrequest.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputresponse.java diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java index 0e09eca03747..7c12dd573a27 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java @@ -37,6 +37,7 @@ public static CodegenCustomizationProcessor getProcessorFor( new SmithyRpcV2CborProtocolProcessor(), new RemoveExceptionMessagePropertyProcessor(), new UseLegacyEventGenerationSchemeProcessor(), + new EventStreamSharedEventProcessor(config.getUseLegacyEventGenerationScheme()), new NewAndLegacyEventStreamProcessor(), new S3RemoveBucketFromUriProcessor(), new S3ControlRemoveAccountIdHostPrefixProcessor(), diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java new file mode 100644 index 000000000000..be70f95efaec --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java @@ -0,0 +1,71 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.codegen.customization.processors; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor; +import software.amazon.awssdk.codegen.model.config.customization.LegacyEventGenerationMode; +import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; +import software.amazon.awssdk.codegen.model.service.Member; +import software.amazon.awssdk.codegen.model.service.ServiceModel; +import software.amazon.awssdk.codegen.model.service.Shape; + +/** + * Processor for eventstreams with shared events. This Processor does two things: 1. Apply the duplicateAndRenameSharedEvents + * customization 2. Raise helpful error messages on untransfromed shared events. + */ +public final class EventStreamSharedEventProcessor implements CodegenCustomizationProcessor { + private static final Logger log = LoggerFactory.getLogger(EventStreamSharedEventProcessor.class); + + private final Map> useLegacyEventGenerationScheme; + + public EventStreamSharedEventProcessor(Map> useLegacyEventGenerationScheme) { + this.useLegacyEventGenerationScheme = useLegacyEventGenerationScheme; + } + + @Override + public void preprocess(ServiceModel serviceModel) { + Map newEventShapes = new HashMap<>(); + for (Map.Entry shapeEntry : serviceModel.getShapes().entrySet()) { + if (shapeEntry.getValue().isEventstream()) { + Shape eventStreamShape = shapeEntry.getValue(); + Map eventLegacyModes = useLegacyEventGenerationScheme + .getOrDefault(shapeEntry.getKey(), Collections.emptyMap()); + for (Map.Entry memberEntry : eventStreamShape.getMembers().entrySet()) { + Shape memberTargetShape = serviceModel.getShape(memberEntry.getValue().getShape()); + LegacyEventGenerationMode legacyEventGenerationMode = eventLegacyModes + .getOrDefault(memberEntry.getKey(), LegacyEventGenerationMode.DISABLED); + + if (memberTargetShape.isEvent() && legacyEventGenerationMode == LegacyEventGenerationMode.DISABLED) { + String newShapeName = memberEntry.getValue().getShape() + shapeEntry.getKey(); + newEventShapes.put(newShapeName, memberTargetShape); + memberEntry.getValue().setShape(newShapeName); + } + } + } + } + serviceModel.getShapes().putAll(newEventShapes); + } + + @Override + public void postprocess(IntermediateModel intermediateModel) { + // no-op + } +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessor.java index fcb51cc3f8f7..d4e7cd9dee15 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessor.java @@ -16,11 +16,11 @@ package software.amazon.awssdk.codegen.customization.processors; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor; +import software.amazon.awssdk.codegen.model.config.customization.LegacyEventGenerationMode; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; @@ -42,9 +42,8 @@ public void preprocess(ServiceModel serviceModel) { @Override public void postprocess(IntermediateModel intermediateModel) { - Map> useLegacyEventGenerationScheme = intermediateModel.getCustomizationConfig() - .getUseLegacyEventGenerationScheme(); - + Map> useLegacyEventGenerationScheme = + intermediateModel.getCustomizationConfig().getUseLegacyEventGenerationScheme(); useLegacyEventGenerationScheme.forEach((eventStream, members) -> { ShapeModel shapeModel = getShapeByC2jName(intermediateModel, eventStream); @@ -56,13 +55,15 @@ public void postprocess(IntermediateModel intermediateModel) { Map shapeToEventCount = new HashMap<>(); - members.forEach(m -> { + members.forEach((m, legacyEventGenerationMode) -> { MemberModel event = shapeModel.getMemberByC2jName(m); if (event != null) { - String shapeName = event.getC2jShape(); - int count = shapeToEventCount.getOrDefault(shapeName, 0); - shapeToEventCount.put(shapeName, ++count); + if (legacyEventGenerationMode == LegacyEventGenerationMode.NO_EVENT_SUBCLASS) { + String shapeName = event.getC2jShape(); + int count = shapeToEventCount.getOrDefault(shapeName, 0); + shapeToEventCount.put(shapeName, ++count); + } } else { String msg = String.format("Encountered %s customization for unrecognized eventstream member %s#%s", CUSTOMIZATION_NAME, eventStream, m); @@ -73,7 +74,7 @@ public void postprocess(IntermediateModel intermediateModel) { shapeToEventCount.forEach((shape, count) -> { if (count > 1) { throw new IllegalArgumentException(CUSTOMIZATION_NAME + " customization declared for " - + eventStream + ", but more than it targets more than one member with the shape " + shape); + + eventStream + ", but it targets more than one member with the shape " + shape); } }); }); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java index 32cecd79feb5..5e4af45c72e9 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java @@ -208,7 +208,7 @@ public class CustomizationConfig { * generation scheme for the visitor methods was changed. There should be no good reason to use this customization * for any other purpose. */ - private Map> useLegacyEventGenerationScheme = new HashMap<>(); + private Map> useLegacyEventGenerationScheme = new HashMap<>(); /** * How the code generator should behave when it encounters shapes with underscores in the name. @@ -646,11 +646,12 @@ public void setAllowEndpointOverrideForEndpointDiscoveryRequiredOperations( allowEndpointOverrideForEndpointDiscoveryRequiredOperations; } - public Map> getUseLegacyEventGenerationScheme() { + public Map> getUseLegacyEventGenerationScheme() { return useLegacyEventGenerationScheme; } - public void setUseLegacyEventGenerationScheme(Map> useLegacyEventGenerationScheme) { + public void setUseLegacyEventGenerationScheme( + Map> useLegacyEventGenerationScheme) { this.useLegacyEventGenerationScheme = useLegacyEventGenerationScheme; } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/LegacyEventGenerationMode.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/LegacyEventGenerationMode.java new file mode 100644 index 000000000000..a30b0aeed305 --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/LegacyEventGenerationMode.java @@ -0,0 +1,25 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.codegen.model.config.customization; + +/** + * Legacy event generation modes. + */ +public enum LegacyEventGenerationMode { + DISABLED, + NO_EVENT_SUBCLASS, // old legacy - do not generate subclasses of events + NO_UNIQUE_EVENT_NAMES // new legacy - do not duplicate event shapes to ensure unique events +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/EventStreamSpecHelper.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/EventStreamSpecHelper.java index 6569e775d013..f9db376de74e 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/EventStreamSpecHelper.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/EventStreamSpecHelper.java @@ -19,10 +19,10 @@ import com.squareup.javapoet.ClassName; import com.squareup.javapoet.TypeSpec; -import java.util.List; import java.util.Locale; import java.util.Map; import javax.lang.model.element.Modifier; +import software.amazon.awssdk.codegen.model.config.customization.LegacyEventGenerationMode; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; @@ -56,16 +56,16 @@ public String eventPackageName() { } public boolean useLegacyGenerationScheme(MemberModel event) { - Map> useLegacyEventGenerationScheme = intermediateModel.getCustomizationConfig() - .getUseLegacyEventGenerationScheme(); + Map> useLegacyEventGenerationScheme = + intermediateModel.getCustomizationConfig().getUseLegacyEventGenerationScheme(); - List targetEvents = useLegacyEventGenerationScheme.get(eventStream.getC2jName()); + Map targetEvents = useLegacyEventGenerationScheme.get(eventStream.getC2jName()); - if (targetEvents == null) { + if (targetEvents == null || !targetEvents.containsKey(event.getC2jName())) { return false; } - return targetEvents.stream().anyMatch(e -> e.equals(event.getC2jName())); + return targetEvents.get(event.getC2jName()).equals(LegacyEventGenerationMode.NO_EVENT_SUBCLASS); } public ClassName eventClassName(MemberModel eventModel) { diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessorTest.java b/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessorTest.java index ff041882bbc7..a49acc9537da 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessorTest.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/UseLegacyEventGenerationSchemeProcessorTest.java @@ -17,7 +17,7 @@ import java.io.File; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -39,11 +39,11 @@ public class UseLegacyEventGenerationSchemeProcessorTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static ServiceModel serviceModel; + private ServiceModel serviceModel; - @BeforeClass - public static void setup() { + @Before + public void setup() { String c2jFilePath = UseLegacyEventGenerationSchemeProcessorTest.class.getResource(RESOURCE_ROOT + "/service-2.json").getFile(); File c2jFile = new File(c2jFilePath); @@ -67,7 +67,7 @@ public void testPostProcess_customizationIsValid_succeeds() { } - private static IntermediateModel intermediateModelWithConfig(String configName) { + private IntermediateModel intermediateModelWithConfig(String configName) { return new IntermediateModelBuilder(C2jModels.builder() .serviceModel(serviceModel) .customizationConfig(loadCustomizationConfig(configName)) diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/happy-case-customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/happy-case-customization.config index 8c8a414fcc24..149bf3733cf3 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/happy-case-customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/happy-case-customization.config @@ -1,6 +1,6 @@ { "useLegacyEventGenerationScheme": { - "EventStream": ["EventOne"] + "EventStream": {"EventOne": "NO_EVENT_SUBCLASS"} }, "underscoresInNameBehavior": "ALLOW" } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/multiple-event-types-same-shape.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/multiple-event-types-same-shape.config index 67821c2af904..b7ad338dd5a8 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/multiple-event-types-same-shape.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/emitters/customizations/processors/uselegacyeventgenerationscheme/multiple-event-types-same-shape.config @@ -1,5 +1,6 @@ { "useLegacyEventGenerationScheme": { - "EventStream": ["EventOne", "secondEventOne"] - } + "EventStream": {"EventOne": "NO_EVENT_SUBCLASS", "secondEventOne": "NO_EVENT_SUBCLASS"} + }, + "underscoresInNameBehavior": "ALLOW" } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/cbor/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/cbor/customization.config index 29eb1e7f6981..775dcf49debd 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/cbor/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/cbor/customization.config @@ -20,7 +20,17 @@ "createMethodParams": ["param1", "param2", "param3"] }, "useLegacyEventGenerationScheme": { - "EventStream": ["EventOne", "event-two", "eventThree"] + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": { + "InputEventOne": "NO_UNIQUE_EVENT_NAMES", + "InputEventTwo": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_EVENT_SUBCLASS", + "eventThree": "NO_EVENT_SUBCLASS", + "EventTheSecond": "NO_UNIQUE_EVENT_NAMES", + "secondEventOne": "NO_UNIQUE_EVENT_NAMES" + } }, "customServiceMetadata": { "protocol": "cbor" diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/json/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/json/customization.config index b22f02b7debe..6ce86133b958 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/json/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/json/customization.config @@ -19,7 +19,17 @@ "returnType": "software.amazon.awssdk.services.json.JsonUtilities", "createMethodParams": ["param1", "param2", "param3"] }, - "useLegacyEventGenerationScheme": { - "EventStream": ["EventOne", "event-two", "eventThree"] - } + "useLegacyEventGenerationScheme": { + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": { + "InputEventOne": "NO_UNIQUE_EVENT_NAMES", + "InputEventTwo": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_EVENT_SUBCLASS", + "eventThree": "NO_EVENT_SUBCLASS", + "EventTheSecond": "NO_UNIQUE_EVENT_NAMES", + "secondEventOne": "NO_UNIQUE_EVENT_NAMES" + } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/customization.config index 250560d3535f..b7222b577980 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/customization.config @@ -63,7 +63,17 @@ "software.amazon.awssdk.codegen.poet.plugins.InternalTestPlugin2" ], "useLegacyEventGenerationScheme": { - "EventStream": ["EventOne", "event-two", "eventThree"] + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": { + "InputEventOne": "NO_UNIQUE_EVENT_NAMES", + "InputEventTwo": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_EVENT_SUBCLASS", + "eventThree": "NO_EVENT_SUBCLASS", + "EventTheSecond": "NO_UNIQUE_EVENT_NAMES", + "secondEventOne": "NO_UNIQUE_EVENT_NAMES" + } }, "asyncClientDecoratorClass": true, "syncClientDecoratorClass": true, diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/eventstream/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/eventstream/customization.config index 2c63c0851048..f84eb49088ce 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/eventstream/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/eventstream/customization.config @@ -1,2 +1,15 @@ { + "useLegacyEventGenerationScheme": { + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": { + "InputEventOne": "NO_UNIQUE_EVENT_NAMES", + "InputEventTwo": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES", + "secondEventOne": "NO_UNIQUE_EVENT_NAMES", + "secondeventtwo": "NO_UNIQUE_EVENT_NAMES" + } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config index 0375c733e912..56367c454658 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config @@ -60,5 +60,16 @@ } }, "underscoresInNameBehavior": "ALLOW", - "requiredTraitValidationEnabled": true + "requiredTraitValidationEnabled": true, + "useLegacyEventGenerationScheme": { + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": {"InputEventTwo": "NO_UNIQUE_EVENT_NAMES"}, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "SecondEventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES", + "SecondEventTwo": "NO_UNIQUE_EVENT_NAMES", + "eventthree": "NO_UNIQUE_EVENT_NAMES" + } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/eventstream.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/eventstream.java index 7b4ee13981f9..a5957f545e4a 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/eventstream.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/eventstream.java @@ -41,7 +41,7 @@ public void accept(StreamDeathsResponseHandler.Visitor visitor) { /** * Create a builder for the {@code Person} event type for this stream. */ - static Person.Builder personBuilder() { + static PersonEventStream.Builder personBuilder() { return DefaultPerson.builder(); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/person.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personeventstream.java similarity index 87% rename from codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/person.java rename to codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personeventstream.java index 9ee0ccbce85e..1e0b85814a93 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/person.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personeventstream.java @@ -25,13 +25,14 @@ /** */ @Generated("software.amazon.awssdk:codegen") -public class Person implements SdkPojo, Serializable, ToCopyableBuilder, EventStream { +public class PersonEventStream implements SdkPojo, Serializable, ToCopyableBuilder, + EventStream { private static final SdkField NAME_FIELD = SdkField. builder(MarshallingType.STRING).memberName("Name") - .getter(getter(Person::name)).setter(setter(Builder::name)) + .getter(getter(PersonEventStream::name)).setter(setter(Builder::name)) .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Name").build()).build(); private static final SdkField BIRTHDAY_FIELD = SdkField. builder(MarshallingType.INSTANT) - .memberName("Birthday").getter(getter(Person::birthday)).setter(setter(Builder::birthday)) + .memberName("Birthday").getter(getter(PersonEventStream::birthday)).setter(setter(Builder::birthday)) .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Birthday").build()).build(); private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(NAME_FIELD, BIRTHDAY_FIELD)); @@ -44,7 +45,7 @@ public class Person implements SdkPojo, Serializable, ToCopyableBuilder Optional getValueForField(String fieldName, Class clazz) { @@ -129,7 +130,7 @@ public final Optional getValueForField(String fieldName, Class clazz) } @Override - public final Person copy(Consumer modifier) { + public final PersonEventStream copy(Consumer modifier) { return ToCopyableBuilder.super.copy(modifier); } @@ -150,8 +151,8 @@ private static Map> memberNameToFieldInitializer() { return Collections.unmodifiableMap(map); } - private static Function getter(Function g) { - return obj -> g.apply((Person) obj); + private static Function getter(Function g) { + return obj -> g.apply((PersonEventStream) obj); } private static BiConsumer setter(BiConsumer s) { @@ -159,7 +160,7 @@ private static BiConsumer setter(BiConsumer s) { } /** - * Calls the appropriate visit method depending on the subtype of {@link Person}. + * Calls the appropriate visit method depending on the subtype of {@link PersonEventStream}. * * @param visitor * Visitor to invoke. @@ -170,7 +171,7 @@ public void accept(StreamBirthsResponseHandler.Visitor visitor) { } /** - * Calls the appropriate visit method depending on the subtype of {@link Person}. + * Calls the appropriate visit method depending on the subtype of {@link PersonEventStream}. * * @param visitor * Visitor to invoke. @@ -180,7 +181,7 @@ public void accept(StreamDeathsResponseHandler.Visitor visitor) { throw new UnsupportedOperationException(); } - public interface Builder extends SdkPojo, CopyableBuilder { + public interface Builder extends SdkPojo, CopyableBuilder { /** * Sets the value of the Name property for this object. * @@ -208,7 +209,7 @@ protected static class BuilderImpl implements Builder { protected BuilderImpl() { } - protected BuilderImpl(Person model) { + protected BuilderImpl(PersonEventStream model) { name(model.name); birthday(model.birthday); } @@ -242,8 +243,8 @@ public final Builder birthday(Instant birthday) { } @Override - public Person build() { - return new Person(this); + public PersonEventStream build() { + return new PersonEventStream(this); } @Override diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreambirthsinputeventstream.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreambirthsinputeventstream.java new file mode 100644 index 000000000000..55fa66926761 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreambirthsinputeventstream.java @@ -0,0 +1,240 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.io.Serializable; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.core.protocol.MarshallLocation; +import software.amazon.awssdk.core.protocol.MarshallingType; +import software.amazon.awssdk.core.traits.LocationTrait; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +/** + */ +@Generated("software.amazon.awssdk:codegen") +public class PersonStreamBirthsInputEventStream implements SdkPojo, Serializable, + ToCopyableBuilder, + StreamBirthsInputEventStream { + private static final SdkField NAME_FIELD = SdkField. builder(MarshallingType.STRING).memberName("Name") + .getter(getter(PersonStreamBirthsInputEventStream::name)).setter(setter(Builder::name)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Name").build()).build(); + + private static final SdkField BIRTHDAY_FIELD = SdkField. builder(MarshallingType.INSTANT) + .memberName("Birthday").getter(getter(PersonStreamBirthsInputEventStream::birthday)) + .setter(setter(Builder::birthday)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Birthday").build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(NAME_FIELD, BIRTHDAY_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private static final long serialVersionUID = 1L; + + private final String name; + + private final Instant birthday; + + protected PersonStreamBirthsInputEventStream(BuilderImpl builder) { + this.name = builder.name; + this.birthday = builder.birthday; + } + + /** + * Returns the value of the Name property for this object. + * + * @return The value of the Name property for this object. + */ + public final String name() { + return name; + } + + /** + * Returns the value of the Birthday property for this object. + * + * @return The value of the Birthday property for this object. + */ + public final Instant birthday() { + return birthday; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(name()); + hashCode = 31 * hashCode + Objects.hashCode(birthday()); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof PersonStreamBirthsInputEventStream)) { + return false; + } + PersonStreamBirthsInputEventStream other = (PersonStreamBirthsInputEventStream) obj; + return Objects.equals(name(), other.name()) && Objects.equals(birthday(), other.birthday()); + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("PersonStreamBirthsInputEventStream").add("Name", name()).add("Birthday", birthday()).build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "Name": + return Optional.ofNullable(clazz.cast(name())); + case "Birthday": + return Optional.ofNullable(clazz.cast(birthday())); + default: + return Optional.empty(); + } + } + + @Override + public final PersonStreamBirthsInputEventStream copy(Consumer modifier) { + return ToCopyableBuilder.super.copy(modifier); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("Name", NAME_FIELD); + map.put("Birthday", BIRTHDAY_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((PersonStreamBirthsInputEventStream) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + public interface Builder extends SdkPojo, CopyableBuilder { + /** + * Sets the value of the Name property for this object. + * + * @param name + * The new value for the Name property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder name(String name); + + /** + * Sets the value of the Birthday property for this object. + * + * @param birthday + * The new value for the Birthday property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder birthday(Instant birthday); + } + + protected static class BuilderImpl implements Builder { + private String name; + + private Instant birthday; + + protected BuilderImpl() { + } + + protected BuilderImpl(PersonStreamBirthsInputEventStream model) { + name(model.name); + birthday(model.birthday); + } + + public final String getName() { + return name; + } + + public final void setName(String name) { + this.name = name; + } + + @Override + public final Builder name(String name) { + this.name = name; + return this; + } + + public final Instant getBirthday() { + return birthday; + } + + public final void setBirthday(Instant birthday) { + this.birthday = birthday; + } + + @Override + public final Builder birthday(Instant birthday) { + this.birthday = birthday; + return this; + } + + @Override + public PersonStreamBirthsInputEventStream build() { + return new PersonStreamBirthsInputEventStream(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreamdeathsinputeventstream.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreamdeathsinputeventstream.java new file mode 100644 index 000000000000..30c4df6cf657 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/personstreamdeathsinputeventstream.java @@ -0,0 +1,240 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.io.Serializable; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.core.protocol.MarshallLocation; +import software.amazon.awssdk.core.protocol.MarshallingType; +import software.amazon.awssdk.core.traits.LocationTrait; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +/** + */ +@Generated("software.amazon.awssdk:codegen") +public class PersonStreamDeathsInputEventStream implements SdkPojo, Serializable, + ToCopyableBuilder, + StreamDeathsInputEventStream { + private static final SdkField NAME_FIELD = SdkField. builder(MarshallingType.STRING).memberName("Name") + .getter(getter(PersonStreamDeathsInputEventStream::name)).setter(setter(Builder::name)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Name").build()).build(); + + private static final SdkField BIRTHDAY_FIELD = SdkField. builder(MarshallingType.INSTANT) + .memberName("Birthday").getter(getter(PersonStreamDeathsInputEventStream::birthday)) + .setter(setter(Builder::birthday)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Birthday").build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(NAME_FIELD, BIRTHDAY_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private static final long serialVersionUID = 1L; + + private final String name; + + private final Instant birthday; + + protected PersonStreamDeathsInputEventStream(BuilderImpl builder) { + this.name = builder.name; + this.birthday = builder.birthday; + } + + /** + * Returns the value of the Name property for this object. + * + * @return The value of the Name property for this object. + */ + public final String name() { + return name; + } + + /** + * Returns the value of the Birthday property for this object. + * + * @return The value of the Birthday property for this object. + */ + public final Instant birthday() { + return birthday; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(name()); + hashCode = 31 * hashCode + Objects.hashCode(birthday()); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof PersonStreamDeathsInputEventStream)) { + return false; + } + PersonStreamDeathsInputEventStream other = (PersonStreamDeathsInputEventStream) obj; + return Objects.equals(name(), other.name()) && Objects.equals(birthday(), other.birthday()); + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("PersonStreamDeathsInputEventStream").add("Name", name()).add("Birthday", birthday()).build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "Name": + return Optional.ofNullable(clazz.cast(name())); + case "Birthday": + return Optional.ofNullable(clazz.cast(birthday())); + default: + return Optional.empty(); + } + } + + @Override + public final PersonStreamDeathsInputEventStream copy(Consumer modifier) { + return ToCopyableBuilder.super.copy(modifier); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("Name", NAME_FIELD); + map.put("Birthday", BIRTHDAY_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((PersonStreamDeathsInputEventStream) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + public interface Builder extends SdkPojo, CopyableBuilder { + /** + * Sets the value of the Name property for this object. + * + * @param name + * The new value for the Name property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder name(String name); + + /** + * Sets the value of the Birthday property for this object. + * + * @param birthday + * The new value for the Birthday property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder birthday(Instant birthday); + } + + protected static class BuilderImpl implements Builder { + private String name; + + private Instant birthday; + + protected BuilderImpl() { + } + + protected BuilderImpl(PersonStreamDeathsInputEventStream model) { + name(model.name); + birthday(model.birthday); + } + + public final String getName() { + return name; + } + + public final void setName(String name) { + this.name = name; + } + + @Override + public final Builder name(String name) { + this.name = name; + return this; + } + + public final Instant getBirthday() { + return birthday; + } + + public final void setBirthday(Instant birthday) { + this.birthday = birthday; + } + + @Override + public final Builder birthday(Instant birthday) { + this.birthday = birthday; + return this; + } + + @Override + public PersonStreamDeathsInputEventStream build() { + return new PersonStreamDeathsInputEventStream(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/service-2.json index 4fa3c6714366..afc9c3816424 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/service-2.json +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/service-2.json @@ -33,6 +33,26 @@ "shape": "PeopleOutput" } }, + "StreamBirthsInput" : { + "name": "StreamBirths", + "http": { + "method": "POST", + "requestUri": "/births" + }, + "input": { + "shape": "StreamBirthsInputRequest" + } + }, + "StreamDeathsInput" : { + "name": "StreamDeathsInput", + "http": { + "method": "POST", + "requestUri": "/deaths" + }, + "input": { + "shape": "StreamDeathsInputRequest" + } + }, "GetRandomPerson" : { "name" : "GetRandomPerson", "http": { @@ -79,6 +99,40 @@ } }, "event": true + }, + "StreamBirthsInputRequest": { + "type": "structure", + "members": { + "StreamBirthsInputEventStream": { + "shape": "StreamBirthsInputEventStream" + } + } + }, + "StreamDeathsInputRequest": { + "type": "structure", + "members": { + "StreamDeathsInputEventStream": { + "shape": "StreamDeathsInputEventStream" + } + } + }, + "StreamBirthsInputEventStream": { + "type": "structure", + "members": { + "Person": { + "shape": "Person" + } + }, + "eventstream": true + }, + "StreamDeathsInputEventStream": { + "type": "structure", + "members": { + "Person": { + "shape": "Person" + } + }, + "eventstream": true } }, "documentation": "A service that streams births and deaths" diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputeventstream.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputeventstream.java new file mode 100644 index 000000000000..db9beee7542c --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputeventstream.java @@ -0,0 +1,79 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.services.sharedeventstream.model.streambirthsinputeventstream.DefaultPerson; +import software.amazon.awssdk.utils.internal.EnumUtils; + +/** + * Base interface for all event types in StreamBirthsInputEventStream. + */ +@Generated("software.amazon.awssdk:codegen") +@SdkPublicApi +public interface StreamBirthsInputEventStream { + /** + * Create a builder for the {@code Person} event type for this stream. + */ + static PersonStreamBirthsInputEventStream.Builder personBuilder() { + return DefaultPerson.builder(); + } + + /** + * The type of this event. Corresponds to the {@code :event-type} header on the Message. + */ + default EventType sdkEventType() { + return EventType.UNKNOWN_TO_SDK_VERSION; + } + + /** + * The known possible types of events for {@code StreamBirthsInputEventStream}. + */ + @Generated("software.amazon.awssdk:codegen") + enum EventType { + PERSON("Person"), + + UNKNOWN_TO_SDK_VERSION(null); + + private static final Map VALUE_MAP = EnumUtils.uniqueIndex(EventType.class, EventType::toString); + + private final String value; + + private EventType(String value) { + this.value = value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + /** + * Use this in place of valueOf to convert the raw string returned by the service into the enum value. + * + * @param value + * real value + * @return EventType corresponding to the value + */ + public static EventType fromValue(String value) { + if (value == null) { + return null; + } + return VALUE_MAP.getOrDefault(value, UNKNOWN_TO_SDK_VERSION); + } + + /** + * Use this in place of {@link #values()} to return a {@link Set} of all values known to the SDK. This will + * return all known enum values except {@link #UNKNOWN_TO_SDK_VERSION}. + * + * @return a {@link Set} of known {@link EventType}s + */ + public static Set knownValues() { + Set knownValues = EnumSet.allOf(EventType.class); + knownValues.remove(UNKNOWN_TO_SDK_VERSION); + return knownValues; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputrequest.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputrequest.java new file mode 100644 index 000000000000..1524d21efca4 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputrequest.java @@ -0,0 +1,139 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +/** + */ +@Generated("software.amazon.awssdk:codegen") +public final class StreamBirthsInputRequest extends SharedEventStreamRequest implements + ToCopyableBuilder { + private static final List> SDK_FIELDS = Collections.emptyList(); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private StreamBirthsInputRequest(BuilderImpl builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof StreamBirthsInputRequest)) { + return false; + } + return true; + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("StreamBirthsInputRequest").build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + return Optional.empty(); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + return Collections.emptyMap(); + } + + public interface Builder extends SharedEventStreamRequest.Builder, SdkPojo, + CopyableBuilder { + @Override + Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration); + + @Override + Builder overrideConfiguration(Consumer builderConsumer); + } + + static final class BuilderImpl extends SharedEventStreamRequest.BuilderImpl implements Builder { + private BuilderImpl() { + } + + private BuilderImpl(StreamBirthsInputRequest model) { + super(model); + } + + @Override + public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) { + super.overrideConfiguration(overrideConfiguration); + return this; + } + + @Override + public Builder overrideConfiguration(Consumer builderConsumer) { + super.overrideConfiguration(builderConsumer); + return this; + } + + @Override + public StreamBirthsInputRequest build() { + return new StreamBirthsInputRequest(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputresponse.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputresponse.java new file mode 100644 index 000000000000..44ba1723fc9e --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streambirthsinputresponse.java @@ -0,0 +1,118 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +@Generated("software.amazon.awssdk:codegen") +public final class StreamBirthsInputResponse extends SharedEventStreamResponse implements + ToCopyableBuilder { + private static final List> SDK_FIELDS = Collections.emptyList(); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private StreamBirthsInputResponse(BuilderImpl builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof StreamBirthsInputResponse)) { + return false; + } + return true; + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("StreamBirthsInputResponse").build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + return Optional.empty(); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + return Collections.emptyMap(); + } + + public interface Builder extends SharedEventStreamResponse.Builder, SdkPojo, + CopyableBuilder { + } + + static final class BuilderImpl extends SharedEventStreamResponse.BuilderImpl implements Builder { + private BuilderImpl() { + } + + private BuilderImpl(StreamBirthsInputResponse model) { + super(model); + } + + @Override + public StreamBirthsInputResponse build() { + return new StreamBirthsInputResponse(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputeventstream.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputeventstream.java new file mode 100644 index 000000000000..fa8aaf65586b --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputeventstream.java @@ -0,0 +1,79 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.services.sharedeventstream.model.streamdeathsinputeventstream.DefaultPerson; +import software.amazon.awssdk.utils.internal.EnumUtils; + +/** + * Base interface for all event types in StreamDeathsInputEventStream. + */ +@Generated("software.amazon.awssdk:codegen") +@SdkPublicApi +public interface StreamDeathsInputEventStream { + /** + * Create a builder for the {@code Person} event type for this stream. + */ + static PersonStreamDeathsInputEventStream.Builder personBuilder() { + return DefaultPerson.builder(); + } + + /** + * The type of this event. Corresponds to the {@code :event-type} header on the Message. + */ + default EventType sdkEventType() { + return EventType.UNKNOWN_TO_SDK_VERSION; + } + + /** + * The known possible types of events for {@code StreamDeathsInputEventStream}. + */ + @Generated("software.amazon.awssdk:codegen") + enum EventType { + PERSON("Person"), + + UNKNOWN_TO_SDK_VERSION(null); + + private static final Map VALUE_MAP = EnumUtils.uniqueIndex(EventType.class, EventType::toString); + + private final String value; + + private EventType(String value) { + this.value = value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + /** + * Use this in place of valueOf to convert the raw string returned by the service into the enum value. + * + * @param value + * real value + * @return EventType corresponding to the value + */ + public static EventType fromValue(String value) { + if (value == null) { + return null; + } + return VALUE_MAP.getOrDefault(value, UNKNOWN_TO_SDK_VERSION); + } + + /** + * Use this in place of {@link #values()} to return a {@link Set} of all values known to the SDK. This will + * return all known enum values except {@link #UNKNOWN_TO_SDK_VERSION}. + * + * @return a {@link Set} of known {@link EventType}s + */ + public static Set knownValues() { + Set knownValues = EnumSet.allOf(EventType.class); + knownValues.remove(UNKNOWN_TO_SDK_VERSION); + return knownValues; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputrequest.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputrequest.java new file mode 100644 index 000000000000..466d2820c5e6 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputrequest.java @@ -0,0 +1,139 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +/** + */ +@Generated("software.amazon.awssdk:codegen") +public final class StreamDeathsInputRequest extends SharedEventStreamRequest implements + ToCopyableBuilder { + private static final List> SDK_FIELDS = Collections.emptyList(); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private StreamDeathsInputRequest(BuilderImpl builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof StreamDeathsInputRequest)) { + return false; + } + return true; + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("StreamDeathsInputRequest").build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + return Optional.empty(); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + return Collections.emptyMap(); + } + + public interface Builder extends SharedEventStreamRequest.Builder, SdkPojo, + CopyableBuilder { + @Override + Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration); + + @Override + Builder overrideConfiguration(Consumer builderConsumer); + } + + static final class BuilderImpl extends SharedEventStreamRequest.BuilderImpl implements Builder { + private BuilderImpl() { + } + + private BuilderImpl(StreamDeathsInputRequest model) { + super(model); + } + + @Override + public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) { + super.overrideConfiguration(overrideConfiguration); + return this; + } + + @Override + public Builder overrideConfiguration(Consumer builderConsumer) { + super.overrideConfiguration(builderConsumer); + return this; + } + + @Override + public StreamDeathsInputRequest build() { + return new StreamDeathsInputRequest(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputresponse.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputresponse.java new file mode 100644 index 000000000000..8356ee764d4d --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/sharedstream/streamdeathsinputresponse.java @@ -0,0 +1,118 @@ +package software.amazon.awssdk.services.sharedeventstream.model; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +@Generated("software.amazon.awssdk:codegen") +public final class StreamDeathsInputResponse extends SharedEventStreamResponse implements + ToCopyableBuilder { + private static final List> SDK_FIELDS = Collections.emptyList(); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private StreamDeathsInputResponse(BuilderImpl builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof StreamDeathsInputResponse)) { + return false; + } + return true; + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("StreamDeathsInputResponse").build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + return Optional.empty(); + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + return Collections.emptyMap(); + } + + public interface Builder extends SharedEventStreamResponse.Builder, SdkPojo, + CopyableBuilder { + } + + static final class BuilderImpl extends SharedEventStreamResponse.BuilderImpl implements Builder { + private BuilderImpl() { + } + + private BuilderImpl(StreamDeathsInputResponse model) { + super(model); + } + + @Override + public StreamDeathsInputResponse build() { + return new StreamDeathsInputResponse(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/customization.config index e66eb09003af..69c1a15a8a04 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/customization.config @@ -7,5 +7,14 @@ ], "modelMarshallerDefaultValueSupplier": { "StringMember" : "software.amazon.awssdk.codegen.poet.transform.CustomDefaultValueSupplier.getInstance()" + }, + "useLegacyEventGenerationScheme": { + "InputEventStream": {"InputEvent": "NO_UNIQUE_EVENT_NAMES"}, + "InputEventStreamTwo": {"InputEventTwo": "NO_UNIQUE_EVENT_NAMES"}, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES", + "EventThree": "NO_UNIQUE_EVENT_NAMES" + } } } \ No newline at end of file diff --git a/services/kinesis/src/main/resources/codegen-resources/customization.config b/services/kinesis/src/main/resources/codegen-resources/customization.config index 93d23c80b74b..d43980894a07 100644 --- a/services/kinesis/src/main/resources/codegen-resources/customization.config +++ b/services/kinesis/src/main/resources/codegen-resources/customization.config @@ -18,7 +18,7 @@ }, "serviceSpecificHttpConfig": "software.amazon.awssdk.services.kinesis.internal.KinesisHttpConfigurationOptions", "useLegacyEventGenerationScheme": { - "SubscribeToShardEventStream": ["SubscribeToShardEvent"] + "SubscribeToShardEventStream": {"SubscribeToShardEvent": "NO_EVENT_SUBCLASS"} }, "skipEndpointTests": { "Account endpoint targeting control operation type in ADC regions": "Test is broken for client tests, need operationInputs.", diff --git a/services/transcribestreaming/src/main/resources/codegen-resources/customization.config b/services/transcribestreaming/src/main/resources/codegen-resources/customization.config index 9f59866f0821..10842c60385d 100644 --- a/services/transcribestreaming/src/main/resources/codegen-resources/customization.config +++ b/services/transcribestreaming/src/main/resources/codegen-resources/customization.config @@ -3,9 +3,9 @@ "serviceSpecificHttpConfig": "software.amazon.awssdk.services.transcribestreaming.internal.DefaultHttpConfigurationOptions", "skipSyncClientGeneration": true, "useLegacyEventGenerationScheme": { - "TranscriptResultStream": ["TranscriptEvent"], - "AudioStream": ["AudioEvent"], - "MedicalTranscriptResultStream": ["TranscriptEvent"] + "TranscriptResultStream": {"TranscriptEvent": "NO_EVENT_SUBCLASS"}, + "AudioStream": {"AudioEvent": "NO_EVENT_SUBCLASS"}, + "MedicalTranscriptResultStream": {"TranscriptEvent": "NO_EVENT_SUBCLASS"} }, "usePriorKnowledgeForH2": true, "enableFastUnmarshaller": true From 00608dd5cdd7742203d15f1f30b27e1a5301f197 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Tue, 22 Apr 2025 17:34:10 -0700 Subject: [PATCH 2/6] Add all existing eventstreams to customization w/ legacy mode --- .../codegen-resources/customization.config | 76 +- .../codegen-resources/customization.config | 40 +- .../codegen-resources/customization.config | 12 +- .../codegen-resources/customization.config | 17 +- .../codegen-resources/customization.config | 10 +- .../codegen-resources/customization.config | 30 +- .../codegen-resources/customization.config | 21 +- .../codegen-resources/customization.config | 681 +++++++++--------- .../codegen-resources/customization.config | 11 +- 9 files changed, 547 insertions(+), 351 deletions(-) diff --git a/services/bedrockagentruntime/src/main/resources/codegen-resources/customization.config b/services/bedrockagentruntime/src/main/resources/codegen-resources/customization.config index 6bc46bc3c310..fc2547bf0491 100644 --- a/services/bedrockagentruntime/src/main/resources/codegen-resources/customization.config +++ b/services/bedrockagentruntime/src/main/resources/codegen-resources/customization.config @@ -1,4 +1,76 @@ { "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "FlowResponseStream": { + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "badGatewayException": "NO_UNIQUE_EVENT_NAMES", + "conflictException": "NO_UNIQUE_EVENT_NAMES", + "dependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "flowCompletionEvent": "NO_UNIQUE_EVENT_NAMES", + "flowMultiTurnInputRequestEvent": "NO_UNIQUE_EVENT_NAMES", + "flowOutputEvent": "NO_UNIQUE_EVENT_NAMES", + "flowTraceEvent": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "resourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "serviceQuotaExceededException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES" + }, + "InlineAgentResponseStream": { + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "badGatewayException": "NO_UNIQUE_EVENT_NAMES", + "chunk": "NO_UNIQUE_EVENT_NAMES", + "conflictException": "NO_UNIQUE_EVENT_NAMES", + "dependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "files": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "resourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "returnControl": "NO_UNIQUE_EVENT_NAMES", + "serviceQuotaExceededException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "trace": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES" + }, + "OptimizedPromptStream": { + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "analyzePromptEvent": "NO_UNIQUE_EVENT_NAMES", + "badGatewayException": "NO_UNIQUE_EVENT_NAMES", + "dependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "optimizedPromptEvent": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES" + }, + "ResponseStream": { + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "badGatewayException": "NO_UNIQUE_EVENT_NAMES", + "chunk": "NO_UNIQUE_EVENT_NAMES", + "conflictException": "NO_UNIQUE_EVENT_NAMES", + "dependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "files": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "modelNotReadyException": "NO_UNIQUE_EVENT_NAMES", + "resourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "returnControl": "NO_UNIQUE_EVENT_NAMES", + "serviceQuotaExceededException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "trace": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES" + }, + "RetrieveAndGenerateStreamResponseOutput": { + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "badGatewayException": "NO_UNIQUE_EVENT_NAMES", + "citation": "NO_UNIQUE_EVENT_NAMES", + "conflictException": "NO_UNIQUE_EVENT_NAMES", + "dependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "guardrail": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "output": "NO_UNIQUE_EVENT_NAMES", + "resourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "serviceQuotaExceededException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/bedrockruntime/src/main/resources/codegen-resources/customization.config b/services/bedrockruntime/src/main/resources/codegen-resources/customization.config index 6bc46bc3c310..9ec96194bd03 100644 --- a/services/bedrockruntime/src/main/resources/codegen-resources/customization.config +++ b/services/bedrockruntime/src/main/resources/codegen-resources/customization.config @@ -1,4 +1,40 @@ { "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "ConverseStreamOutput": { + "messageStart": "NO_UNIQUE_EVENT_NAMES", + "contentBlockStart": "NO_UNIQUE_EVENT_NAMES", + "contentBlockDelta": "NO_UNIQUE_EVENT_NAMES", + "contentBlockStop": "NO_UNIQUE_EVENT_NAMES", + "messageStop": "NO_UNIQUE_EVENT_NAMES", + "metadata": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "modelStreamErrorException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "serviceUnavailableException": "NO_UNIQUE_EVENT_NAMES" + }, + "InvokeModelWithBidirectionalStreamInput": { + "chunk": "NO_UNIQUE_EVENT_NAMES" + }, + "InvokeModelWithBidirectionalStreamOutput": { + "chunk": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "modelStreamErrorException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "modelTimeoutException": "NO_UNIQUE_EVENT_NAMES", + "serviceUnavailableException": "NO_UNIQUE_EVENT_NAMES" + }, + "ResponseStream": { + "chunk": "NO_UNIQUE_EVENT_NAMES", + "internalServerException": "NO_UNIQUE_EVENT_NAMES", + "modelStreamErrorException": "NO_UNIQUE_EVENT_NAMES", + "validationException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES", + "modelTimeoutException": "NO_UNIQUE_EVENT_NAMES", + "serviceUnavailableException": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/cloudwatchlogs/src/main/resources/codegen-resources/customization.config b/services/cloudwatchlogs/src/main/resources/codegen-resources/customization.config index dae61a4ae724..5b35d57246ad 100644 --- a/services/cloudwatchlogs/src/main/resources/codegen-resources/customization.config +++ b/services/cloudwatchlogs/src/main/resources/codegen-resources/customization.config @@ -15,5 +15,13 @@ "GetLogEvents": "LastPageHasPreviousToken" }, "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": false -} + "enableFastUnmarshaller": false, + "useLegacyEventGenerationScheme": { + "StartLiveTailResponseStream": { + "sessionStart": "NO_UNIQUE_EVENT_NAMES", + "sessionUpdate": "NO_UNIQUE_EVENT_NAMES", + "SessionTimeoutException": "NO_UNIQUE_EVENT_NAMES", + "SessionStreamingException": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/iotsitewise/src/main/resources/codegen-resources/customization.config b/services/iotsitewise/src/main/resources/codegen-resources/customization.config index 2880fc39d3a3..928cd998c447 100644 --- a/services/iotsitewise/src/main/resources/codegen-resources/customization.config +++ b/services/iotsitewise/src/main/resources/codegen-resources/customization.config @@ -1,5 +1,18 @@ { "generateEndpointClientTests": true, "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "ResponseStream": { + "trace": "NO_UNIQUE_EVENT_NAMES", + "output": "NO_UNIQUE_EVENT_NAMES", + "accessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "conflictingOperationException": "NO_UNIQUE_EVENT_NAMES", + "internalFailureException": "NO_UNIQUE_EVENT_NAMES", + "invalidRequestException": "NO_UNIQUE_EVENT_NAMES", + "limitExceededException": "NO_UNIQUE_EVENT_NAMES", + "resourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "throttlingException": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/lambda/src/main/resources/codegen-resources/customization.config b/services/lambda/src/main/resources/codegen-resources/customization.config index d9800630318d..7e7d777ee633 100644 --- a/services/lambda/src/main/resources/codegen-resources/customization.config +++ b/services/lambda/src/main/resources/codegen-resources/customization.config @@ -9,5 +9,11 @@ "InvokeAsync" ], "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "InvokeWithResponseStreamResponseEvent": { + "PayloadChunk": "NO_UNIQUE_EVENT_NAMES", + "InvokeComplete": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/lexruntimev2/src/main/resources/codegen-resources/customization.config b/services/lexruntimev2/src/main/resources/codegen-resources/customization.config index 6a46da376f05..2ec7766f88cb 100644 --- a/services/lexruntimev2/src/main/resources/codegen-resources/customization.config +++ b/services/lexruntimev2/src/main/resources/codegen-resources/customization.config @@ -4,5 +4,31 @@ }, "enableGenerateCompiledEndpointRules": true, "usePriorKnowledgeForH2": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "StartConversationRequestEventStream": { + "ConfigurationEvent": "NO_UNIQUE_EVENT_NAMES", + "AudioInputEvent": "NO_UNIQUE_EVENT_NAMES", + "DTMFInputEvent": "NO_UNIQUE_EVENT_NAMES", + "TextInputEvent": "NO_UNIQUE_EVENT_NAMES", + "PlaybackCompletionEvent": "NO_UNIQUE_EVENT_NAMES", + "DisconnectionEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "StartConversationResponseEventStream": { + "PlaybackInterruptionEvent": "NO_UNIQUE_EVENT_NAMES", + "TranscriptEvent": "NO_UNIQUE_EVENT_NAMES", + "IntentResultEvent": "NO_UNIQUE_EVENT_NAMES", + "TextResponseEvent": "NO_UNIQUE_EVENT_NAMES", + "AudioResponseEvent": "NO_UNIQUE_EVENT_NAMES", + "HeartbeatEvent": "NO_UNIQUE_EVENT_NAMES", + "AccessDeniedException": "NO_UNIQUE_EVENT_NAMES", + "ResourceNotFoundException": "NO_UNIQUE_EVENT_NAMES", + "ValidationException": "NO_UNIQUE_EVENT_NAMES", + "ThrottlingException": "NO_UNIQUE_EVENT_NAMES", + "InternalServerException": "NO_UNIQUE_EVENT_NAMES", + "ConflictException": "NO_UNIQUE_EVENT_NAMES", + "DependencyFailedException": "NO_UNIQUE_EVENT_NAMES", + "BadGatewayException": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/qbusiness/src/main/resources/codegen-resources/customization.config b/services/qbusiness/src/main/resources/codegen-resources/customization.config index 6424907d3404..f58f827b3047 100644 --- a/services/qbusiness/src/main/resources/codegen-resources/customization.config +++ b/services/qbusiness/src/main/resources/codegen-resources/customization.config @@ -1,5 +1,22 @@ { "enableGenerateCompiledEndpointRules": true, "usePriorKnowledgeForH2": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "ChatInputStream": { + "configurationEvent": "NO_UNIQUE_EVENT_NAMES", + "textEvent": "NO_UNIQUE_EVENT_NAMES", + "attachmentEvent": "NO_UNIQUE_EVENT_NAMES", + "actionExecutionEvent": "NO_UNIQUE_EVENT_NAMES", + "endOfInputEvent": "NO_UNIQUE_EVENT_NAMES", + "authChallengeResponseEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "ChatOutputStream": { + "textEvent": "NO_UNIQUE_EVENT_NAMES", + "metadataEvent": "NO_UNIQUE_EVENT_NAMES", + "actionReviewEvent": "NO_UNIQUE_EVENT_NAMES", + "failedAttachmentEvent": "NO_UNIQUE_EVENT_NAMES", + "authChallengeRequestEvent": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/services/s3/src/main/resources/codegen-resources/customization.config b/services/s3/src/main/resources/codegen-resources/customization.config index 8acd43509eab..4fa4712f685b 100644 --- a/services/s3/src/main/resources/codegen-resources/customization.config +++ b/services/s3/src/main/resources/codegen-resources/customization.config @@ -1,362 +1,373 @@ { - "shapeSubstitutions": { - "Expires": { - "emitAsType": "timestamp" - } - }, - "verifiedSimpleMethods": [ - "listBuckets" - ], - "renameShapes": { - "Error": "S3Error", - "Object": "S3Object" - }, - "customSdkShapes": { - "shapes":{ - "SdkPartType":{ - "type":"string", - "enum":[ - "DEFAULT", - "LAST" - ] - } - } - }, - "shapeModifiers": { - "S3Object": { - "modify": [ - { - "Size": { - "emitAsType": "long" - } + "shapeSubstitutions": { + "Expires": { + "emitAsType": "timestamp" } - ] }, - "GetObjectOutput": { - "modify": [ - { - "Expires": { - "emitAsType": "timestamp", - "deprecated": "true", - "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString", - "ignoreDataTypeConversionFailures": "true" - } + "verifiedSimpleMethods": [ + "listBuckets" + ], + "renameShapes": { + "Error": "S3Error", + "Object": "S3Object" + }, + "customSdkShapes": { + "shapes": { + "SdkPartType": { + "type": "string", + "enum": [ + "DEFAULT", + "LAST" + ] + } } - ], - "inject": [ - { - "ExpiresString": { - "shape": "Expiration", - "documentation":"

The date and time at which the object is no longer cacheable

", - "location":"header", - "locationName":"Expires" - } + }, + "shapeModifiers": { + "S3Object": { + "modify": [ + { + "Size": { + "emitAsType": "long" + } + } + ] + }, + "GetObjectOutput": { + "modify": [ + { + "Expires": { + "emitAsType": "timestamp", + "deprecated": "true", + "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString", + "ignoreDataTypeConversionFailures": "true" + } + } + ], + "inject": [ + { + "ExpiresString": { + "shape": "Expiration", + "documentation": "

The date and time at which the object is no longer cacheable

", + "location": "header", + "locationName": "Expires" + } + } + ] + }, + "HeadObjectOutput": { + "modify": [ + { + "Expires": { + "emitAsType": "timestamp", + "deprecated": "true", + "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString", + "ignoreDataTypeConversionFailures": "true" + } + } + ], + "inject": [ + { + "ExpiresString": { + "shape": "Expiration", + "documentation": "

The date and time at which the object is no longer cacheable

", + "location": "header", + "locationName": "Expires" + } + } + ] + }, + "UploadPartRequest": { + "inject": [ + { + "SdkPartType": { + "shape": "SdkPartType", + "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." + } + } + ] + }, + "CopyObjectRequest": { + "inject": [ + { + "SourceBucket": { + "shape": "BucketName", + "documentation": "The name of the bucket containing the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + }, + "SourceKey": { + "shape": "ObjectKey", + "documentation": "The key of the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + }, + "SourceVersionId": { + "shape": "ObjectVersionId", + "documentation": "Specifies a particular version of the source object to copy. By default the latest version is copied. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + } + } + ], + "modify": [ + { + "CopySource": { + "deprecated": true, + "deprecatedMessage": "The {@code copySource} parameter has been deprecated in favor of the more user-friendly {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters. The {@code copySource} parameter will remain fully functional, but it must not be used in conjunction with its replacement parameters." + }, + "Bucket": { + "emitPropertyName": "DestinationBucket", + "existingNameDeprecated": true + }, + "Key": { + "emitPropertyName": "DestinationKey", + "existingNameDeprecated": true + } + } + ] + }, + "UploadPartCopyRequest": { + "inject": [ + { + "SourceBucket": { + "shape": "BucketName", + "documentation": "The name of the bucket containing the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + }, + "SourceKey": { + "shape": "ObjectKey", + "documentation": "The key of the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + }, + "SourceVersionId": { + "shape": "ObjectVersionId", + "documentation": "Specifies a particular version of the source object to copy. By default the latest version is copied. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." + } + } + ], + "modify": [ + { + "CopySource": { + "deprecated": true, + "deprecatedMessage": "The {@code copySource} parameter has been deprecated in favor of the more user-friendly {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters. The {@code copySource} parameter will remain fully functional, but it must not be used in conjunction with its replacement parameters." + }, + "Bucket": { + "emitPropertyName": "DestinationBucket", + "existingNameDeprecated": true + }, + "Key": { + "emitPropertyName": "DestinationKey", + "existingNameDeprecated": true + } + } + ] + }, + "ObjectVersion": { + "modify": [ + { + "Size": { + "emitAsType": "long" + } + } + ] + }, + "Part": { + "modify": [ + { + "Size": { + "emitAsType": "long" + } + } + ] + }, + "FilterRuleName": { + "modify": [ + { + "prefix": { + "emitEnumValue": "Prefix" + } + }, + { + "suffix": { + "emitEnumValue": "Suffix" + } + } + ] + }, + "ReplicationRuleFilter": { + "union": true + }, + "MetricsFilter": { + "union": true + }, + "AnalyticsFilter": { + "union": true + }, + "LifecycleRuleFilter": { + "union": true } - ] }, - "HeadObjectOutput": { - "modify": [ + "serviceConfig": { + "className": "S3Configuration", + "hasDualstackProperty": true, + "hasUseArnRegionProperty": true, + "hasMultiRegionEnabledProperty": true, + "hasPathStyleAccessEnabledProperty": true, + "hasAccelerateModeEnabledProperty": true, + "hasCrossRegionAccessEnabledProperty": true, + "hasChecksumValidationEnabledProperty": true + }, + "skipEndpointTests": { + "Invalid access point ARN: Not S3": "Test assumes UseArnRegion is true but SDK defaults to false", + "Invalid access point ARN: AccountId is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", + "Invalid access point ARN: access point name is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", + "Access points (disable access points explicitly false)": "Test assumes UseArnRegion is true but SDK defaults to false", + "Bucket region is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", + "Access point ARN with FIPS & Dualstack": "Test assumes UseArnRegion is true but SDK defaults to false", + "Access point ARN with Dualstack": "Test assumes UseArnRegion is true but SDK defaults to false", + "vanilla access point arn with region mismatch and UseArnRegion unset": "SDK config default to UseArnRegion = false", + "no region set": "SDK client builder requires a region", + "path style + accelerate = error@us-west-2": "Validation for this happens during client build time", + "path style + accelerate = error@cn-north-1": "Validation for this happens during client build time", + "path style + accelerate = error@af-south-1": "Validation for this happens during client build time", + "outposts arn with region mismatch and UseArnRegion unset": "SDK default to UseArnRegion=false" + }, + "attachPayloadTraitToMember": { + "GetBucketLocationOutput": "LocationConstraint" + }, + "convenienceTypeOverloads": [ { - "Expires": { - "emitAsType": "timestamp", - "deprecated": "true", - "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString", - "ignoreDataTypeConversionFailures": "true" - } - } - ], - "inject": [ + "shapeName": "PutObjectRequest", + "memberName": "Tagging", + "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", + "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" + }, { - "ExpiresString": { - "shape": "Expiration", - "documentation":"

The date and time at which the object is no longer cacheable

", - "location":"header", - "locationName":"Expires" - } - } - ] - }, - "UploadPartRequest": { - "inject": [ + "shapeName": "CopyObjectRequest", + "memberName": "Tagging", + "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", + "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" + }, { - "SdkPartType": { - "shape": "SdkPartType", - "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." - } + "shapeName": "CreateMultipartUploadRequest", + "memberName": "Tagging", + "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", + "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" } - ] + ], + "customResponseMetadata": { + "EXTENDED_REQUEST_ID": "x-amz-id-2", + "CLOUD_FRONT_ID": "X-Amz-Cf-Id", + "REQUEST_ID": "x-amz-request-id" + }, + "customProtocolFactoryFqcn": "software.amazon.awssdk.protocols.xml.AwsS3ProtocolFactory", + "operationModifiers": {}, + "deprecatedOperations": [ + "GetBucketLifecycle", + "GetBucketNotification", + "PutBucketLifecycle", + "PutBucketNotification" + ], + "utilitiesMethod": { + "returnType": "software.amazon.awssdk.services.s3.S3Utilities", + "createMethodParams": [ + "clientConfiguration" + ] }, - "CopyObjectRequest": { - "inject": [ + "additionalBuilderMethods": [ { - "SourceBucket": { - "shape": "BucketName", - "documentation": "The name of the bucket containing the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - }, - "SourceKey": { - "shape": "ObjectKey", - "documentation": "The key of the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - }, - "SourceVersionId": { - "shape": "ObjectVersionId", - "documentation": "Specifies a particular version of the source object to copy. By default the latest version is copied. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - } - } - ], - "modify": [ + "methodName": "crtBuilder", + "clientType": "async", + "instanceType": "software.amazon.awssdk.services.s3.internal.crt.S3CrtAsyncClient", + "returnType": "software.amazon.awssdk.services.s3.S3CrtAsyncClientBuilder", + "statement": "builder()", + "javaDoc": "Create a builder that can be used to configure a CRT-based {@link S3AsyncClient}" + }, { - "CopySource": { - "deprecated": true, - "deprecatedMessage": "The {@code copySource} parameter has been deprecated in favor of the more user-friendly {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters. The {@code copySource} parameter will remain fully functional, but it must not be used in conjunction with its replacement parameters." - }, - "Bucket": { - "emitPropertyName": "DestinationBucket", - "existingNameDeprecated": true - }, - "Key": { - "emitPropertyName": "DestinationKey", - "existingNameDeprecated": true - } + "methodName": "crtCreate", + "clientType": "async", + "instanceType": "software.amazon.awssdk.services.s3.internal.crt.S3CrtAsyncClient", + "returnType": "software.amazon.awssdk.services.s3.S3AsyncClient", + "statement": "builder().build()", + "javaDoc": "Create a CRT-based {@link S3AsyncClient} with default settings" } - ] + ], + "delegateAsyncClientClass": true, + "delegateSyncClientClass": true, + "syncClientDecorator": "software.amazon.awssdk.services.s3.internal.client.S3SyncClientDecorator", + "asyncClientDecorator": "software.amazon.awssdk.services.s3.internal.client.S3AsyncClientDecorator", + "useGlobalEndpoint": true, + "useS3ExpressSessionAuth": true, + "multipartCustomization": { + "multipartConfigurationClass": "software.amazon.awssdk.services.s3.multipart.MultipartConfiguration", + "multipartConfigMethodDoc": "Configuration for multipart operation of this client.", + "multipartEnableMethodDoc": "Enables automatic conversion of GET, PUT and COPY methods to their equivalent multipart operation. CRC32 checksum will be enabled for PUT, unless the checksum is specified or checksum validation is disabled.", + "contextParamEnabledKey": "S3AsyncClientDecorator.MULTIPART_ENABLED_KEY", + "contextParamConfigKey": "S3AsyncClientDecorator.MULTIPART_CONFIGURATION_KEY" }, - "UploadPartCopyRequest": { - "inject": [ - { - "SourceBucket": { - "shape": "BucketName", - "documentation": "The name of the bucket containing the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - }, - "SourceKey": { - "shape": "ObjectKey", - "documentation": "The key of the object to copy. The provided input will be URL encoded. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - }, - "SourceVersionId": { - "shape": "ObjectVersionId", - "documentation": "Specifies a particular version of the source object to copy. By default the latest version is copied. The {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters must not be used in conjunction with the {@code copySource} parameter." - } + "interceptors": [ + "software.amazon.awssdk.services.s3.internal.handlers.StreamingRequestInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.CreateBucketInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.CreateMultipartUploadRequestInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.DecodeUrlEncodedResponseInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.GetBucketPolicyInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.AsyncChecksumValidationInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.EnableTrailingChecksumInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.ExceptionTranslationInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.GetObjectInterceptor", + "software.amazon.awssdk.services.s3.internal.handlers.ObjectMetadataInterceptor" + ], + "internalPlugins": [ + "software.amazon.awssdk.services.s3.internal.plugins.S3DisableChunkEncodingIfConfiguredPlugin(config)", + "software.amazon.awssdk.services.s3.internal.s3express.S3ExpressPlugin" + ], + "requiredTraitValidationEnabled": true, + "s3ExpressAuthSupport": "true", + "enableEndpointAuthSchemeParams": true, + "customClientContextParams": { + "CrossRegionAccessEnabled": { + "documentation": "Enables cross-region bucket access for this client", + "type": "boolean" } - ], - "modify": [ - { - "CopySource": { - "deprecated": true, - "deprecatedMessage": "The {@code copySource} parameter has been deprecated in favor of the more user-friendly {@code sourceBucket}, {@code sourceKey}, and {@code sourceVersionId} parameters. The {@code copySource} parameter will remain fully functional, but it must not be used in conjunction with its replacement parameters." - }, - "Bucket": { - "emitPropertyName": "DestinationBucket", - "existingNameDeprecated": true - }, - "Key": { - "emitPropertyName": "DestinationKey", - "existingNameDeprecated": true - } - } - ] }, - "ObjectVersion": { - "modify": [ - { - "Size": { - "emitAsType": "long" - } + "endpointAuthSchemeConfig": { + "authSchemeStrategyFactoryClass": "software.amazon.awssdk.services.s3.endpoints.internal.S3EndpointAuthSchemeStrategyFactory", + "knownEndpointProperties": "software.amazon.awssdk.services.s3.endpoints.internal.KnownS3ExpressEndpointProperty.KNOWN_S3_ENDPOINT_PROPERTIES", + "endpointProviderTestKeys": { + "backend": { + "key": "software.amazon.awssdk.services.s3.endpoints.internal.KnownS3ExpressEndpointProperty.BACKEND", + "type": "string" + } } - ] }, - "Part": { - "modify": [ - { - "Size": { - "emitAsType": "long" - } + "enableGenerateCompiledEndpointRules": true, + "endpointParameters": { + "DeleteObjectKeys": { + "required": false, + "documentation": "DeleteObjectKeys Endpoint Params from the customization config", + "type": "StringArray" } - ] }, - "FilterRuleName": { - "modify": [ + "customOperationContextParams": [ { - "prefix": { "emitEnumValue": "Prefix" } + "operationName": "DeleteObjects", + "operationContextParamsMap": { + "DeleteObjectKeys": { + "path": "Delete.Objects[*].Key" + } + } + } + ], + "preClientExecutionRequestCustomizer": { + "CopyObject": { + "methodName": "modifyCopyObjectRequest", + "className": "software.amazon.awssdk.services.s3.internal.CustomRequestTransformerUtils" }, - { - "suffix": { "emitEnumValue": "Suffix" } + "UploadPartCopy": { + "methodName": "modifyUploadPartCopyRequest", + "className": "software.amazon.awssdk.services.s3.internal.CustomRequestTransformerUtils" } - ] }, - "ReplicationRuleFilter": { - "union": true - }, - "MetricsFilter": { - "union": true - }, - "AnalyticsFilter": { - "union": true - }, - "LifecycleRuleFilter": { - "union": true - } - }, - "serviceConfig": { - "className": "S3Configuration", - "hasDualstackProperty": true, - "hasUseArnRegionProperty": true, - "hasMultiRegionEnabledProperty": true, - "hasPathStyleAccessEnabledProperty":true, - "hasAccelerateModeEnabledProperty":true, - "hasCrossRegionAccessEnabledProperty":true, - "hasChecksumValidationEnabledProperty":true - }, - "skipEndpointTests": { - "Invalid access point ARN: Not S3": "Test assumes UseArnRegion is true but SDK defaults to false", - "Invalid access point ARN: AccountId is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", - "Invalid access point ARN: access point name is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", - "Access points (disable access points explicitly false)": "Test assumes UseArnRegion is true but SDK defaults to false", - "Bucket region is invalid": "Test assumes UseArnRegion is true but SDK defaults to false", - "Access point ARN with FIPS & Dualstack": "Test assumes UseArnRegion is true but SDK defaults to false", - "Access point ARN with Dualstack": "Test assumes UseArnRegion is true but SDK defaults to false", - "vanilla access point arn with region mismatch and UseArnRegion unset": "SDK config default to UseArnRegion = false", - "no region set": "SDK client builder requires a region", - "path style + accelerate = error@us-west-2": "Validation for this happens during client build time", - "path style + accelerate = error@cn-north-1": "Validation for this happens during client build time", - "path style + accelerate = error@af-south-1": "Validation for this happens during client build time", - "outposts arn with region mismatch and UseArnRegion unset": "SDK default to UseArnRegion=false" - }, - "attachPayloadTraitToMember": { - "GetBucketLocationOutput": "LocationConstraint" - }, - "convenienceTypeOverloads": [ - { - "shapeName": "PutObjectRequest", - "memberName": "Tagging", - "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", - "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" - }, - { - "shapeName": "CopyObjectRequest", - "memberName": "Tagging", - "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", - "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" - }, - { - "shapeName": "CreateMultipartUploadRequest", - "memberName": "Tagging", - "convenienceType": "software.amazon.awssdk.services.s3.model.Tagging", - "typeAdapterFqcn": "software.amazon.awssdk.services.s3.internal.TaggingAdapter" - } - ], - "customResponseMetadata": { - "EXTENDED_REQUEST_ID": "x-amz-id-2", - "CLOUD_FRONT_ID": "X-Amz-Cf-Id", - "REQUEST_ID": "x-amz-request-id" - }, - "customProtocolFactoryFqcn": "software.amazon.awssdk.protocols.xml.AwsS3ProtocolFactory", - "operationModifiers": { - }, - "deprecatedOperations": [ - "GetBucketLifecycle", - "GetBucketNotification", - "PutBucketLifecycle", - "PutBucketNotification" - ], - "utilitiesMethod": { - "returnType": "software.amazon.awssdk.services.s3.S3Utilities", - "createMethodParams": [ - "clientConfiguration" - ] - }, - "additionalBuilderMethods": [ - { - "methodName": "crtBuilder", - "clientType": "async", - "instanceType": "software.amazon.awssdk.services.s3.internal.crt.S3CrtAsyncClient", - "returnType": "software.amazon.awssdk.services.s3.S3CrtAsyncClientBuilder", - "statement": "builder()", - "javaDoc": "Create a builder that can be used to configure a CRT-based {@link S3AsyncClient}" - }, - { - "methodName": "crtCreate", - "clientType": "async", - "instanceType": "software.amazon.awssdk.services.s3.internal.crt.S3CrtAsyncClient", - "returnType": "software.amazon.awssdk.services.s3.S3AsyncClient", - "statement": "builder().build()", - "javaDoc": "Create a CRT-based {@link S3AsyncClient} with default settings" - } - ], - "delegateAsyncClientClass": true, - "delegateSyncClientClass": true, - "syncClientDecorator": "software.amazon.awssdk.services.s3.internal.client.S3SyncClientDecorator", - "asyncClientDecorator": "software.amazon.awssdk.services.s3.internal.client.S3AsyncClientDecorator", - "useGlobalEndpoint": true, - "useS3ExpressSessionAuth": true, - "multipartCustomization": { - "multipartConfigurationClass": "software.amazon.awssdk.services.s3.multipart.MultipartConfiguration", - "multipartConfigMethodDoc": "Configuration for multipart operation of this client.", - "multipartEnableMethodDoc": "Enables automatic conversion of GET, PUT and COPY methods to their equivalent multipart operation. CRC32 checksum will be enabled for PUT, unless the checksum is specified or checksum validation is disabled.", - "contextParamEnabledKey": "S3AsyncClientDecorator.MULTIPART_ENABLED_KEY", - "contextParamConfigKey": "S3AsyncClientDecorator.MULTIPART_CONFIGURATION_KEY" - }, - "interceptors": [ - "software.amazon.awssdk.services.s3.internal.handlers.StreamingRequestInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.CreateBucketInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.CreateMultipartUploadRequestInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.DecodeUrlEncodedResponseInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.GetBucketPolicyInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.AsyncChecksumValidationInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.EnableTrailingChecksumInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.ExceptionTranslationInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.GetObjectInterceptor", - "software.amazon.awssdk.services.s3.internal.handlers.ObjectMetadataInterceptor" - ], - "internalPlugins": [ - "software.amazon.awssdk.services.s3.internal.plugins.S3DisableChunkEncodingIfConfiguredPlugin(config)", - "software.amazon.awssdk.services.s3.internal.s3express.S3ExpressPlugin" - ], - "requiredTraitValidationEnabled": true, - "s3ExpressAuthSupport" : "true", - "enableEndpointAuthSchemeParams": true, - "customClientContextParams":{ - "CrossRegionAccessEnabled":{ - "documentation":"Enables cross-region bucket access for this client", - "type":"boolean" - } - }, - "endpointAuthSchemeConfig": { - "authSchemeStrategyFactoryClass": "software.amazon.awssdk.services.s3.endpoints.internal.S3EndpointAuthSchemeStrategyFactory", - "knownEndpointProperties": "software.amazon.awssdk.services.s3.endpoints.internal.KnownS3ExpressEndpointProperty.KNOWN_S3_ENDPOINT_PROPERTIES", - "endpointProviderTestKeys": { - "backend": { - "key": "software.amazon.awssdk.services.s3.endpoints.internal.KnownS3ExpressEndpointProperty.BACKEND", - "type": "string" - } - } - }, - - "enableGenerateCompiledEndpointRules": true, - "endpointParameters": { - "DeleteObjectKeys": { - "required": false, - "documentation": "DeleteObjectKeys Endpoint Params from the customization config", - "type": "StringArray" - } - }, - "customOperationContextParams": [ - { - "operationName": "DeleteObjects", - "operationContextParamsMap": { - "DeleteObjectKeys": { - "path": "Delete.Objects[*].Key" + "useLegacyEventGenerationScheme": { + "SelectObjectContentEventStream": { + "Records": "NO_UNIQUE_EVENT_NAMES", + "Stats": "NO_UNIQUE_EVENT_NAMES", + "Progress": "NO_UNIQUE_EVENT_NAMES", + "Cont": "NO_UNIQUE_EVENT_NAMES", + "End": "NO_UNIQUE_EVENT_NAMES" } - } - } - ], - "preClientExecutionRequestCustomizer": { - "CopyObject": { - "methodName": "modifyCopyObjectRequest", - "className": "software.amazon.awssdk.services.s3.internal.CustomRequestTransformerUtils" - }, - "UploadPartCopy": { - "methodName": "modifyUploadPartCopyRequest", - "className": "software.amazon.awssdk.services.s3.internal.CustomRequestTransformerUtils" } - } -} +} \ No newline at end of file diff --git a/services/sagemakerruntime/src/main/resources/codegen-resources/customization.config b/services/sagemakerruntime/src/main/resources/codegen-resources/customization.config index 6bc46bc3c310..ff7788be43f1 100644 --- a/services/sagemakerruntime/src/main/resources/codegen-resources/customization.config +++ b/services/sagemakerruntime/src/main/resources/codegen-resources/customization.config @@ -1,4 +1,11 @@ { "enableGenerateCompiledEndpointRules": true, - "enableFastUnmarshaller": true -} + "enableFastUnmarshaller": true, + "useLegacyEventGenerationScheme": { + "ResponseStream": { + "PayloadPart": "NO_UNIQUE_EVENT_NAMES", + "ModelStreamError": "NO_UNIQUE_EVENT_NAMES", + "InternalStreamFailure": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file From 4b748f41bb8a1bd3afb5b6130445776b25de6322 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 23 Apr 2025 09:31:40 -0700 Subject: [PATCH 3/6] Fix codegen-generated-classes-test (add legacy customization) --- .../customization.config | 37 ++++++++------ .../endpointproviders/customization.config | 24 ++++++--- .../eventstreams/customization.config | 18 +++++-- .../query/customization.config | 11 ++++- .../serviceconfig/customization.config | 13 ++++- .../waiters/customization.config | 11 ++++- .../xml/customization.config | 47 +++++++++++------- .../xmlinternalplugins/customization.config | 49 +++++++++++-------- 8 files changed, 141 insertions(+), 69 deletions(-) diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/customresponsemetadata/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/customresponsemetadata/customization.config index b23341dbf867..88b88e938ad2 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/customresponsemetadata/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/customresponsemetadata/customization.config @@ -1,5 +1,5 @@ { - "verifiedSimpleMethods" : [ + "verifiedSimpleMethods": [ "allTypes", "deleteOperation", "mapOfStringToListOfStringInQueryParams", @@ -15,8 +15,8 @@ "nestedContainers" ], "customResponseMetadata": { - "FOO_ID" : "x-foo-id", - "BAR_ID" : "x-bar-id", + "FOO_ID": "x-foo-id", + "BAR_ID": "x-bar-id", "REQUEST_ID": "x-foobar-id" }, "skipEndpointTestGeneration": true, @@ -26,18 +26,27 @@ "useSraAuth": true, "endpointParameters": { "Tables": { - "required": false, - "type": "StringArray" + "required": false, + "type": "StringArray" } }, "customOperationContextParams": [ - { - "operationName": "GetOperationWithMapEndpointParam", - "operationContextParamsMap": { - "Tables": { - "path" : "keys(MapOfStrings)" - } + { + "operationName": "GetOperationWithMapEndpointParam", + "operationContextParamsMap": { + "Tables": { + "path": "keys(MapOfStrings)" + } + } } - } - ] -} + ], + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/endpointproviders/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/endpointproviders/customization.config index 341d2bca3aa5..b5c6897fc73e 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/endpointproviders/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/endpointproviders/customization.config @@ -1,6 +1,5 @@ { "skipEndpointTestGeneration": true, - "enableGenerateCompiledEndpointRules": false, "endpointParameters": { "PojoString": { @@ -23,11 +22,11 @@ "documentation": "A list of string that are map keys", "type": "StringArray" }, - "MissingRequestValuesListOfString": { - "required": false, - "documentation": "A list of string from a field that is not populated in the request", - "type": "StringArray" - } + "MissingRequestValuesListOfString": { + "required": false, + "documentation": "A list of string from a field that is not populated in the request", + "type": "StringArray" + } }, "customOperationContextParams": [ { @@ -50,5 +49,14 @@ } } } - ] -} + ], + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/eventstreams/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/eventstreams/customization.config index 40ae9f6030f1..b57b0d6db8de 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/eventstreams/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/eventstreams/customization.config @@ -1,6 +1,16 @@ { + "skipEndpointTestGeneration": true, "useLegacyEventGenerationScheme": { - "EventStream": ["LegacyGeneratedEvent"] - }, - "skipEndpointTestGeneration": true -} + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES", + "InputEventB": "NO_UNIQUE_EVENT_NAMES", + "InputEventTwo": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "LegacyGeneratedEvent": "NO_EVENT_SUBCLASS", + "TheEventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES", + "SecondEventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/query/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/query/customization.config index b5c73436bb3f..38d0c33c9c7f 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/query/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/query/customization.config @@ -1,3 +1,12 @@ { - "skipEndpointTestGeneration": true + "skipEndpointTestGeneration": true, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } } \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/serviceconfig/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/serviceconfig/customization.config index 17a346db4f7d..6c90bb92f996 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/serviceconfig/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/serviceconfig/customization.config @@ -1,9 +1,18 @@ { - "verifiedSimpleMethods" : [ + "verifiedSimpleMethods": [ "allTypes" ], "serviceConfig": { "className": "ProtocolRestJsonWithConfigConfiguration", "hasDualstackProperty": true + }, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } } -} +} \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/waiters/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/waiters/customization.config index b5c73436bb3f..38d0c33c9c7f 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/waiters/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/waiters/customization.config @@ -1,3 +1,12 @@ { - "skipEndpointTestGeneration": true + "skipEndpointTestGeneration": true, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } } \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xml/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xml/customization.config index 293c611d1e24..61017fd7c038 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xml/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xml/customization.config @@ -2,26 +2,35 @@ "skipEndpointTestGeneration": true, "requiredTraitValidationEnabled": true, "customSdkShapes": { - "shapes":{ - "SdkPartType":{ - "type":"string", - "enum":[ - "DEFAULT", - "LAST" - ] + "shapes": { + "SdkPartType": { + "type": "string", + "enum": [ + "DEFAULT", + "LAST" + ] + } } - } }, "shapeModifiers": { - "AllTypesStructure": { - "inject": [ - { - "SdkPartType": { - "shape": "SdkPartType", - "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." - } - } - ] - } + "AllTypesStructure": { + "inject": [ + { + "SdkPartType": { + "shape": "SdkPartType", + "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." + } + } + ] + } + }, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } } -} +} \ No newline at end of file diff --git a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xmlinternalplugins/customization.config b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xmlinternalplugins/customization.config index b40406d580de..5a14ab06dc93 100644 --- a/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xmlinternalplugins/customization.config +++ b/test/codegen-generated-classes-test/src/main/resources/codegen-resources/xmlinternalplugins/customization.config @@ -2,29 +2,38 @@ "skipEndpointTestGeneration": true, "requiredTraitValidationEnabled": true, "customSdkShapes": { - "shapes":{ - "SdkPartType":{ - "type":"string", - "enum":[ - "DEFAULT", - "LAST" - ] + "shapes": { + "SdkPartType": { + "type": "string", + "enum": [ + "DEFAULT", + "LAST" + ] + } } - } }, "shapeModifiers": { - "AllTypesStructure": { - "inject": [ - { - "SdkPartType": { - "shape": "SdkPartType", - "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." - } - } - ] - } + "AllTypesStructure": { + "inject": [ + { + "SdkPartType": { + "shape": "SdkPartType", + "documentation": "Indicates whether the request is a last part or not. This field will not be included in the request payload." + } + } + ] + } }, "internalPlugins": [ "software.amazon.awssdk.plugins.EndpointOverrideInternalTestPlugin" - ] -} + ], + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file From 1237efabb09d39d4a6fcdb7e4017f3e079a860ae Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 23 Apr 2025 13:03:42 -0700 Subject: [PATCH 4/6] Add legacy customization flags to protocol tests --- .../restjson/contenttype/customization.config | 17 +++++++++++++++-- .../restjson/customization.config | 19 ++++++++++++++++--- .../restxml/customization.config | 13 ++++++++++--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/test/protocol-tests/src/main/resources/codegen-resources/restjson/contenttype/customization.config b/test/protocol-tests/src/main/resources/codegen-resources/restjson/contenttype/customization.config index ec7c8d355d50..b244a219f33e 100644 --- a/test/protocol-tests/src/main/resources/codegen-resources/restjson/contenttype/customization.config +++ b/test/protocol-tests/src/main/resources/codegen-resources/restjson/contenttype/customization.config @@ -1,3 +1,16 @@ { - "skipEndpointTestGeneration": true -} + "skipEndpointTestGeneration": true, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "BlobAndHeadersEvent": "NO_UNIQUE_EVENT_NAMES", + "StringAndHeadersEvent": "NO_UNIQUE_EVENT_NAMES", + "HeadersOnlyEvent": "NO_UNIQUE_EVENT_NAMES", + "EndEvent": "NO_UNIQUE_EVENT_NAMES", + "ImplicitPayloadAndHeadersEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/test/protocol-tests/src/main/resources/codegen-resources/restjson/customization.config b/test/protocol-tests/src/main/resources/codegen-resources/restjson/customization.config index a2df149f84de..94d6a0ef7b42 100644 --- a/test/protocol-tests/src/main/resources/codegen-resources/restjson/customization.config +++ b/test/protocol-tests/src/main/resources/codegen-resources/restjson/customization.config @@ -1,5 +1,5 @@ { - "verifiedSimpleMethods" : [ + "verifiedSimpleMethods": [ "allTypes", "deleteOperation", "mapOfStringToListOfStringInQueryParams", @@ -17,5 +17,18 @@ "statusCodeInOutputOperation", "getOperationWithBody" ], - "skipEndpointTestGeneration": true -} + "skipEndpointTestGeneration": true, + "useLegacyEventGenerationScheme": { + "InputEventStream": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "InputEventStreamStringPayload": { + "InputEvent": "NO_UNIQUE_EVENT_NAMES" + }, + "EventStream": { + "EventOne": "NO_UNIQUE_EVENT_NAMES", + "EventTwo": "NO_UNIQUE_EVENT_NAMES", + "errorOne": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file diff --git a/test/protocol-tests/src/main/resources/codegen-resources/restxml/customization.config b/test/protocol-tests/src/main/resources/codegen-resources/restxml/customization.config index 2ca221e9d30e..f2e27b14e5b0 100644 --- a/test/protocol-tests/src/main/resources/codegen-resources/restxml/customization.config +++ b/test/protocol-tests/src/main/resources/codegen-resources/restxml/customization.config @@ -1,5 +1,5 @@ { - "verifiedSimpleMethods" : [ + "verifiedSimpleMethods": [ "allTypes", "deleteOperation", "mapOfStringToListOfStringInQueryParams", @@ -10,5 +10,12 @@ "queryParamWithoutValue", "restXmlTypes" ], - "skipEndpointTestGeneration": true -} + "skipEndpointTestGeneration": true, + "useLegacyEventGenerationScheme": { + "EventStream": { + "EventPayloadEvent": "NO_UNIQUE_EVENT_NAMES", + "NonEventPayloadEvent": "NO_UNIQUE_EVENT_NAMES", + "SecondEventPayloadEvent": "NO_UNIQUE_EVENT_NAMES" + } + } +} \ No newline at end of file From 5b35d9274c28ecd1643512e1a2a4e2aea99d387b Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Thu, 24 Apr 2025 11:58:01 -0700 Subject: [PATCH 5/6] Refactor/cleanup processor + add check for duplicated shape names --- .../DefaultCustomizationProcessor.java | 2 +- .../EventStreamSharedEventProcessor.java | 71 -------------- ...EventStreamUniqueEventShapesProcessor.java | 92 +++++++++++++++++++ 3 files changed, 93 insertions(+), 72 deletions(-) delete mode 100644 codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java create mode 100644 codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java index 7c12dd573a27..7890e5196ee4 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java @@ -37,7 +37,7 @@ public static CodegenCustomizationProcessor getProcessorFor( new SmithyRpcV2CborProtocolProcessor(), new RemoveExceptionMessagePropertyProcessor(), new UseLegacyEventGenerationSchemeProcessor(), - new EventStreamSharedEventProcessor(config.getUseLegacyEventGenerationScheme()), + new EventStreamUniqueEventShapesProcessor(config.getUseLegacyEventGenerationScheme()), new NewAndLegacyEventStreamProcessor(), new S3RemoveBucketFromUriProcessor(), new S3ControlRemoveAccountIdHostPrefixProcessor(), diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java deleted file mode 100644 index be70f95efaec..000000000000 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamSharedEventProcessor.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package software.amazon.awssdk.codegen.customization.processors; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor; -import software.amazon.awssdk.codegen.model.config.customization.LegacyEventGenerationMode; -import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; -import software.amazon.awssdk.codegen.model.service.Member; -import software.amazon.awssdk.codegen.model.service.ServiceModel; -import software.amazon.awssdk.codegen.model.service.Shape; - -/** - * Processor for eventstreams with shared events. This Processor does two things: 1. Apply the duplicateAndRenameSharedEvents - * customization 2. Raise helpful error messages on untransfromed shared events. - */ -public final class EventStreamSharedEventProcessor implements CodegenCustomizationProcessor { - private static final Logger log = LoggerFactory.getLogger(EventStreamSharedEventProcessor.class); - - private final Map> useLegacyEventGenerationScheme; - - public EventStreamSharedEventProcessor(Map> useLegacyEventGenerationScheme) { - this.useLegacyEventGenerationScheme = useLegacyEventGenerationScheme; - } - - @Override - public void preprocess(ServiceModel serviceModel) { - Map newEventShapes = new HashMap<>(); - for (Map.Entry shapeEntry : serviceModel.getShapes().entrySet()) { - if (shapeEntry.getValue().isEventstream()) { - Shape eventStreamShape = shapeEntry.getValue(); - Map eventLegacyModes = useLegacyEventGenerationScheme - .getOrDefault(shapeEntry.getKey(), Collections.emptyMap()); - for (Map.Entry memberEntry : eventStreamShape.getMembers().entrySet()) { - Shape memberTargetShape = serviceModel.getShape(memberEntry.getValue().getShape()); - LegacyEventGenerationMode legacyEventGenerationMode = eventLegacyModes - .getOrDefault(memberEntry.getKey(), LegacyEventGenerationMode.DISABLED); - - if (memberTargetShape.isEvent() && legacyEventGenerationMode == LegacyEventGenerationMode.DISABLED) { - String newShapeName = memberEntry.getValue().getShape() + shapeEntry.getKey(); - newEventShapes.put(newShapeName, memberTargetShape); - memberEntry.getValue().setShape(newShapeName); - } - } - } - } - serviceModel.getShapes().putAll(newEventShapes); - } - - @Override - public void postprocess(IntermediateModel intermediateModel) { - // no-op - } -} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java new file mode 100644 index 000000000000..bebe31b7110f --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java @@ -0,0 +1,92 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.codegen.customization.processors; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor; +import software.amazon.awssdk.codegen.model.config.customization.LegacyEventGenerationMode; +import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; +import software.amazon.awssdk.codegen.model.service.ServiceModel; +import software.amazon.awssdk.codegen.model.service.Shape; +import software.amazon.awssdk.utils.Logger; + +/** + * Processor for eventstreams that ensures that all eventstream event shapes are unique - for each eventstream/event it creates a + * new shape with a unique name constructed from the EventStream and Event shape names: `[ShapeName][EventStreamName]`. Any legacy + * eventstream/events (configured with the useLegacyEventGenerationScheme customization) are skipped. When an event shape is + * shared between multiple eventstreams, it causes SDK generation/compilation failures. The top level shape POJO implements the + * event stream interface for each stream and the return type of the sdkEventType method conflicts. + */ +public final class EventStreamUniqueEventShapesProcessor implements CodegenCustomizationProcessor { + private static final Logger log = Logger.loggerFor(EventStreamUniqueEventShapesProcessor.class); + + private final Map> useLegacyEventGenerationScheme; + + public EventStreamUniqueEventShapesProcessor( + Map> useLegacyEventGenerationScheme) { + this.useLegacyEventGenerationScheme = useLegacyEventGenerationScheme; + } + + @Override + public void preprocess(ServiceModel serviceModel) { + Map newEventShapes = new HashMap<>(); + serviceModel.getShapes().forEach((name, shape) -> { + if (!shape.isEventstream()) { + return; + } + + preprocessEventStream(serviceModel, name, shape, newEventShapes); + }); + serviceModel.getShapes().putAll(newEventShapes); + } + + private void preprocessEventStream(ServiceModel serviceModel, String eventStreamName, Shape eventStreamShape, Map newEventShapes) { + Map eventLegacyModes = useLegacyEventGenerationScheme + .getOrDefault(eventStreamName, Collections.emptyMap()); + + eventStreamShape.getMembers().forEach((memberName, member) -> { + String eventShapeName = member.getShape(); + Shape memberTargetShape = serviceModel.getShape(eventShapeName); + LegacyEventGenerationMode legacyEventGenerationMode = eventLegacyModes + .getOrDefault(memberName, LegacyEventGenerationMode.DISABLED); + + if (memberTargetShape.isEvent() && legacyEventGenerationMode == LegacyEventGenerationMode.DISABLED) { + String newShapeName = eventShapeName + eventStreamName; + if (serviceModel.getShapes().containsKey(newShapeName)) { + // TODO: This could be an error instead. Its unlikely we'll run into this. And if we do, not creating the + // unique name is only an issue when/if the event is shared with another event stream whos event/eventstream + // shape name is also in the model. + log.warn(() -> String.format("Shape name conflict, unable to create a new unique event shape name for %s in" + + " eventstream %s because %s already exists in the model. Skipping.", + eventShapeName, eventStreamName, newShapeName)); + } else { + log.debug(() -> String.format("Creating new, unique, event shape for %s in eventstream %s: %s", + eventShapeName, eventStreamName, newShapeName)); + newEventShapes.put(newShapeName, memberTargetShape); + member.setShape(newShapeName); + } + } + }); + } + + @Override + public void postprocess(IntermediateModel intermediateModel) { + // no-op + } +} From 9e7e11012793675959e55e008b13494bce0dcad2 Mon Sep 17 00:00:00 2001 From: Alex Woods Date: Wed, 30 Apr 2025 14:29:19 -0700 Subject: [PATCH 6/6] Move naming to NamingStrategy --- .../awssdk/codegen/IntermediateModelBuilder.java | 2 +- .../processors/DefaultCustomizationProcessor.java | 5 +++-- .../EventStreamUniqueEventShapesProcessor.java | 11 ++++++----- .../awssdk/codegen/naming/DefaultNamingStrategy.java | 7 +++++++ .../amazon/awssdk/codegen/naming/NamingStrategy.java | 10 ++++++++++ 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/IntermediateModelBuilder.java b/codegen/src/main/java/software/amazon/awssdk/codegen/IntermediateModelBuilder.java index 33290241d534..ae13fe41eb6c 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/IntermediateModelBuilder.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/IntermediateModelBuilder.java @@ -94,7 +94,7 @@ private List createShapeProcessors() { public IntermediateModel build() { CodegenCustomizationProcessor customization = DefaultCustomizationProcessor - .getProcessorFor(customConfig); + .getProcessorFor(customConfig, namingStrategy); customization.preprocess(service); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java index 7890e5196ee4..f19dda720993 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java @@ -18,6 +18,7 @@ import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor; import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessorChain; import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig; +import software.amazon.awssdk.codegen.naming.NamingStrategy; public final class DefaultCustomizationProcessor { @@ -25,7 +26,7 @@ private DefaultCustomizationProcessor() { } public static CodegenCustomizationProcessor getProcessorFor( - CustomizationConfig config) { + CustomizationConfig config, NamingStrategy namingStrategy) { return new CodegenCustomizationProcessorChain( new MetadataModifiersProcessor(config.getCustomServiceMetadata()), @@ -37,7 +38,7 @@ public static CodegenCustomizationProcessor getProcessorFor( new SmithyRpcV2CborProtocolProcessor(), new RemoveExceptionMessagePropertyProcessor(), new UseLegacyEventGenerationSchemeProcessor(), - new EventStreamUniqueEventShapesProcessor(config.getUseLegacyEventGenerationScheme()), + new EventStreamUniqueEventShapesProcessor(config.getUseLegacyEventGenerationScheme(), namingStrategy), new NewAndLegacyEventStreamProcessor(), new S3RemoveBucketFromUriProcessor(), new S3ControlRemoveAccountIdHostPrefixProcessor(), diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java index bebe31b7110f..e9f0cd3d6dee 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/EventStreamUniqueEventShapesProcessor.java @@ -23,6 +23,7 @@ import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.service.ServiceModel; import software.amazon.awssdk.codegen.model.service.Shape; +import software.amazon.awssdk.codegen.naming.NamingStrategy; import software.amazon.awssdk.utils.Logger; /** @@ -36,10 +37,13 @@ public final class EventStreamUniqueEventShapesProcessor implements CodegenCusto private static final Logger log = Logger.loggerFor(EventStreamUniqueEventShapesProcessor.class); private final Map> useLegacyEventGenerationScheme; + private final NamingStrategy namingStrategy; public EventStreamUniqueEventShapesProcessor( - Map> useLegacyEventGenerationScheme) { + Map> useLegacyEventGenerationScheme, + NamingStrategy namingStrategy) { this.useLegacyEventGenerationScheme = useLegacyEventGenerationScheme; + this.namingStrategy = namingStrategy; } @Override @@ -67,11 +71,8 @@ private void preprocessEventStream(ServiceModel serviceModel, String eventStream .getOrDefault(memberName, LegacyEventGenerationMode.DISABLED); if (memberTargetShape.isEvent() && legacyEventGenerationMode == LegacyEventGenerationMode.DISABLED) { - String newShapeName = eventShapeName + eventStreamName; + String newShapeName = namingStrategy.getUniqueEventStreamEventShapeName(member, eventStreamName); if (serviceModel.getShapes().containsKey(newShapeName)) { - // TODO: This could be an error instead. Its unlikely we'll run into this. And if we do, not creating the - // unique name is only an issue when/if the event is shared with another event stream whos event/eventstream - // shape name is also in the model. log.warn(() -> String.format("Shape name conflict, unable to create a new unique event shape name for %s in" + " eventstream %s because %s already exists in the model. Skipping.", eventShapeName, eventStreamName, newShapeName)); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java index e5a4904f295f..fb08c0813b7f 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java @@ -41,6 +41,7 @@ import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; import software.amazon.awssdk.codegen.model.intermediate.Metadata; +import software.amazon.awssdk.codegen.model.service.Member; import software.amazon.awssdk.codegen.model.service.ServiceModel; import software.amazon.awssdk.codegen.model.service.Shape; import software.amazon.awssdk.utils.Logger; @@ -411,6 +412,12 @@ public String getUnionEnumTypeName(MemberModel memberModel) { return screamCase(memberModel.getName()); } + @Override + public String getUniqueEventStreamEventShapeName(Member eventMember, String eventStreamName) { + return eventMember.getShape() + eventStreamName; + } + + private String rewriteInvalidMemberName(String memberName, Shape parentShape) { if (isJavaKeyword(memberName) || isDisallowedNameForShape(memberName, parentShape)) { return Utils.unCapitalize(memberName + CONFLICTING_NAME_SUFFIX); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java index 1fe32773d71f..5545da6ca9da 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java @@ -17,6 +17,7 @@ import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; +import software.amazon.awssdk.codegen.model.service.Member; import software.amazon.awssdk.codegen.model.service.Shape; import software.amazon.awssdk.core.SdkField; @@ -200,6 +201,15 @@ public interface NamingStrategy { */ String getExistenceCheckMethodName(String memberName, Shape parentShape); + /** + * Returns a unique shape name to use for an event member of an eventStream. + * + * @param eventMember The event member to get the shape name for. + * @param eventStreamName The name of the eventStream containing the member. + * @return Unique name for the event shape / eventStream combo. + */ + String getUniqueEventStreamEventShapeName(Member eventMember, String eventStreamName); + /** * Verify the customer-visible naming in the provided intermediate model will compile and is idiomatic to Java. */