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

Support for javaType and existingJavaType extensions in java-generator #5844

Merged
merged 2 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

#### Bugs
* Fix #5853: [java-generator] Gracefully handle colliding enum definitions
* Fix #5860: Corrections to java-generator gradle plugin extension

#### Improvements
* Fix #5843: Support existingJavaTypes extension in java-generator

#### Dependency Upgrade

Expand Down
16 changes: 13 additions & 3 deletions doc/java-generation-from-CRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,20 @@ Provide a `source` referencing a file or a folder containing your CRDs definitio
The full list of options of the CLI is (output of `--help`):

```
Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase]
Usage: java-gen [-hV] [-add-extra-annotations] [-always-preserve-unknown]
[-enum-uppercase]
[-deserialization-datetime-format=<deserializationDateTimeFormat
>] [-dt=<downloadTarget>] [-s=<source>]
[-serialization-datetime-format=<serializationDateTimeFormat>]
-t=<target> [-files-suffixes=<filesSuffixes>]...
-t=<target> [-existing-java-types=<String=String>]...
[-files-suffixes=<filesSuffixes>]...
[-package-overrides=<String=String>]... [-u=<urls>]...
-add-extra-annotations, --add-extra-annotations
Add extra lombok and sundrio annotation to the
generated classes
-always-preserve-unknown, --always-preserve-unknown
Always preserve unknown fields in the generated
classes
classes by emitting an additionalProperties field
-deserialization-datetime-format,
--deserialization-datetime-format=<deserializationDateTimeFormat>
DateTime format used for Deserialization of fields of
Expand All @@ -100,6 +102,9 @@ Usage: java-gen [-hV] [-add-extra-annotations] [-enum-uppercase]
crds
-enum-uppercase, --enum-uppercase
Uppercase the enum values
-existing-java-types, --existing-java-types=<String=String>
Mapping from fully qualified generated type to fully
qualified existing Java type
-files-suffixes, --files-suffixes=<filesSuffixes>
Filter the source files with the specific suffixes
-h, --help Show this help message and exit.
Expand Down Expand Up @@ -141,6 +146,11 @@ And the corresponding configurations of the Maven plugin are (output of `mvn hel
User property: fabric8.java-generator.enum-uppercase
Generate uppercase Enums

existingJavaTypes
User property: fabric8.java-generator.existing-java-types
Mapping from fully qualified generated type to fully qualified existing
Java type

extraAnnotations
User property: fabric8.java-generator.extra-annotations
Generate Extra annotation for lombok and sundrio integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public class GenerateJavaSources implements Runnable {
"--deserialization-datetime-format" }, description = "DateTime format used for Deserialization of fields of type `date-time`", required = false)
String deserializationDateTimeFormat = null;

@Option(names = { "-existing-java-types",
"--existing-java-types" }, description = "Mapping from fully qualified generated type to fully qualified existing Java type", required = false)
Map<String, String> existingJavaTypes = null;

@Override
public void run() {
final Boolean noGeneratedAnnotations = (skipGeneratedAnnotations != null) ? skipGeneratedAnnotations : false;
Expand All @@ -94,7 +98,8 @@ public void run() {
packageOverrides,
filesSuffixes,
serializationDateTimeFormat,
deserializationDateTimeFormat);
deserializationDateTimeFormat,
existingJavaTypes);

