Skip to content

Commit

Permalink
refactor: OpenAPI-based generator and Maven Plugin Java 8 compatible
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Nuri <marc@marcnuri.com>
  • Loading branch information
manusa committed Jul 18, 2024
1 parent f9c5d1d commit 26886fa
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 128 deletions.
6 changes: 3 additions & 3 deletions kubernetes-model-generator/openapi/maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
<packaging>maven-plugin</packaging>

<properties>
<maven.compiler.release>11</maven.compiler.release>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<!-- <maven.compiler.release>11</maven.compiler.release>-->
<!-- <maven.compiler.target>11</maven.compiler.target>-->
<!-- <maven.compiler.source>11</maven.compiler.source>-->
<maven.deploy.skip>true</maven.deploy.skip><!-- Keep module private -->
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ApiVersion {

@Override
public String toString() {
if (group == null || group.isBlank()) {
if (group == null || group.trim().isEmpty()) {
return version;
}
return group + "/" + version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
package io.fabric8.kubernetes.schema.generator;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -56,8 +58,9 @@ public GeneratorUtils(GeneratorSettings settings) {
}

public String readTemplate(String name) {
try (var stream = SchemaUtils.class.getResourceAsStream("/templates/" + name + ".mustache")) {
return new String(Objects.requireNonNull(stream).readAllBytes(), StandardCharsets.UTF_8);
try (InputStream stream = Objects
.requireNonNull(SchemaUtils.class.getResourceAsStream("/templates/" + name + ".mustache"))) {
return IOUtils.toString(stream, StandardCharsets.UTF_8);
} catch (IOException ex) {
settings.getLogger().severe(ex.getMessage());
throw new GeneratorException("Can't load template " + name);
Expand All @@ -66,7 +69,7 @@ public String readTemplate(String name) {

public final void writeFile(Path file, String fileContents) {
try {
Files.writeString(file, fileContents,
Files.write(file, fileContents.getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException ex) {
settings.getLogger().severe(ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
*/
package io.fabric8.kubernetes.schema.generator;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

public class ImportOrderComparator implements Comparator<String> {
private static final Set<String> JAVA_PACKAGES = Set.of("java", "javax");
private static final Set<String> JAVA_PACKAGES = new HashSet<>(Arrays.asList("java", "javax"));

@Override
public int compare(String o1, String o2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
import io.swagger.v3.oas.models.media.StringSchema;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
Expand All @@ -40,64 +43,82 @@ public class SchemaUtils {
private static final String OBJECT_PRIMITIVE = "Object";
private static final String STRING_PRIMITIVE = "String";

private static final Map<String, String> REF_TO_JAVA_TYPE_MAP = Map.of(
"#/components/schemas/io.k8s.apimachinery.pkg.util.intstr.IntOrString", "io.fabric8.kubernetes.api.model.IntOrString",
"#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity", "io.fabric8.kubernetes.api.model.Quantity",
"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", "io.fabric8.kubernetes.api.model.ObjectMeta",
"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta_v2", "io.fabric8.kubernetes.api.model.ObjectMeta",
"#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension", "io.fabric8.kubernetes.api.model.KubernetesResource",
"#/components/schemas/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSON",
"com.fasterxml.jackson.databind.JsonNode",
"#/components/schemas/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSON",
"com.fasterxml.jackson.databind.JsonNode");

private static final Map<String, String> REF_TO_JAVA_PRIMITIVE_MAP = Map.of(
"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time", "String");

private static final Map<String, String> JAVA_CLASS_SERIALIZER_MAP = Map.of(
"io.fabric8.kubernetes.api.model.MicroTime", "io.fabric8.kubernetes.api.model.MicroTimeSerDes.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArraySerDe.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArraySerDe.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBoolSerDe.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBoolSerDe.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArraySerDe.Serializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArraySerDe.Serializer.class");

private static final Map<String, String> JAVA_CLASS_DESERIALIZER_MAP = Map.of(
"io.fabric8.kubernetes.api.model.MicroTime", "io.fabric8.kubernetes.api.model.MicroTimeSerDes.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArraySerDe.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArraySerDe.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBoolSerDe.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBoolSerDe.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArraySerDe.Deserializer.class",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArraySerDe.Deserializer.class");

private static final Map<String, String> REF_SERIALIZER_MAP = Map.of(
// "#/components/schemas/io.k8s.apimachinery.pkg.util.intstr.IntOrString", "com.marcnuri.yakc.model.serialization.IntOrStringSerializer.class"
);

private static final Map<String, String> TYPE_MAP = Map.of(
"boolean", "Boolean",
"int32", "Integer",
"int64", "Long",
"double", "Double",
"number", "Number",
"object", OBJECT_PRIMITIVE,
"string", STRING_PRIMITIVE);

private static final Set<String> PROTECTED_WORDS = Set.of(
private static final Map<String, String> REF_TO_JAVA_TYPE_MAP = new LinkedHashMap<>();
static {
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.util.intstr.IntOrString",
"io.fabric8.kubernetes.api.model.IntOrString");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.api.resource.Quantity",
"io.fabric8.kubernetes.api.model.Quantity");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta",
"io.fabric8.kubernetes.api.model.ObjectMeta");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta_v2",
"io.fabric8.kubernetes.api.model.ObjectMeta");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension",
"io.fabric8.kubernetes.api.model.KubernetesResource");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSON",
"com.fasterxml.jackson.databind.JsonNode");
REF_TO_JAVA_TYPE_MAP.put("#/components/schemas/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSON",
"com.fasterxml.jackson.databind.JsonNode");
}

private static final Map<String, String> REF_TO_JAVA_PRIMITIVE_MAP = new LinkedHashMap<>();
static {
REF_TO_JAVA_PRIMITIVE_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time", "String");
}

private static final Map<String, String> JAVA_CLASS_SERIALIZER_MAP = new LinkedHashMap<>();
static {
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.MicroTime",
"io.fabric8.kubernetes.api.model.MicroTimeSerDes.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArraySerDe.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArraySerDe.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBoolSerDe.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBoolSerDe.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArraySerDe.Serializer.class");
JAVA_CLASS_SERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArraySerDe.Serializer.class");
}

private static final Map<String, String> JAVA_CLASS_DESERIALIZER_MAP = new LinkedHashMap<>();
static {
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.MicroTime",
"io.fabric8.kubernetes.api.model.MicroTimeSerDes.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrArraySerDe.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrArraySerDe.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrBoolSerDe.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBool",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrBoolSerDe.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsOrStringArraySerDe.Deserializer.class");
JAVA_CLASS_DESERIALIZER_MAP.put("io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArray",
"io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaPropsOrStringArraySerDe.Deserializer.class");
}

private static final Map<String, String> REF_SERIALIZER_MAP = Collections.emptyMap();// new LinkedHashMap<>();
static {
// REF_SERIALIZER_MAP.put("#/components/schemas/io.k8s.apimachinery.pkg.util.intstr.IntOrString", "com.marcnuri.yakc.model.serialization.IntOrStringSerializer.class");
}

private static final Map<String, String> TYPE_MAP = new LinkedHashMap<>();
static {
TYPE_MAP.put("boolean", "Boolean");
TYPE_MAP.put("int32", "Integer");
TYPE_MAP.put("int64", "Long");
TYPE_MAP.put("double", "Double");
TYPE_MAP.put("number", "Number");
TYPE_MAP.put("object", OBJECT_PRIMITIVE);
TYPE_MAP.put("string", STRING_PRIMITIVE);
}

private static final Set<String> PROTECTED_WORDS = new HashSet<>(Arrays.asList(
"continue",
"default",
"enum",
Expand All @@ -107,7 +128,7 @@ public class SchemaUtils {
"private",
"for",
"return",
"package");
"package"));

private final GeneratorSettings settings;

Expand Down Expand Up @@ -168,16 +189,18 @@ public String schemaToClassName(Consumer<String> addImport, Schema<?> schema) {
if (isString(schema)) {
return "String";
}
if (ref != null && !ref.isBlank()) {
return schemaRefToJavaPrimitive(schema)
.or(() -> schemaRefToJavaType(schema).map(javaType -> {
addImport.accept(javaType);
return javaType.substring(javaType.lastIndexOf('.') + 1);
}))
.orElseGet(() -> {
addImport.accept(refToModelPackage(ref));
return refToClassName(ref);
});
if (ref != null && !ref.trim().isEmpty()) {
final Optional<String> javaPrimitive = schemaRefToJavaPrimitive(schema);
if (javaPrimitive.isPresent()) {
return javaPrimitive.get();
}
final Optional<String> javaType = schemaRefToJavaType(schema);
if (javaType.isPresent()) {
addImport.accept(javaType.get());
return javaType.get().substring(javaType.get().lastIndexOf('.') + 1);
}
addImport.accept(refToModelPackage(ref));
return refToClassName(ref);
}
// Plain OpenAPI object map to KubernetesResource (deserializer will take care of the rest)
if (isObject(schema)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private void processTemplate(TemplateContext ret) {
.orElse("com.fasterxml.jackson.databind.JsonDeserializer.None.class"));
ret.put("package", ret.getPackageName());
if (settings.isGenerateJavadoc()) {
ret.put("hasDescription", !sanitizeDescription(ret.getClassSchema().getDescription()).isBlank());
ret.put("hasDescription", !sanitizeDescription(ret.getClassSchema().getDescription()).trim().isEmpty());
ret.put("description", sanitizeDescription(ret.getClassSchema().getDescription()));
}
ret.addImport("com.fasterxml.jackson.annotation.JsonInclude");
Expand Down Expand Up @@ -162,7 +162,7 @@ private List<Map<String, Object>> templateFields(TemplateContext templateContext
templateProp.put("required", true);
}
if (settings.isGenerateJavadoc()) {
templateProp.put("hasDescription", !sanitizeDescription(propertySchema.getDescription()).isBlank());
templateProp.put("hasDescription", !sanitizeDescription(propertySchema.getDescription()).trim().isEmpty());
templateProp.put("description", sanitizeDescription(propertySchema.getDescription()));
}
final String serializeUsing = serializerForSchema(propertySchema);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ApiVersionTest {
"group, v1, group/v1",
})
void toString(String group, String version, String expected) {
final var result = ApiVersion.builder().group(group).version(version).build()
final String result = ApiVersion.builder().group(group).version(version).build()
.toString();
assertEquals(expected, result);
}
Expand Down
Loading

0 comments on commit 26886fa

Please sign in to comment.