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:
+ *
+ * - {@code minLength} and/or {@code maxLength} for a String
+ * - {@code minItems} and/or {@code maxItems} for a list/array
+ * - {@code minProperties} and/or {@code maxProperties} for a map
+ *
+ *
+ *
+ * @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;
+}