From b9620a5bf2c39f180c5b8544ad1d89dcc88ff7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Mon, 17 Jun 2024 11:49:56 +0200 Subject: [PATCH] feat(core): validate that an input of type FILE didn't have any defaults --- .../core/models/flows/input/FileInput.java | 2 ++ .../core/validations/FileInputValidation.java | 16 ++++++++++ .../validator/FileInputValidator.java | 31 +++++++++++++++++++ .../io/kestra/core/models/flows/FlowTest.java | 12 +++++++ .../flows/invalids/inputs-validation.yaml | 15 +++++++++ 5 files changed, 76 insertions(+) create mode 100644 core/src/main/java/io/kestra/core/validations/FileInputValidation.java create mode 100644 core/src/main/java/io/kestra/core/validations/validator/FileInputValidator.java create mode 100644 core/src/test/resources/flows/invalids/inputs-validation.yaml diff --git a/core/src/main/java/io/kestra/core/models/flows/input/FileInput.java b/core/src/main/java/io/kestra/core/models/flows/input/FileInput.java index 76753ec16ae..78d2f1e17a6 100644 --- a/core/src/main/java/io/kestra/core/models/flows/input/FileInput.java +++ b/core/src/main/java/io/kestra/core/models/flows/input/FileInput.java @@ -1,6 +1,7 @@ package io.kestra.core.models.flows.input; import io.kestra.core.models.flows.Input; +import io.kestra.core.validations.FileInputValidation; import jakarta.validation.ConstraintViolationException; import lombok.Builder; import lombok.Getter; @@ -12,6 +13,7 @@ @SuperBuilder @Getter @NoArgsConstructor +@FileInputValidation public class FileInput extends Input { @Builder.Default public String extension = ".upl"; diff --git a/core/src/main/java/io/kestra/core/validations/FileInputValidation.java b/core/src/main/java/io/kestra/core/validations/FileInputValidation.java new file mode 100644 index 00000000000..689c7937e08 --- /dev/null +++ b/core/src/main/java/io/kestra/core/validations/FileInputValidation.java @@ -0,0 +1,16 @@ +package io.kestra.core.validations; + +import io.kestra.core.validations.validator.FileInputValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = FileInputValidator.class) +public @interface FileInputValidation { + String message() default "invalid file input"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/core/src/main/java/io/kestra/core/validations/validator/FileInputValidator.java b/core/src/main/java/io/kestra/core/validations/validator/FileInputValidator.java new file mode 100644 index 00000000000..d999fdcb96b --- /dev/null +++ b/core/src/main/java/io/kestra/core/validations/validator/FileInputValidator.java @@ -0,0 +1,31 @@ +package io.kestra.core.validations.validator; + +import io.kestra.core.models.flows.input.FileInput; +import io.kestra.core.validations.FileInputValidation; +import io.micronaut.core.annotation.AnnotationValue; +import io.micronaut.core.annotation.Introspected; +import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.validation.validator.constraints.ConstraintValidator; +import io.micronaut.validation.validator.constraints.ConstraintValidatorContext; +import jakarta.inject.Singleton; + +@Singleton +@Introspected +public class FileInputValidator implements ConstraintValidator { + @Override + public boolean isValid(@Nullable FileInput value, @NonNull AnnotationValue annotationMetadata, @NonNull ConstraintValidatorContext context) { + if (value == null) { + return true; // nulls are allowed according to spec + } + + if (value.getDefaults() != null) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate("no `defaults` can be set for inputs of type 'FILE'") + .addConstraintViolation(); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/core/src/test/java/io/kestra/core/models/flows/FlowTest.java b/core/src/test/java/io/kestra/core/models/flows/FlowTest.java index 9e6c3b9ff49..f6375503433 100644 --- a/core/src/test/java/io/kestra/core/models/flows/FlowTest.java +++ b/core/src/test/java/io/kestra/core/models/flows/FlowTest.java @@ -142,6 +142,18 @@ void allTasksWithChildsAndTriggerIds() { assertThat(all.size(), is(3)); } + @Test + void inputValidation() { + Flow flow = this.parse("flows/invalids/inputs-validation.yaml"); + Optional validate = modelValidator.isValid(flow); + + assertThat(validate.isPresent(), is(true)); + assertThat(validate.get().getConstraintViolations().size(), is(2)); + + assertThat(validate.get().getMessage(), containsString("inputs[0]: no `defaults` can be set for inputs of type 'FILE'")); + assertThat(validate.get().getMessage(), containsString("inputs[1]: `itemType` cannot be `ARRAY")); + } + private Flow parse(String path) { URL resource = TestsUtils.class.getClassLoader().getResource(path); assert resource != null; diff --git a/core/src/test/resources/flows/invalids/inputs-validation.yaml b/core/src/test/resources/flows/invalids/inputs-validation.yaml new file mode 100644 index 00000000000..8fb108c95d5 --- /dev/null +++ b/core/src/test/resources/flows/invalids/inputs-validation.yaml @@ -0,0 +1,15 @@ +id: inputs-validations +namespace: io.kestra.tests + +inputs: + - id: file + type: FILE + defaults: something + - id: array + type: ARRAY + itemType: ARRAY + +tasks: + - id: hello + type: io.kestra.plugin.core.log.Log + message: Hello World! 🚀 \ No newline at end of file