Skip to content

Commit a89a718

Browse files
authored
Merge pull request #297 from java-operator-sdk/native-compilation
Native compilation improvements
2 parents be02fbc + f124dda commit a89a718

File tree

5 files changed

+145
-8
lines changed

5 files changed

+145
-8
lines changed

operator-framework-quarkus-extension/deployment/src/main/java/io/javaoperatorsdk/quarkus/extension/deployment/QuarkusExtensionProcessor.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
import io.quarkus.deployment.builditem.FeatureBuildItem;
2323
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
2424
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
25+
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
2526
import io.quarkus.gizmo.ClassCreator;
2627
import io.quarkus.gizmo.ClassOutput;
2728
import io.quarkus.gizmo.MethodCreator;
2829
import io.quarkus.gizmo.MethodDescriptor;
29-
import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem;
3030
import java.lang.reflect.Modifier;
3131
import java.util.List;
3232
import java.util.Optional;
@@ -63,21 +63,24 @@ void indexSDKDependencies(BuildProducer<IndexDependencyBuildItem> indexDependenc
6363
}
6464

6565
@BuildStep
66-
@Record(ExecutionTime.RUNTIME_INIT)
66+
@Record(ExecutionTime.STATIC_INIT)
6767
void createConfigurationServiceAndOperator(
6868
CombinedIndexBuildItem combinedIndexBuildItem,
6969
BuildProducer<GeneratedClassBuildItem> generatedClass,
7070
BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer,
7171
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
72-
KubernetesClientBuildItem clientBuildItem,
72+
BuildProducer<ReflectiveClassBuildItem> reflectionClasses,
7373
ConfigurationServiceRecorder recorder) {
7474
final var index = combinedIndexBuildItem.getIndex();
7575
final var resourceControllers = index.getAllKnownImplementors(RESOURCE_CONTROLLER);
7676

7777
final var classOutput = new GeneratedClassGizmoAdaptor(generatedClass, true);
7878
final List<ControllerConfiguration> controllerConfigs =
7979
resourceControllers.stream()
80-
.map(ci -> createControllerConfiguration(ci, classOutput, additionalBeans))
80+
.map(
81+
ci ->
82+
createControllerConfiguration(
83+
ci, classOutput, additionalBeans, reflectionClasses))
8184
.collect(Collectors.toList());
8285

8386
final var supplier = recorder.configurationServiceSupplier(controllerConfigs);
@@ -95,7 +98,8 @@ void createConfigurationServiceAndOperator(
9598
private ControllerConfiguration createControllerConfiguration(
9699
ClassInfo info,
97100
ClassOutput classOutput,
98-
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
101+
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
102+
BuildProducer<ReflectiveClassBuildItem> reflectionClasses) {
99103
// first retrieve the custom resource class
100104
final var rcInterface =
101105
info.interfaceTypes().stream()
@@ -147,9 +151,18 @@ private ControllerConfiguration createControllerConfiguration(
147151
+ Controller.class.getCanonicalName()
148152
+ " annotation");
149153
}
154+
155+
// load CR class
156+
final Class<CustomResource> crClass = (Class<CustomResource>) loadClass(crType);
157+
158+
// register CR class for introspection
159+
reflectionClasses.produce(new ReflectiveClassBuildItem(true, true, crClass));
160+
150161
final var crdName =
151162
valueOrDefault(
152163
controllerAnnotation, "crdName", AnnotationValue::asString, EXCEPTION_SUPPLIER);
164+
165+
// create the configuration
153166
final var configuration =
154167
new QuarkusControllerConfiguration(
155168
resourceControllerClassName,
@@ -193,4 +206,12 @@ private <T> T valueOrDefault(
193206
Supplier<T> defaultValue) {
194207
return Optional.ofNullable(annotation.value(name)).map(converter).orElseGet(defaultValue);
195208
}
209+
210+
private Class<?> loadClass(String className) {
211+
try {
212+
return Thread.currentThread().getContextClassLoader().loadClass(className);
213+
} catch (ClassNotFoundException e) {
214+
throw new IllegalArgumentException("Couldn't find class " + className);
215+
}
216+
}
196217
}

operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusControllerConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ public static Set<String> asSet(String[] namespaces) {
5656
: Set.of(namespaces);
5757
}
5858

59+
// Needed for Quarkus to find the associated constructor parameter
5960
public String getCrdName() {
6061
return getCRDName();
6162
}
6263

64+
// Needed for Quarkus to find the associated constructor parameter
6365
public String getCrClass() {
6466
return crClass;
6567
}
6668

69+
// Needed for Quarkus to find the associated constructor parameter
6770
public String getDoneableClassName() {
6871
return doneableClassName;
6972
}

operator-framework-quarkus-extension/tests/pom.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
<artifactId>quarkus-junit5-internal</artifactId>
3434
<scope>test</scope>
3535
</dependency>
36+
<dependency>
37+
<groupId>io.quarkus</groupId>
38+
<artifactId>quarkus-junit5</artifactId>
39+
<scope>test</scope>
40+
</dependency>
3641
<dependency>
3742
<groupId>io.rest-assured</groupId>
3843
<artifactId>rest-assured</artifactId>
@@ -70,6 +75,9 @@
7075
<groupId>org.apache.maven.plugins</groupId>
7176
<artifactId>maven-surefire-plugin</artifactId>
7277
<configuration>
78+
<excludes>
79+
<exclude>**/Native*.java</exclude>
80+
</excludes>
7381
<systemPropertyVariables>
7482
<java.util.logging.manager>
7583
org.jboss.logmanager.LogManager
@@ -80,4 +88,44 @@
8088
</plugin>
8189
</plugins>
8290
</build>
91+
92+
93+
<profiles>
94+
<profile>
95+
<id>native</id>
96+
<properties>
97+
<quarkus.package.type>native</quarkus.package.type>
98+
</properties>
99+
<build>
100+
<plugins>
101+
<plugin>
102+
<groupId>org.apache.maven.plugins</groupId>
103+
<artifactId>maven-failsafe-plugin</artifactId>
104+
<version>${maven.surefire.version}</version>
105+
<executions>
106+
<execution>
107+
<goals>
108+
<goal>integration-test</goal>
109+
<goal>verify</goal>
110+
</goals>
111+
<configuration>
112+
<systemPropertyVariables>
113+
<native.image.path>
114+
${project.build.directory}/${project.build.finalName}-runner
115+
</native.image.path>
116+
<java.util.logging.manager>
117+
org.jboss.logmanager.LogManager
118+
</java.util.logging.manager>
119+
<maven.home>${maven.home}</maven.home>
120+
</systemPropertyVariables>
121+
</configuration>
122+
</execution>
123+
</executions>
124+
</plugin>
125+
</plugins>
126+
</build>
127+
</profile>
128+
</profiles>
129+
130+
83131
</project>

operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package io.javaoperatorsdk.quarkus.it;
22

3+
import com.fasterxml.jackson.annotation.JsonProperty;
34
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
45
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
6+
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;
7+
import java.util.Set;
58
import javax.inject.Inject;
69
import javax.ws.rs.GET;
710
import javax.ws.rs.Path;
@@ -22,8 +25,64 @@ public boolean getController(@PathParam("name") String name) {
2225

2326
@GET
2427
@Path("{name}/config")
25-
public ControllerConfiguration getConfig(@PathParam("name") String name) {
26-
final var config = configurationService.getConfigurationFor(controller);
27-
return name.equals(config.getName()) ? config : null;
28+
public JSONControllerConfiguration getConfig(@PathParam("name") String name) {
29+
var config = configurationService.getConfigurationFor(controller);
30+
if (config == null) {
31+
return null;
32+
}
33+
return name.equals(config.getName()) ? new JSONControllerConfiguration(config) : null;
34+
}
35+
36+
static class JSONControllerConfiguration {
37+
private final ControllerConfiguration conf;
38+
39+
public JSONControllerConfiguration(ControllerConfiguration conf) {
40+
this.conf = conf;
41+
}
42+
43+
public String getName() {
44+
return conf.getName();
45+
}
46+
47+
@JsonProperty("crdName")
48+
public String getCRDName() {
49+
return conf.getCRDName();
50+
}
51+
52+
public String getFinalizer() {
53+
return conf.getFinalizer();
54+
}
55+
56+
public boolean isGenerationAware() {
57+
return conf.isGenerationAware();
58+
}
59+
60+
public String getCustomResourceClass() {
61+
return conf.getCustomResourceClass().getCanonicalName();
62+
}
63+
64+
public String getAssociatedControllerClassName() {
65+
return conf.getAssociatedControllerClassName();
66+
}
67+
68+
public String getDoneableClass() {
69+
return conf.getDoneableClass().getCanonicalName();
70+
}
71+
72+
public boolean isClusterScoped() {
73+
return conf.isClusterScoped();
74+
}
75+
76+
public Set<String> getNamespaces() {
77+
return conf.getNamespaces();
78+
}
79+
80+
public boolean watchAllNamespaces() {
81+
return conf.watchAllNamespaces();
82+
}
83+
84+
public RetryConfiguration getRetryConfiguration() {
85+
return conf.getRetryConfiguration();
86+
}
2887
}
2988
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package io.javaoperatorsdk.quarkus.it;
2+
3+
import io.quarkus.test.junit.NativeImageTest;
4+
5+
@NativeImageTest
6+
public class NativeQuarkusExtensionProcessorIT extends QuarkusExtensionProcessorTest {}

0 commit comments

Comments
 (0)