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

feat(crd-generator): Add CRD-Generator Maven plugin #5979

Merged
merged 40 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f6040bd
feat(crd-generator): Add CRD-Generator Maven plugin
baloo42 Apr 25, 2024
4057f67
Add crd-generator-collector module
baloo42 May 3, 2024
d4b7f2a
Refactor crd-generator-maven-plugin to use collector module
baloo42 May 3, 2024
1dce59e
Adjusted log levels and allow to force create indices
baloo42 May 3, 2024
dbc1153
Enable parallel by default in crd-generator maven plugin
baloo42 May 3, 2024
f4a6028
Remove not necessary classes from base index
baloo42 May 3, 2024
d7be6a6
Cleanup
baloo42 May 3, 2024
ff1b97d
More cleanup
baloo42 May 3, 2024
a283857
Fix base index (must also include CustomResource)
baloo42 May 3, 2024
9ab5fac
Fix includes/excludes and some code smells
baloo42 May 4, 2024
9125a0a
Add CustomResourceCollector tests
baloo42 May 4, 2024
85fcc91
Cleanup, add tests and fix code smells
baloo42 May 7, 2024
f91de1c
Add tests for crd-generator-maven-plugin and fix code smells
baloo42 May 8, 2024
ef4fe25
Fix code smells
baloo42 May 8, 2024
9ed611c
Remove high level filtering and return an array of cr classes instead…
baloo42 May 8, 2024
b536658
Refactor Jandex utility methods to be more reusable
baloo42 May 9, 2024
b0eef86
Polish var names, add javadoc, improve error handling, refactor tests
baloo42 May 10, 2024
c47fe6d
Fix CrdGeneratorMojoTest
baloo42 May 12, 2024
c7d2ab9
Fix code smells
baloo42 May 12, 2024
9e85e4b
Try to fix tests
baloo42 May 12, 2024
e227f15
Use same jandex version for core module and maven plugin
baloo42 May 13, 2024
cc18c80
Add README for crd-generator maven plugin
baloo42 May 14, 2024
e1c768b
Fix README
baloo42 May 15, 2024
e8c881f
Add integration tests using maven-invoker plugin
baloo42 May 15, 2024
818d37f
Add more integration tests and verify content
baloo42 May 15, 2024
db4c6a2
Add integration tests for intermediate custom resource classes
baloo42 May 15, 2024
0fc55ed
Remove CrdGeneratorMojoTest - already covered by integration test
baloo42 May 15, 2024
fe68d5d
Fix ClasspathTypeTest
baloo42 May 15, 2024
0c6a349
Fix groovy files formatting
baloo42 May 16, 2024
25d34f0
Fix version after rebase
baloo42 May 30, 2024
b5ebcac
Reimplement integration tests to be OS independent
baloo42 May 30, 2024
82677b9
Add collection input methods to CRDGenerator
baloo42 May 31, 2024
f5dac69
Refactor CustomResourceCollector to use only a list as output
baloo42 May 31, 2024
9551136
Fix integration tests for Java 8
baloo42 Jul 2, 2024
bcf601d
Make file comparison in integration tests OS independent
baloo42 Jul 3, 2024
b1ce3de
Add groovy formatter settings to parent pom and remove crd-generator …
baloo42 Jul 3, 2024
02976f1
Make reset methods package-private
baloo42 Jul 3, 2024
f10f525
Add @SuppressWarnings("UnusedReturnValue") to get rid of all warnings
baloo42 Jul 3, 2024
b9a8534
Improve log message
baloo42 Jul 3, 2024
04228c9
Fix jandex version after rebase
baloo42 Aug 27, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -42,7 +43,6 @@
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CRDGenerator {

Expand Down Expand Up @@ -112,7 +112,27 @@ Map<String, AbstractCustomResourceHandler> getHandlers() {
// (we also cannot use @SafeVarargs, because that requires the method to be final, which is another signature change)
@SuppressWarnings("unchecked")
public final CRDGenerator customResourceClasses(Class<? extends HasMetadata>... crClasses) {
return customResources(Stream.of(crClasses).map(CustomResourceInfo::fromClass).toArray(CustomResourceInfo[]::new));
if (crClasses == null) {
return this;
}
return customResourceClasses(Arrays.asList(crClasses));
}

public CRDGenerator customResourceClasses(Collection<Class<? extends HasMetadata>> crClasses) {
if (crClasses == null) {
return this;
}
return customResources(crClasses.stream()
.filter(Objects::nonNull)
.map(CustomResourceInfo::fromClass)
.toArray(CustomResourceInfo[]::new));
}

public CRDGenerator customResources(Collection<CustomResourceInfo> infos) {
if (infos == null) {
return this;
}
return customResources(infos.toArray(new CustomResourceInfo[0]));
}

public CRDGenerator customResources(CustomResourceInfo... infos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.fabric8.crdv2.example.nocyclic.NoCyclic;
import io.fabric8.crdv2.example.simplest.Simplest;
import io.fabric8.crdv2.generator.CRDGenerator.AbstractCRDOutput;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceColumnDefinition;
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionNames;
Expand All @@ -51,6 +52,7 @@
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -109,12 +111,27 @@ void addingCustomResourceInfosShouldWork() {
generator.customResources();
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResources(null);
generator.customResources((CustomResourceInfo[]) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResources((CustomResourceInfo) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResources((Collection<CustomResourceInfo>) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResources(null, null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResourceClasses((Class<? extends HasMetadata>[]) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResourceClasses((Class<? extends HasMetadata>) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResourceClasses((Collection<Class<? extends HasMetadata>>) null);
assertTrue(generator.getCustomResourceInfos().isEmpty());

generator.customResourceClasses(Simplest.class);
assertEquals(1, generator.getCustomResourceInfos().size());
assertTrue(generator.getCustomResourceInfos().stream().allMatch(cri -> cri.crClassName().equals(Simplest.class.getName())));
Expand Down
66 changes: 66 additions & 0 deletions crd-generator/collector/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>crd-generator-parent</artifactId>
<groupId>io.fabric8</groupId>
<version>7.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>crd-generator-collector</artifactId>
<name>Fabric8 :: CRD generator :: Collector</name>

<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>crd-generator-api-v2</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>jandex</artifactId>
</dependency>

<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* 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.
*/
package io.fabric8.crd.generator.collector;

import io.fabric8.kubernetes.api.model.HasMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
* Allows to build a class loader to load Custom Resource classes.
* The actual class loader is built lazy and is cached once used.
*/
class CustomResourceClassLoader {

private static final Logger log = LoggerFactory.getLogger(CustomResourceClassLoader.class);

private final Set<String> classpathElements = new LinkedHashSet<>();

private ClassLoader parentClassLoader;

private ClassLoader cachedClassLoader;

@SuppressWarnings("UnusedReturnValue")
public CustomResourceClassLoader withParentClassLoader(ClassLoader parentClassLoader) {
this.parentClassLoader = parentClassLoader;
return this;
}

@SuppressWarnings("UnusedReturnValue")
public CustomResourceClassLoader withClasspathElement(String... classpathElements) {
if (classpathElements != null) {
withClasspathElements(Arrays.asList(classpathElements));
}
return this;
}

@SuppressWarnings("UnusedReturnValue")
public CustomResourceClassLoader withClasspathElements(Collection<String> classpathElements) {
if (classpathElements != null) {
classpathElements.stream()
.filter(Objects::nonNull)
.forEach(this.classpathElements::add);
}
return this;
}

/**
* Load a Custom Resource class by its name and the previously configured class loader.
*
* @param className the class name of the Custom Resource class
* @return the Custom Resource class
*/
public Class<? extends HasMetadata> loadCustomResourceClass(String className) {
Class<?> clazz = loadClass(className);
if (HasMetadata.class.isAssignableFrom(clazz)) {
return clazz.asSubclass(HasMetadata.class);
}
throw new CustomResourceClassLoaderException(
"Could not load Custom Resource. Class does not implement HasMetadata: " + className);
}

private Class<?> loadClass(String className) {
try {
return getClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
throw new CustomResourceClassLoaderException(e);
}
}

ClassLoader getClassLoader() {
if (cachedClassLoader == null) {
cachedClassLoader = createClassLoader();
}
return cachedClassLoader;
}

private ClassLoader createClassLoader() {
if (!classpathElements.isEmpty()) {
URL[] urls = classpathElements.stream()
.map(s -> {
try {
return new File(s).toURI().toURL();
} catch (MalformedURLException e) {
throw new CustomResourceClassLoaderException("Could not transform file to URL: " + s, e);
}
}).toArray(URL[]::new);
String urlsAsString = Arrays.toString(urls);
if (parentClassLoader != null) {
log.trace("Using URLClassLoader with parent ClassLoader {} and {}", parentClassLoader, urlsAsString);
return new URLClassLoader(urls, parentClassLoader);
} else {
log.trace("Using URLClassLoader with {}", urlsAsString);
return new URLClassLoader(urls);
}
} else {
if (parentClassLoader != null) {
log.trace("Using given ClassLoader {}", parentClassLoader);
return parentClassLoader;
} else {
log.trace("Using default ClassLoader");
return getDefaultClassLoader();
}
}
}

private ClassLoader getDefaultClassLoader() {
return Thread.currentThread().getContextClassLoader();
}

void reset() {
classpathElements.clear();
parentClassLoader = null;
cachedClassLoader = null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.
*/
package io.fabric8.crd.generator.collector;

public class CustomResourceClassLoaderException extends RuntimeException {

public CustomResourceClassLoaderException(String message) {
super(message);
}

public CustomResourceClassLoaderException(String message, Throwable cause) {
super(message, cause);
}

public CustomResourceClassLoaderException(Throwable cause) {
super(cause);
}
}
Loading
Loading