From 8a5fe054bf09da349862cdb0fa106d45d0d53b9a Mon Sep 17 00:00:00 2001 From: JordonPhillips Date: Tue, 26 Nov 2019 15:11:46 -0800 Subject: [PATCH] Add validation for length trait values --- .../validators/LengthTraitValidator.java | 58 +++++++++++++++ ...e.amazon.smithy.model.validation.Validator | 1 + .../errorfiles/validators/length-trait.errors | 3 + .../errorfiles/validators/length-trait.json | 73 +++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/LengthTraitValidator.java create mode 100644 smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.errors create mode 100644 smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.json diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/LengthTraitValidator.java b/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/LengthTraitValidator.java new file mode 100644 index 00000000000..198981669f4 --- /dev/null +++ b/smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/LengthTraitValidator.java @@ -0,0 +1,58 @@ +/* + * Copyright 2019 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.validation.validators; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.traits.LengthTrait; +import software.amazon.smithy.model.traits.Trait; +import software.amazon.smithy.model.validation.AbstractValidator; +import software.amazon.smithy.model.validation.ValidationEvent; +import software.amazon.smithy.utils.Pair; + +public class LengthTraitValidator extends AbstractValidator { + @Override + public List validate(Model model) { + return model.shapes() + .flatMap(shape -> Trait.flatMapStream(shape, LengthTrait.class)) + .flatMap(pair -> validateLengthTrait(model, pair.getLeft(), pair.getRight()).stream()) + .collect(Collectors.toList()); + } + + private List validateLengthTrait(Model model, Shape shape, LengthTrait trait) { + List events = new ArrayList<>(); + trait.getMin() + .filter(min -> min < 0) + .map(min -> error(shape, trait, "A length trait is applied with a negative `min` value.")) + .ifPresent(events::add); + + trait.getMax() + .filter(max -> max < 0) + .map(max -> error(shape, trait, "A length trait is applied with a negative `max` value.")) + .ifPresent(events::add); + + trait.getMin() + .flatMap(min -> trait.getMax().map(max -> Pair.of(min, max))) + .filter(pair -> pair.getLeft() > pair.getRight()) + .map(pair -> error(shape, trait, "A length trait is applied with a `min` value greater than " + + "its `max` value.")) + .map(events::add); + return events; + } +} diff --git a/smithy-model/src/main/resources/META-INF/services/software.amazon.smithy.model.validation.Validator b/smithy-model/src/main/resources/META-INF/services/software.amazon.smithy.model.validation.Validator index 1ec659528aa..382d319ac1e 100644 --- a/smithy-model/src/main/resources/META-INF/services/software.amazon.smithy.model.validation.Validator +++ b/smithy-model/src/main/resources/META-INF/services/software.amazon.smithy.model.validation.Validator @@ -15,6 +15,7 @@ software.amazon.smithy.model.validation.validators.HttpPrefixHeadersTraitValidat software.amazon.smithy.model.validation.validators.HttpQueryTraitValidator software.amazon.smithy.model.validation.validators.HttpResponseCodeSemanticsValidator software.amazon.smithy.model.validation.validators.HttpUriConflictValidator +software.amazon.smithy.model.validation.validators.LengthTraitValidator software.amazon.smithy.model.validation.validators.PaginatedTraitValidator software.amazon.smithy.model.validation.validators.PrivateAccessValidator software.amazon.smithy.model.validation.validators.RangeTraitValidator diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.errors b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.errors new file mode 100644 index 00000000000..d606507c4eb --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.errors @@ -0,0 +1,3 @@ +[ERROR] ns.foo#Invalid1: A length trait is applied with a negative `max` value. | LengthTrait +[ERROR] ns.foo#Invalid2: A length trait is applied with a negative `min` value. | LengthTrait +[ERROR] ns.foo#Invalid3: A length trait is applied with a `min` value greater than its `max` value. | LengthTrait \ No newline at end of file diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.json b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.json new file mode 100644 index 00000000000..a1a80163185 --- /dev/null +++ b/smithy-model/src/test/resources/software/amazon/smithy/model/errorfiles/validators/length-trait.json @@ -0,0 +1,73 @@ +{ + "smithy": "0.4.0", + "ns.foo": { + "shapes": { + "Valid1": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "min": 0 + } + }, + "Valid2": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "max": 1 + } + }, + "Valid3": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "min": 0, + "max": 1 + } + }, + "Valid4": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "min": 4, + "max": 4 + } + }, + "Invalid1": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "max": -1 + } + }, + "Invalid2": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "min": -1 + } + }, + "Invalid3": { + "type": "list", + "member": { + "target": "smithy.api#String" + }, + "smithy.api#length": { + "min": 5, + "max": 4 + } + } + } + } +}