Skip to content

Commit

Permalink
fix: rely upon jackson json schema for java types
Browse files Browse the repository at this point in the history
closes fabric8io#5866

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
  • Loading branch information
shawkins committed Apr 10, 2024
1 parent fbcc9b6 commit b2fdf7c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Fix #5847: Missing `Log4j2Plugins.dat` descriptor in Kubernetes Lookup
* Fix #5853: [java-generator] Gracefully handle colliding enum definitions
* Fix #5860: Corrections to java-generator gradle plugin extension
* Fix #5866: Addressed cycle in crd generation with Java 19+ and ZonedDateTime
* Fix #5817: NPE on EKS OIDC cluster when token needs to be refreshed

#### Improvements
Expand Down
5 changes: 5 additions & 0 deletions crd-generator/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<artifactId>kubernetes-client-api</artifactId>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
</dependency>

<dependency>
<groupId>io.fabric8</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
package io.fabric8.crd.generator;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
import io.fabric8.crd.generator.InternalSchemaSwaps.SwapResult;
import io.fabric8.crd.generator.annotation.SchemaSwap;
import io.fabric8.crd.generator.utils.Types;
import io.fabric8.generator.annotation.ValidationRule;
import io.fabric8.kubernetes.api.model.Duration;
import io.fabric8.kubernetes.api.model.IntOrString;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
import io.sundr.builder.internal.functions.TypeAs;
import io.sundr.model.AnnotationRef;
import io.sundr.model.ClassRef;
Expand Down Expand Up @@ -122,6 +126,8 @@ public abstract class AbstractJsonSchema<T, B> {
public static final String JSON_NODE_TYPE = "com.fasterxml.jackson.databind.JsonNode";
public static final String ANY_TYPE = "io.fabric8.kubernetes.api.model.AnyType";

private static final JsonSchemaGenerator GENERATOR;

static {
COMMON_MAPPINGS.put(STRING_REF, STRING_MARKER);
COMMON_MAPPINGS.put(DATE_REF, STRING_MARKER);
Expand All @@ -138,6 +144,9 @@ public abstract class AbstractJsonSchema<T, B> {
COMMON_MAPPINGS.put(QUANTITY_REF, INT_OR_STRING_MARKER);
COMMON_MAPPINGS.put(INT_OR_STRING_REF, INT_OR_STRING_MARKER);
COMMON_MAPPINGS.put(DURATION_REF, STRING_MARKER);
ObjectMapper mapper = new ObjectMapper();
new KubernetesSerialization(mapper, false);
GENERATOR = new JsonSchemaGenerator(mapper);
}

public static String getSchemaTypeFor(TypeRef typeRef) {
Expand Down Expand Up @@ -853,15 +862,34 @@ private T internalFromImpl(String name, TypeRef typeRef, LinkedHashMap<String, S

private T resolveNestedClass(String name, TypeDef def, LinkedHashMap<String, String> visited,
InternalSchemaSwaps schemaSwaps) {
if (visited.put(def.getFullyQualifiedName(), name) != null) {
String fullyQualifiedName = def.getFullyQualifiedName();
if (fullyQualifiedName.startsWith("java.") || fullyQualifiedName.startsWith("javax.")) {
try {
Class<?> clazz = Class.forName(fullyQualifiedName);
// TODO: cache this
JsonSchema schema = GENERATOR.generateSchema(clazz);
if (schema.isIntegerSchema()) {
return singleProperty(INTEGER_MARKER);
} else if (schema.isNumberSchema()){
return singleProperty(NUMBER_MARKER);
} else if (schema.isBooleanSchema()) {
return singleProperty(BOOLEAN_MARKER);
} else if (schema.isStringSchema()) {
return singleProperty(STRING_MARKER);
}
} catch (Exception e) {
LOGGER.debug("Something went wrong with detecting java type schema for {}, will use full introspection instead property {}", fullyQualifiedName, e);
}
}
if (visited.put(fullyQualifiedName, name) != null) {
throw new IllegalArgumentException(
"Found a cyclic reference involving the field of type " + def.getFullyQualifiedName() + " starting a field "
"Found a cyclic reference involving the field of type " + fullyQualifiedName + " starting a field "
+ visited.entrySet().stream().map(e -> e.getValue() + " >>\n" + e.getKey()).collect(Collectors.joining(".")) + "."
+ name);
}

T res = internalFromImpl(def, visited, schemaSwaps);
visited.remove(def.getFullyQualifiedName());
visited.remove(fullyQualifiedName);
return res;
}

Expand Down

0 comments on commit b2fdf7c

Please sign in to comment.