List<JavaGenerator> runners = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class Config {
// RFC 3339 - from: https://swagger.io/docs/specification/data-models/data-types/
public static final String DEFAULT_SER_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssVV";
public static final String DEFAULT_DESER_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss[XXX][VV]";
public static final Map<String, String> DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES = new HashMap<>();

private Boolean uppercaseEnums = DEFAULT_UPPERCASE_ENUM;
private Boolean objectExtraAnnotations = DEFAULT_ADD_EXTRA_ANNOTATIONS;
Expand All @@ -44,6 +45,7 @@ public class Config {
private List<String> filesSuffixes = DEFAULT_FILES_SUFFIXES;
private String serDatetimeFormat = DEFAULT_SER_DATETIME_FORMAT;
private String deserDatetimeFormat = DEFAULT_DESER_DATETIME_FORMAT;
private Map<String, String> existingJavaTypes = DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES;

public Config(
Boolean uppercaseEnums,
Expand All @@ -64,6 +66,7 @@ public Config(
}
}

@Deprecated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tnx 👍

public Config(
matteriben marked this conversation as resolved.
Show resolved Hide resolved
Boolean uppercaseEnums,
Boolean objectExtraAnnotations,
Expand All @@ -87,6 +90,7 @@ public Config(
}
}

@Deprecated
public Config(
Boolean uppercaseEnums,
Boolean objectExtraAnnotations,
Expand Down Expand Up @@ -126,7 +130,8 @@ public Config(
Map<String, String> packageOverrides,
List<String> filesSuffixes,
String serDatetimeFormat,
String deserDatetimeFormat) {
String deserDatetimeFormat,
Map<String, String> existingJavaTypes) {
if (uppercaseEnums != null) {
this.uppercaseEnums = uppercaseEnums;
}
Expand All @@ -151,6 +156,9 @@ public Config(
if (deserDatetimeFormat != null) {
this.deserDatetimeFormat = deserDatetimeFormat;
}
if (existingJavaTypes != null) {
this.existingJavaTypes = existingJavaTypes;
}
}

public boolean isUppercaseEnums() {
Expand Down Expand Up @@ -198,4 +206,10 @@ public String getDeserDatetimeFormat() {
? DEFAULT_DESER_DATETIME_FORMAT
: deserDatetimeFormat;
}

public Map<String, String> getExistingJavaTypes() {
return (existingJavaTypes == null || existingJavaTypes.isEmpty())
? DEFAULT_EXISTING_JAVA_TYPES_OVERRIDES
: existingJavaTypes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public JObject(

@Override
public String getType() {
return this.type;
return config.getExistingJavaTypes().getOrDefault(this.type, this.type);
}

private String getSortedFieldsAsParam(Set<String> list) {
Expand All @@ -153,6 +153,9 @@ private String getSortedFieldsAsParam(Set<String> list) {

@Override
public GeneratorResult generateJava() {
if (config.getExistingJavaTypes().containsKey(this.type)) {
return new GeneratorResult(Collections.emptyList());
}
CompilationUnit cu = new CompilationUnit();
if (!this.pkg.isEmpty()) {
cu.setPackageDeclaration(new PackageDeclaration(new Name(this.pkg)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.junit.jupiter.params.provider.MethodSource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Stream;
Expand All @@ -44,7 +45,10 @@ private static Stream<Arguments> getCRDGenerationInputData() {
Arguments.of("testJokeCrd", "jokerequests-crd.yml", "JokeRequest", "JokeRequestJavaCr", new Config()),
Arguments.of("testAkkaMicroservicesCrd", "akka-microservices-crd.yml", "AkkaMicroservice", "AkkaMicroserviceJavaCr",
new Config()),
Arguments.of("testCalicoIPPoolCrd", "calico-ippool-crd.yml", "IPPool", "CalicoIPPoolCr", new Config()));
Arguments.of("testCalicoIPPoolCrd", "calico-ippool-crd.yml", "IPPool", "CalicoIPPoolCr", new Config()),
Arguments.of("testExistingJavaType", "existing-java-type-crd.yml", "ExistingJavaType", "ExistingJavaTypeCr",
Config.builder().existingJavaTypes(Collections.singletonMap(
"org.test.v1.existingjavatypespec.Affinity", "io.fabric8.kubernetes.api.model.Affinity")).build()));
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ConfigTest {

@Test
void defaultValuesWithAllArgsConstructor() {
final Config result = new Config(null, null, null, null, null, null, null, null);
final Config result = new Config(null, null, null, null, null, null, null, null, null);
assertThat(result)
.returns(Config.DEFAULT_UPPERCASE_ENUM, Config::isUppercaseEnums)
.returns(Config.DEFAULT_ADD_EXTRA_ANNOTATIONS, Config::isObjectExtraAnnotations)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ void testObjectWithPreservedFields() {
@Test
void testConfigToGeneratePreservedUnknownFields() {
// Arrange
Config config = new Config(null, null, null, true, new HashMap<>(), new ArrayList<>(), null, null);
Config config = new Config(null, null, null, true, new HashMap<>(), new ArrayList<>(), null, null, null);
JObject obj = new JObject(
null,
"t",
Expand Down Expand Up @@ -982,4 +982,28 @@ void testExactlyDuplicatedFieldNotMarkedAsDeprecatedFailsWithException() {
},
"An exception is expected to be thrown when an object contains one duplicated field that is not marked as deprecated");
}

@Test
void testExistingJavaTypeObject() {
// Arrange
Config config = Config.builder()
.existingJavaTypes(Collections.singletonMap("v1alpha1.T", "org.test.ExistingJavaType")).build();
JObject obj = new JObject(
"v1alpha1",
"T",
null,
null,
false,
config,
null,
Boolean.FALSE,
null);

// Act
GeneratorResult res = obj.generateJava();

// Assert
assertEquals("org.test.ExistingJavaType", obj.getType());
assertEquals(0, res.getTopLevelClasses().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#
# Copyright (C) 2015 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: existing-java-type.example.com
spec:
scope: Namespaced
names:
plural: existingJavaTypes
kind: ExistingJavaType
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
affinity:
type: object
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ExistingJavaTypeCr[0] = package org.test.v1;

@io.fabric8.kubernetes.model.annotation.Version(value = "v1" , storage = true , served = true)
@io.fabric8.kubernetes.model.annotation.Group("example.com")
@io.fabric8.kubernetes.model.annotation.Plural("existingJavaTypes")
@javax.annotation.processing.Generated("io.fabric8.java.generator.CRGeneratorRunner")
public class ExistingJavaType extends io.fabric8.kubernetes.client.CustomResource<org.test.v1.ExistingJavaTypeSpec, java.lang.Void> implements io.fabric8.kubernetes.api.model.Namespaced {
}

ExistingJavaTypeCr[1] = package org.test.v1;

@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
@com.fasterxml.jackson.annotation.JsonPropertyOrder({"affinity"})
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class)
@javax.annotation.processing.Generated("io.fabric8.java.generator.CRGeneratorRunner")
public class ExistingJavaTypeSpec implements io.fabric8.kubernetes.api.model.KubernetesResource {

@com.fasterxml.jackson.annotation.JsonProperty("affinity")
@com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP)
private io.fabric8.kubernetes.api.model.Affinity affinity;

public io.fabric8.kubernetes.api.model.Affinity getAffinity() {
return affinity;
}

public void setAffinity(io.fabric8.kubernetes.api.model.Affinity affinity) {
this.affinity = affinity;
}
}

4 changes: 4 additions & 0 deletions java-generator/gradle-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Loading
Loading