From f60c17e9b85181d868a55cba8536ea3ac240ac13 Mon Sep 17 00:00:00 2001 From: Michael Dowling Date: Fri, 24 Sep 2021 10:38:05 -0700 Subject: [PATCH] Add Operation helper method to include service errors --- .../model/knowledge/OperationIndex.java | 4 +- .../smithy/model/shapes/OperationShape.java | 32 ++++++++++++- .../model/shapes/OperationShapeTest.java | 46 +++++++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 smithy-model/src/test/java/software/amazon/smithy/model/shapes/OperationShapeTest.java diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java index ce0fc5267f6..b95cc3f31d9 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/knowledge/OperationIndex.java @@ -18,11 +18,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.TreeSet; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.OperationShape; @@ -189,7 +189,7 @@ public List getErrors(ToShapeId operation) { * @return Returns the list of error structures, or an empty list. */ public List getErrors(ToShapeId service, ToShapeId operation) { - Set result = new TreeSet<>(getErrors(service)); + Set result = new LinkedHashSet<>(getErrors(service)); result.addAll(getErrors(operation)); return new ArrayList<>(result); } diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java index 28a1158e49a..74b3c500e4c 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/OperationShape.java @@ -17,9 +17,12 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; +import software.amazon.smithy.model.knowledge.OperationIndex; import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -79,18 +82,43 @@ public Optional getOutput() { } /** - *

Gets a list of the error shape IDs that can be encountered.

+ *

Gets a list of the error shape IDs bound directly to the operation + * that can be encountered. + * + *

This DOES NOT include errors that are common to a service. Operations + * can be bound to multiple services, so common service errors cannot be + * returned by this method. Use {@link #getErrors(ServiceShape)} or + * {@link OperationIndex#getErrors(ToShapeId, ToShapeId)} to get all of the + * errors an operation can encounter when used within a service.

* *

Each returned {@link ShapeId} must resolve to a * {@link StructureShape} that is targeted by an error trait; however, * this is only guaranteed after a model is validated.

* * @return Returns the errors. + * @see #getErrors(ServiceShape) + * @see OperationIndex#getErrors(ToShapeId, ToShapeId) */ public List getErrors() { return errors; } + /** + *

Gets a list of the error shape IDs the operation can encounter, + * including any common errors of a service. + * + *

No validation is performed here to ensure that the operation is + * actually bound to the given service shape. + * + * @return Returns the errors. + * @see OperationIndex#getErrors(ToShapeId, ToShapeId) + */ + public List getErrors(ServiceShape service) { + Set result = new LinkedHashSet<>(service.getErrors()); + result.addAll(getErrors()); + return new ArrayList<>(result); + } + @Override public boolean equals(Object other) { if (!super.equals(other)) { @@ -109,7 +137,7 @@ public boolean equals(Object other) { public static final class Builder extends AbstractShapeBuilder { private ShapeId input; private ShapeId output; - private List errors = new ArrayList<>(); + private final List errors = new ArrayList<>(); @Override public ShapeType getShapeType() { diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/OperationShapeTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/OperationShapeTest.java new file mode 100644 index 00000000000..8ddc3ff19f5 --- /dev/null +++ b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/OperationShapeTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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.smithy.model.shapes; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class OperationShapeTest { + @Test + public void combinesErrorsWithServiceErrors() { + ServiceShape service = ServiceShape.builder() + .id("com.foo#Example") + .version("x") + .addError("com.foo#Common1") + .addError(ShapeId.from("com.foo#Common2")) + .build(); + + OperationShape operation = OperationShape.builder() + .id("com.foo#Operation") + .addError("com.foo#OperationError") + .build(); + + List allErrors = operation.getErrors(service); + + assertThat(allErrors, contains( + ShapeId.from("com.foo#Common1"), + ShapeId.from("com.foo#Common2"), + ShapeId.from("com.foo#OperationError"))); + } +}