diff --git a/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/AbstractJsonSchema.java b/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/AbstractJsonSchema.java index 5dc0bad6b35..7a036885edc 100644 --- a/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/AbstractJsonSchema.java +++ b/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/AbstractJsonSchema.java @@ -43,6 +43,7 @@ import io.fabric8.generator.annotation.Nullable; import io.fabric8.generator.annotation.Pattern; import io.fabric8.generator.annotation.Required; +import io.fabric8.generator.annotation.Size; import io.fabric8.generator.annotation.ValidationRule; import io.fabric8.generator.annotation.ValidationRules; import io.fabric8.kubernetes.api.model.GenericKubernetesResource; @@ -234,6 +235,8 @@ class PropertyMetadata { private Double max; private Boolean exclusiveMaximum; private String pattern; + private Long minLength; + private Long maxLength; private boolean nullable; private String format; private List validationRules = new ArrayList<>(); @@ -254,11 +257,24 @@ public PropertyMetadata(JsonSchema value, BeanProperty beanProperty) { } if (value.isStringSchema()) { + System.out.println("String schema"); StringSchema stringSchema = value.asStringSchema(); // only set if ValidationSchemaFactoryWrapper is used this.pattern = stringSchema.getPattern(); - //this.maxLength = ofNullable(stringSchema.getMaxLength()).map(Integer::doubleValue).orElse(null); - //this.minLength = ofNullable(stringSchema.getMinLength()).map(Integer::doubleValue).orElse(null); + + this.maxLength = ofNullable(stringSchema.getMaxLength()) + .map(Integer::longValue) + .or(() -> ofNullable(beanProperty.getAnnotation(Size.class)) + .map(Size::max) + .filter(v -> v < Long.MAX_VALUE)) + .orElse(null); + this.minLength = ofNullable(stringSchema.getMinLength()) + .map(Integer::longValue) + .or(() -> ofNullable(beanProperty.getAnnotation(Size.class)) + .map(Size::min) + .filter(v -> v > 0)) + .orElse(null); + } else { // TODO: process the other schema types for validation values } @@ -313,6 +329,10 @@ public void updateSchema(T schema) { schema.setExclusiveMaximum(exclusiveMaximum); schema.setMinimum(min); schema.setExclusiveMinimum(exclusiveMinimum); + + schema.setMinLength(minLength); + schema.setMaxLength(maxLength); + schema.setPattern(pattern); schema.setFormat(format); if (preserveUnknownFields) { diff --git a/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/KubernetesJSONSchemaProps.java b/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/KubernetesJSONSchemaProps.java index 171bd1d823e..496654f4d32 100644 --- a/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/KubernetesJSONSchemaProps.java +++ b/crd-generator/api-v2/src/main/java/io/fabric8/crdv2/generator/KubernetesJSONSchemaProps.java @@ -38,6 +38,10 @@ public interface KubernetesJSONSchemaProps { void setExclusiveMinimum(Boolean b); + void setMinLength(Long min); + + void setMaxLength(Long max); + void setPattern(String pattern); void setFormat(String format); diff --git a/crd-generator/test/src/test/java/io/fabric8/crd/generator/approvaltests/validation/ValidationSpec.java b/crd-generator/test/src/test/java/io/fabric8/crd/generator/approvaltests/validation/ValidationSpec.java index ddeb87bf4b2..239abb8a8fc 100644 --- a/crd-generator/test/src/test/java/io/fabric8/crd/generator/approvaltests/validation/ValidationSpec.java +++ b/crd-generator/test/src/test/java/io/fabric8/crd/generator/approvaltests/validation/ValidationSpec.java @@ -18,6 +18,7 @@ import io.fabric8.generator.annotation.Max; import io.fabric8.generator.annotation.Min; import io.fabric8.generator.annotation.Pattern; +import io.fabric8.generator.annotation.Size; import lombok.Data; @Data @@ -181,6 +182,13 @@ static class ValidationOnDoublePrim { static class ValidationOnString { @Pattern("(a|b)+") private String pattern; + + @Size(min = 1) + private String minLength1; + @Size(max = 1) + private String maxLength1; + @Size(min = 1, max = 3) + private String minLength1maxLength3; } } diff --git a/crd-generator/test/src/test/resources/io/fabric8/crd/generator/approvaltests/CRDGeneratorApprovalTest.approvalTest.validations.samples.fabric8.io.v1.approved.yml b/crd-generator/test/src/test/resources/io/fabric8/crd/generator/approvaltests/CRDGeneratorApprovalTest.approvalTest.validations.samples.fabric8.io.v1.approved.yml index 24dbfaf842e..de18a96b5d3 100644 --- a/crd-generator/test/src/test/resources/io/fabric8/crd/generator/approvaltests/CRDGeneratorApprovalTest.approvalTest.validations.samples.fabric8.io.v1.approved.yml +++ b/crd-generator/test/src/test/resources/io/fabric8/crd/generator/approvaltests/CRDGeneratorApprovalTest.approvalTest.validations.samples.fabric8.io.v1.approved.yml @@ -235,6 +235,16 @@ spec: type: "object" onString: properties: + maxLength1: + maxLength: 1 + type: "string" + minLength1: + minLength: 1 + type: "string" + minLength1maxLength3: + maxLength: 3 + minLength: 1 + type: "string" pattern: pattern: "(a|b)+" type: "string" diff --git a/generator-annotations/src/main/java/io/fabric8/generator/annotation/Size.java b/generator-annotations/src/main/java/io/fabric8/generator/annotation/Size.java new file mode 100644 index 00000000000..fae51277b5b --- /dev/null +++ b/generator-annotations/src/main/java/io/fabric8/generator/annotation/Size.java @@ -0,0 +1,30 @@ +package io.fabric8.generator.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Decorates the resulting property with size limits. + *

+ * The annotation can be used on strings, list/arrays and maps and will result in an appropriate JSON Schema constraint: + *

+ *

+ * + * @see + * Kubernetes Docs - API Reference - CRD v1 - JSONSchemaProps + * + */ +@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE_USE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Size { + long min() default 0; + + long max() default Long.MAX_VALUE; +}