Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRDGenerator: Cannot specify @Pattern annotation on type parameter #6282

Closed
adriansuarez opened this issue Aug 17, 2024 · 1 comment · Fixed by #6322
Closed

CRDGenerator: Cannot specify @Pattern annotation on type parameter #6282

adriansuarez opened this issue Aug 17, 2024 · 1 comment · Fixed by #6322
Labels
component/crd-generator Related to the CRD generator Waiting on feedback Issues that require feedback from User/Other community members
Milestone

Comments

@adriansuarez
Copy link

Is your enhancement related to a problem? Please describe

Consider the following field in a CRD class:

    @JsonPropertyDescription("A list of names matching the pattern `[A-Za-z][A-Za-z0-9_]*`")
    @JsonProperty
    public List<String> names;

What I would like to be able to add the @io.fabric8.generator.annotation.Pattern annotation so that the Kubernetes API server can validate that the elements of the array match the pattern.

Adding the annotation to the field itself causes the following JSONSchema to be created, which is not what I want:

              names:
                description: A list of names matching the pattern `[A-Za-z][A-Za-z0-9_]*`
                items:
                  type: string
                type: array
                pattern: [A-Za-z][A-Za-z0-9_]*

Describe the solution you'd like

I'd like to declare the validation constraint as follows:

    @JsonPropertyDescription("A list of names")
    @JsonProperty
    public List<@Pattern("[A-Za-z][A-Za-z0-9_]*") String> names;

And have that generate the following JSONSchema:

              names:
                description: A list of names`
                items:
                  type: string
                  pattern: [A-Za-z][A-Za-z0-9_]*
                type: array

This can be achieved by changing the @Target on @Pattern to include ElementType.TYPE_USE, and detecting the presence of the annotation on the type parameters in the declaration to include the pattern constraint.

Describe alternatives you've considered

I've tried various ways to "trick" Fabric8 into letting me put the pattern constraint in the correct place, and nothing has worked.

I tried creating a wrapper class for the string that I can attach the annotation to:

@JsonSerialize(as = String.class)
public class Name {

  private final String value;

  @JsonCreator
  public Name(String value) {
    this.value = value;
  }

  @Pattern("[A-Za-z][A-Za-z0-9_]*")
  @JsonValue
  public String getValue() {
    return value;
  }
}

Unfortunately, the CRD generator does not detect that this class is supposed to be serialized as a string.

The other alternative would be to just have a normal wrapper object that I can attach the annotation to, but that would create gratuitous nesting of properties that I do not want.

Additional context

No response

@shawkins
Copy link
Contributor

This can be achieved by changing the @target on @pattern to include ElementType.TYPE_USE, and detecting the presence of the annotation on the type parameters in the declaration to include the pattern constraint.

That seems to be relatively unsupported in Jackson v2 - https://groups.google.com/g/jackson-user/c/f7ZTj-0PFDQ and indeed with the annotation modified, I don't see the annotation in the type information provided to the JSONSchema when poking around in the debugger. There would need to be additional introspection, potentially based upon some hacks like the collectValidationRules method.

Unfortunately, the CRD generator does not detect that this class is supposed to be serialized as a string.

The v2 CRD generator will produce string for the following:

  @Pattern("[A-Za-z][A-Za-z0-9_]*")
  public class Name {

    private final String value;

    @JsonCreator
    public Name(String value) {
      this.value = value;
    }

    @JsonValue
    public String getValue() {
      return value;
    }
  }

  public List<Name> names;

However the Pattern is still not associated because it is not seen by jackson as being associated with the parent field.

If the beanProperty is a collection, and the collection type is string, but the collection class is not java.lang.String we can use:

beanProperty.getType().getContentType().getRawClass().getAnnotation(Pattern.class) to find the nested annotation with this convention. However I agree it's not ideal to have this type of workaround.

@manusa manusa added component/crd-generator Related to the CRD generator Waiting on feedback Issues that require feedback from User/Other community members labels Aug 27, 2024
shawkins added a commit to shawkins/kubernetes-client that referenced this issue Aug 30, 2024
shawkins added a commit to shawkins/kubernetes-client that referenced this issue Aug 31, 2024
shawkins added a commit to shawkins/kubernetes-client that referenced this issue Aug 31, 2024
manusa pushed a commit to shawkins/kubernetes-client that referenced this issue Sep 16, 2024
@manusa manusa added this to the 7.0.0 milestone Sep 16, 2024 — with automated-tasks
@manusa manusa closed this as completed in cc33729 Sep 17, 2024
@manusa manusa changed the title CRD Generator: Cannot specify @Pattern annotation on type parameter CRDGenerator: Cannot specify @Pattern annotation on type parameter Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/crd-generator Related to the CRD generator Waiting on feedback Issues that require feedback from User/Other community members
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants