Skip to content

Commit d62dca1

Browse files
committed
feat: split extension into several steps
Reasoning is that it feels like it's needed to be able to register the ResourceController instances as beans that could then be registered with the Operator. Doesn't work. :(
1 parent 4db2a49 commit d62dca1

File tree

7 files changed

+106
-35
lines changed

7 files changed

+106
-35
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.javaoperatorsdk.quarkus.extension.deployment;
2+
3+
import io.javaoperatorsdk.quarkus.extension.QuarkusControllerConfiguration;
4+
import io.quarkus.builder.item.MultiBuildItem;
5+
6+
public final class ControllerConfigurationBuildItem extends MultiBuildItem {
7+
private final QuarkusControllerConfiguration configuration;
8+
9+
public ControllerConfigurationBuildItem(QuarkusControllerConfiguration configuration) {
10+
this.configuration = configuration;
11+
}
12+
13+
public QuarkusControllerConfiguration getConfiguration() {
14+
return configuration;
15+
}
16+
}

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

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.javaoperatorsdk.quarkus.extension.deployment;
22

33
import java.lang.reflect.Modifier;
4+
import java.util.List;
45
import java.util.Optional;
56
import java.util.function.Function;
67
import java.util.function.Supplier;
@@ -16,6 +17,8 @@
1617
import io.javaoperatorsdk.quarkus.extension.ConfigurationServiceRecorder;
1718
import io.javaoperatorsdk.quarkus.extension.QuarkusConfigurationService;
1819
import io.javaoperatorsdk.quarkus.extension.QuarkusControllerConfiguration;
20+
import io.javaoperatorsdk.quarkus.extension.QuarkusOperator;
21+
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
1922
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
2023
import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
2124
import io.quarkus.deployment.annotations.BuildProducer;
@@ -29,6 +32,7 @@
2932
import io.quarkus.gizmo.ClassOutput;
3033
import io.quarkus.gizmo.MethodCreator;
3134
import io.quarkus.gizmo.MethodDescriptor;
35+
import io.quarkus.kubernetes.client.spi.KubernetesClientBuildItem;
3236
import org.jboss.jandex.AnnotationInstance;
3337
import org.jboss.jandex.AnnotationValue;
3438
import org.jboss.jandex.ClassInfo;
@@ -51,24 +55,42 @@ FeatureBuildItem feature() {
5155

5256

5357
@BuildStep
54-
@Record(ExecutionTime.RUNTIME_INIT)
55-
void createDoneableClasses(CombinedIndexBuildItem combinedIndexBuildItem,
56-
BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer,
57-
BuildProducer<GeneratedClassBuildItem> generatedClass,
58-
ConfigurationServiceRecorder recorder) {
58+
List<ControllerConfigurationBuildItem> createControllerBeans(CombinedIndexBuildItem combinedIndexBuildItem,
59+
BuildProducer<GeneratedClassBuildItem> generatedClass,
60+
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
5961
final var index = combinedIndexBuildItem.getIndex();
6062
final var resourceControllers = index.getAllKnownImplementors(RESOURCE_CONTROLLER);
61-
final var controllerConfigs = resourceControllers.stream()
62-
.map(ci -> createControllerConfiguration(ci, new GeneratedClassGizmoAdaptor(generatedClass, true)))
63+
64+
final var classOutput = new GeneratedClassGizmoAdaptor(generatedClass, true);
65+
return resourceControllers.stream()
66+
.map(ci -> createControllerConfiguration(ci, classOutput, additionalBeans))
67+
.collect(Collectors.toList());
68+
}
69+
70+
71+
@BuildStep
72+
@Record(ExecutionTime.RUNTIME_INIT)
73+
void createConfigurationService(BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer,
74+
List<ControllerConfigurationBuildItem> configurations,
75+
KubernetesClientBuildItem clientBuildItem,
76+
ConfigurationServiceRecorder recorder) {
77+
final List<ControllerConfiguration> controllerConfigs = configurations.stream()
78+
.map(ControllerConfigurationBuildItem::getConfiguration)
6379
.collect(Collectors.toList());
80+
final var supplier = recorder.configurationServiceSupplier(controllerConfigs, clientBuildItem.getClient());
6481
syntheticBeanBuildItemBuildProducer.produce(SyntheticBeanBuildItem.configure(QuarkusConfigurationService.class)
6582
.scope(Singleton.class)
6683
.setRuntimeInit()
67-
.supplier(recorder.configurationServiceSupplier(controllerConfigs))
84+
.supplier(supplier)
6885
.done());
6986
}
7087

71-
private ControllerConfiguration createControllerConfiguration(ClassInfo info, ClassOutput classOutput) {
88+
@BuildStep
89+
void createOperator(BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
90+
additionalBeans.produce(AdditionalBeanBuildItem.unremovableOf(QuarkusOperator.class));
91+
}
92+
93+
private ControllerConfigurationBuildItem createControllerConfiguration(ClassInfo info, ClassOutput classOutput, BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
7294
// first retrieve the custom resource class
7395
final var rcInterface = info.interfaceTypes().stream()
7496
.filter(t -> t.name().equals(RESOURCE_CONTROLLER))
@@ -83,6 +105,9 @@ private ControllerConfiguration createControllerConfiguration(ClassInfo info, Cl
83105
throw new IllegalArgumentException("Couldn't find class " + crType);
84106
}
85107

108+
// create ResourceController bean
109+
additionalBeans.produce(AdditionalBeanBuildItem.unremovableOf(crType));
110+
86111
// generate associated Doneable class
87112
final var doneableClassName = crType + "Doneable";
88113
try (ClassCreator cc = ClassCreator.builder()
@@ -96,12 +121,10 @@ private ControllerConfiguration createControllerConfiguration(ClassInfo info, Cl
96121
ctor.invokeSpecialMethod(MethodDescriptor.ofConstructor(CustomResourceDoneable.class, crClass, Function.class), ctor.getThis(), ctor.getMethodParam(0), ctor.invokeStaticMethod(MethodDescriptor.ofMethod(Function.class, "identity", Function.class)));
97122
}
98123

99-
// get Controller annotation
124+
// generate configuration
100125
final var controllerAnnotation = info.classAnnotation(CONTROLLER);
101-
102-
103126
final var crdName = valueOrDefault(controllerAnnotation, "crdName", AnnotationValue::asString, EXCEPTION_SUPPLIER);
104-
return new QuarkusControllerConfiguration(
127+
final var configuration = new QuarkusControllerConfiguration(
105128
valueOrDefault(controllerAnnotation, "name", AnnotationValue::asString, () -> ControllerUtils.getDefaultResourceControllerName(info.simpleName())),
106129
crdName,
107130
valueOrDefault(controllerAnnotation, "finalizerName", AnnotationValue::asString, () -> ControllerUtils.getDefaultFinalizerName(crdName)),
@@ -112,8 +135,11 @@ private ControllerConfiguration createControllerConfiguration(ClassInfo info, Cl
112135
doneableClassName,
113136
null // todo: fix-me
114137
);
138+
139+
return new ControllerConfigurationBuildItem(configuration);
115140
}
116141

142+
117143
private <T> T valueOrDefault(AnnotationInstance annotation, String name, Function<AnnotationValue, T> converter, Supplier<T> defaultValue) {
118144
return Optional.ofNullable(annotation.value(name)).map(converter).orElseGet(defaultValue);
119145
}

quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/ConfigurationServiceRecorder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
import java.util.List;
44
import java.util.function.Supplier;
55

6+
import io.fabric8.kubernetes.client.KubernetesClient;
67
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
78
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
89
import io.quarkus.runtime.annotations.Recorder;
910

1011
@Recorder
1112
public class ConfigurationServiceRecorder {
1213

13-
public Supplier<ConfigurationService> configurationServiceSupplier(List<ControllerConfiguration> controllerConfigs) {
14-
return () -> new QuarkusConfigurationService(controllerConfigs);
14+
public Supplier<ConfigurationService> configurationServiceSupplier(List<ControllerConfiguration> controllerConfigs, KubernetesClient client) {
15+
return () -> new QuarkusConfigurationService(controllerConfigs, client);
1516
}
1617
}

quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusConfigurationService.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,19 @@
55
import java.util.Map;
66
import java.util.concurrent.ConcurrentHashMap;
77

8-
import javax.enterprise.inject.Produces;
9-
import javax.inject.Inject;
10-
import javax.inject.Singleton;
11-
128
import io.fabric8.kubernetes.client.Config;
139
import io.fabric8.kubernetes.client.CustomResource;
14-
import io.javaoperatorsdk.operator.Operator;
10+
import io.fabric8.kubernetes.client.KubernetesClient;
1511
import io.javaoperatorsdk.operator.api.ResourceController;
1612
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1713
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
18-
import io.quarkus.arc.DefaultBean;
1914

20-
@Singleton
21-
@DefaultBean
2215
public class QuarkusConfigurationService implements ConfigurationService {
23-
@Inject
24-
io.fabric8.kubernetes.client.KubernetesClient client;
25-
2616
private final Map<String, ControllerConfiguration> controllerConfigurations;
17+
private final KubernetesClient client;
2718

28-
public QuarkusConfigurationService(List<ControllerConfiguration> configurations) {
19+
public QuarkusConfigurationService(List<ControllerConfiguration> configurations, KubernetesClient client) {
20+
this.client = client;
2921
if (configurations != null && !configurations.isEmpty()) {
3022
controllerConfigurations = new ConcurrentHashMap<>(configurations.size());
3123
configurations.forEach(c -> controllerConfigurations.put(c.getName(), c));
@@ -43,11 +35,4 @@ public <R extends CustomResource> ControllerConfiguration<R> getConfigurationFor
4335
public Config getClientConfiguration() {
4436
return client.getConfiguration();
4537
}
46-
47-
@DefaultBean
48-
@Singleton
49-
@Produces
50-
public Operator operator() {
51-
return new Operator(client, this);
52-
}
5338
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public void setCrdName(String crdName) {
102102
}
103103

104104
// For serialization
105-
public void setFinalizer(String finalizer) {
105+
void setFinalizer(String finalizer) {
106106
this.finalizer = finalizer;
107107
}
108108

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.javaoperatorsdk.quarkus.extension;
2+
3+
import javax.enterprise.inject.Produces;
4+
import javax.inject.Inject;
5+
import javax.inject.Singleton;
6+
7+
import io.fabric8.kubernetes.client.KubernetesClient;
8+
import io.javaoperatorsdk.operator.Operator;
9+
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
10+
import io.quarkus.arc.DefaultBean;
11+
12+
@Singleton
13+
@DefaultBean
14+
public class QuarkusOperator {
15+
@Inject
16+
KubernetesClient k8sClient;
17+
18+
@Inject
19+
ConfigurationService configurationService;
20+
21+
private final Operator operator;
22+
23+
public QuarkusOperator() {
24+
operator = new Operator(k8sClient, configurationService);
25+
}
26+
27+
@Produces
28+
@DefaultBean
29+
@Singleton
30+
Operator operator() {
31+
return operator;
32+
}
33+
}

samples/quarkus/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import javax.inject.Inject;
44

5+
import io.fabric8.kubernetes.client.KubernetesClient;
56
import io.javaoperatorsdk.operator.Operator;
67
import io.quarkus.runtime.Quarkus;
78
import io.quarkus.runtime.QuarkusApplication;
@@ -10,16 +11,25 @@
1011
@QuarkusMain
1112
public class QuarkusOperator implements QuarkusApplication {
1213

14+
@Inject
15+
KubernetesClient client;
16+
1317
@Inject
1418
Operator operator;
1519

20+
/*@Inject
21+
ConfigurationService configuration;*/
22+
1623
public static void main(String... args) {
1724
Quarkus.run(QuarkusOperator.class, args);
1825
}
1926

2027
@Override
2128
public int run(String... args) throws Exception {
2229
System.out.println("operator = " + operator);
30+
/*final var config = configuration.getConfigurationFor(new CustomServiceController(client));
31+
System.out.println("CR class: " + config.getCustomResourceClass());
32+
System.out.println("Doneable class = " + config.getDoneableClass());*/
2333
Quarkus.waitForExit();
2434
return 0;
2535
}

0 commit comments

Comments
 (0)