Skip to content

Commit 2242bc1

Browse files
authored
Merge pull request #1532 from dsyer/informers
Ensure KubernetesInformerFactoryProcessor does not access any beans
2 parents a3f3eff + ce7bc1b commit 2242bc1

File tree

6 files changed

+91
-123
lines changed

6 files changed

+91
-123
lines changed

spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerConfigurer.java

Lines changed: 0 additions & 44 deletions
This file was deleted.

spring/src/main/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerFactoryProcessor.java

Lines changed: 81 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
package io.kubernetes.client.spring.extended.controller;
1414

15+
import io.kubernetes.client.common.KubernetesObject;
1516
import io.kubernetes.client.informer.SharedIndexInformer;
1617
import io.kubernetes.client.informer.SharedInformer;
1718
import io.kubernetes.client.informer.SharedInformerFactory;
@@ -20,18 +21,16 @@
2021
import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformer;
2122
import io.kubernetes.client.spring.extended.controller.annotation.KubernetesInformers;
2223
import io.kubernetes.client.util.generic.GenericKubernetesApi;
23-
import java.time.Duration;
24-
import org.slf4j.Logger;
25-
import org.slf4j.LoggerFactory;
2624
import org.springframework.beans.BeansException;
27-
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.beans.factory.BeanFactory;
2826
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
29-
import org.springframework.beans.factory.support.AbstractBeanDefinition;
27+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
3028
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
3129
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
3230
import org.springframework.beans.factory.support.RootBeanDefinition;
3331
import org.springframework.core.Ordered;
3432
import org.springframework.core.ResolvableType;
33+
import org.springframework.core.annotation.AnnotatedElementUtils;
3534

3635
/**
3736
* The type Kubernetes informer factory processor which basically does the following things:
@@ -44,73 +43,14 @@
4443
public class KubernetesInformerFactoryProcessor
4544
implements BeanDefinitionRegistryPostProcessor, Ordered {
4645

47-
private static final Logger log =
48-
LoggerFactory.getLogger(KubernetesInformerFactoryProcessor.class);
49-
5046
public static final int ORDER = 0;
5147

52-
private BeanDefinitionRegistry beanDefinitionRegistry;
53-
54-
private final ApiClient apiClient;
55-
private final SharedInformerFactory sharedInformerFactory;
56-
57-
@Autowired
58-
public KubernetesInformerFactoryProcessor(
59-
ApiClient apiClient, SharedInformerFactory sharedInformerFactory) {
60-
this.apiClient = apiClient;
61-
this.sharedInformerFactory = sharedInformerFactory;
62-
}
48+
private ConfigurableListableBeanFactory beanFactory;
6349

6450
@Override
6551
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
6652
throws BeansException {
67-
68-
this.apiClient.setHttpClient(
69-
this.apiClient.getHttpClient().newBuilder().readTimeout(Duration.ZERO).build());
70-
71-
KubernetesInformers kubernetesInformers =
72-
sharedInformerFactory.getClass().getAnnotation(KubernetesInformers.class);
73-
if (kubernetesInformers == null || kubernetesInformers.value().length == 0) {
74-
log.info("No informers registered in the sharedInformerFactory..");
75-
return;
76-
}
77-
for (KubernetesInformer kubernetesInformer : kubernetesInformers.value()) {
78-
final GenericKubernetesApi api =
79-
new GenericKubernetesApi(
80-
kubernetesInformer.apiTypeClass(),
81-
kubernetesInformer.apiListTypeClass(),
82-
kubernetesInformer.groupVersionResource().apiGroup(),
83-
kubernetesInformer.groupVersionResource().apiVersion(),
84-
kubernetesInformer.groupVersionResource().resourcePlural(),
85-
apiClient);
86-
SharedIndexInformer sharedIndexInformer =
87-
sharedInformerFactory.sharedIndexInformerFor(
88-
api,
89-
kubernetesInformer.apiTypeClass(),
90-
kubernetesInformer.resyncPeriodMillis(),
91-
kubernetesInformer.namespace());
92-
ResolvableType informerType =
93-
ResolvableType.forClassWithGenerics(
94-
SharedInformer.class, kubernetesInformer.apiTypeClass());
95-
RootBeanDefinition informerBean = new RootBeanDefinition();
96-
informerBean.setTargetType(informerType);
97-
informerBean.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
98-
informerBean.setAutowireCandidate(true);
99-
String informerBeanName = informerType.toString();
100-
this.beanDefinitionRegistry.registerBeanDefinition(informerBeanName, informerBean);
101-
beanFactory.registerSingleton(informerBeanName, sharedIndexInformer);
102-
103-
Lister lister = new Lister(sharedIndexInformer.getIndexer());
104-
ResolvableType listerType =
105-
ResolvableType.forClassWithGenerics(Lister.class, kubernetesInformer.apiTypeClass());
106-
RootBeanDefinition listerBean = new RootBeanDefinition();
107-
listerBean.setTargetType(listerType);
108-
listerBean.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
109-
listerBean.setAutowireCandidate(true);
110-
String listerBeanName = listerType.toString();
111-
this.beanDefinitionRegistry.registerBeanDefinition(listerBeanName, listerBean);
112-
beanFactory.registerSingleton(listerBeanName, lister);
113-
}
53+
this.beanFactory = beanFactory;
11454
}
11555

11656
@Override
@@ -121,6 +61,80 @@ public int getOrder() {
12161
@Override
12262
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
12363
throws BeansException {
124-
this.beanDefinitionRegistry = registry;
64+
if (!(registry instanceof BeanFactory)) {
65+
return;
66+
}
67+
for (String name : registry.getBeanDefinitionNames()) {
68+
Class<?> cls = ((BeanFactory) registry).getType(name);
69+
if (cls != null) {
70+
KubernetesInformers kubernetesInformers =
71+
AnnotatedElementUtils.getMergedAnnotation(cls, KubernetesInformers.class);
72+
if (kubernetesInformers != null && kubernetesInformers.value().length > 0) {
73+
for (KubernetesInformer kubernetesInformer : kubernetesInformers.value()) {
74+
registerInformer(registry, kubernetesInformer);
75+
registerLister(registry, kubernetesInformer);
76+
}
77+
}
78+
}
79+
}
80+
}
81+
82+
private void registerInformer(
83+
BeanDefinitionRegistry registry, KubernetesInformer kubernetesInformer) {
84+
RootBeanDefinition informerBean =
85+
(RootBeanDefinition)
86+
BeanDefinitionBuilder.rootBeanDefinition(SharedInformer.class).getBeanDefinition();
87+
informerBean.setInstanceSupplier(
88+
() -> informer(kubernetesInformer.apiTypeClass(), kubernetesInformer));
89+
ResolvableType informerType =
90+
ResolvableType.forClassWithGenerics(
91+
SharedIndexInformer.class, kubernetesInformer.apiTypeClass());
92+
informerBean.setTargetType(informerType);
93+
registry.registerBeanDefinition(
94+
getInformerBeanName(kubernetesInformer.apiTypeClass()), informerBean);
95+
}
96+
97+
private String getInformerBeanName(Class<?> type) {
98+
return type.getName() + "Informer";
99+
}
100+
101+
private void registerLister(
102+
BeanDefinitionRegistry registry, KubernetesInformer kubernetesInformer) {
103+
RootBeanDefinition listerBean =
104+
(RootBeanDefinition)
105+
BeanDefinitionBuilder.rootBeanDefinition(Lister.class).getBeanDefinition();
106+
listerBean.setInstanceSupplier(() -> lister(kubernetesInformer.apiTypeClass()));
107+
ResolvableType listerType =
108+
ResolvableType.forClassWithGenerics(Lister.class, kubernetesInformer.apiTypeClass());
109+
listerBean.setTargetType(listerType);
110+
registry.registerBeanDefinition(listerType.toString(), listerBean);
111+
}
112+
113+
@SuppressWarnings({"unchecked", "rawtypes"})
114+
private <T extends KubernetesObject> Lister<T> lister(Class<T> type) {
115+
SharedIndexInformer sharedInformer =
116+
this.beanFactory.getBean(getInformerBeanName(type), SharedIndexInformer.class);
117+
Lister<T> lister = new Lister<>(sharedInformer.getIndexer());
118+
return lister;
119+
}
120+
121+
@SuppressWarnings({"unchecked", "rawtypes"})
122+
private <T extends KubernetesObject> SharedInformer<T> informer(
123+
Class<T> type, KubernetesInformer kubernetesInformer) {
124+
ApiClient apiClient = this.beanFactory.getBean(ApiClient.class);
125+
SharedInformerFactory sharedInformerFactory =
126+
this.beanFactory.getBean(SharedInformerFactory.class);
127+
final GenericKubernetesApi api =
128+
new GenericKubernetesApi(
129+
kubernetesInformer.apiTypeClass(),
130+
kubernetesInformer.apiListTypeClass(),
131+
kubernetesInformer.groupVersionResource().apiGroup(),
132+
kubernetesInformer.groupVersionResource().apiVersion(),
133+
kubernetesInformer.groupVersionResource().resourcePlural(),
134+
apiClient);
135+
SharedIndexInformer<T> sharedIndexInformer =
136+
sharedInformerFactory.sharedIndexInformerFor(
137+
api, type, kubernetesInformer.resyncPeriodMillis(), kubernetesInformer.namespace());
138+
return sharedIndexInformer;
125139
}
126140
}

spring/src/main/java/io/kubernetes/client/spring/extended/controller/config/KubernetesInformerAutoConfiguration.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import io.kubernetes.client.informer.SharedInformerFactory;
1616
import io.kubernetes.client.openapi.ApiClient;
17-
import io.kubernetes.client.spring.extended.controller.KubernetesInformerConfigurer;
17+
import io.kubernetes.client.spring.extended.controller.KubernetesInformerFactoryProcessor;
1818
import io.kubernetes.client.util.ClientBuilder;
1919
import java.io.IOException;
2020
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -39,8 +39,7 @@ public SharedInformerFactory sharedInformerFactory() {
3939

4040
@Bean
4141
@ConditionalOnMissingBean
42-
public KubernetesInformerConfigurer kubernetesInformerConfigurer(
43-
ApiClient apiClient, SharedInformerFactory sharedInformerFactory) {
44-
return new KubernetesInformerConfigurer(apiClient, sharedInformerFactory);
42+
public static KubernetesInformerFactoryProcessor kubernetesInformerConfigurer() {
43+
return new KubernetesInformerFactoryProcessor();
4544
}
4645
}

spring/src/test/java/io/kubernetes/client/spring/extended/controller/KubernetesInformerCreatorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public ApiClient testingApiClient() {
6666
}
6767

6868
@Bean
69-
public SharedInformerFactory sharedInformerFactory() {
69+
public TestSharedInformerFactory testSharedInformerFactory() {
7070
return new TestSharedInformerFactory();
7171
}
7272

@@ -86,7 +86,7 @@ public SharedInformerFactory sharedInformerFactory() {
8686
apiVersion = "v1",
8787
resourcePlural = "configmaps")),
8888
})
89-
static class TestSharedInformerFactory extends SharedInformerFactory {}
89+
static class TestSharedInformerFactory {}
9090
}
9191

9292
@Autowired private SharedInformerFactory informerFactory;

spring/src/test/java/io/kubernetes/client/spring/extended/controller/KubernetesReconcilerCreatorTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ public ApiClient testingApiClient() {
7575
}
7676

7777
@Bean
78-
public SharedInformerFactory sharedInformerFactory() {
79-
return new KubernetesInformerCreatorTest.App.TestSharedInformerFactory();
78+
public TestSharedInformerFactory testSharedInformerFactory() {
79+
return new TestSharedInformerFactory();
8080
}
8181

8282
@KubernetesInformers({
@@ -94,7 +94,7 @@ public SharedInformerFactory sharedInformerFactory() {
9494
apiVersion = "v1",
9595
resourcePlural = "configmaps")),
9696
})
97-
static class TestSharedInformerFactory extends SharedInformerFactory {}
97+
static class TestSharedInformerFactory {}
9898

9999
@Bean
100100
public TestReconciler testReconciler() {

spring/src/test/java/io/kubernetes/client/spring/extended/controller/KubernetesReconcilerProcessorTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import io.kubernetes.client.extended.controller.reconciler.Request;
2020
import io.kubernetes.client.extended.controller.reconciler.Result;
2121
import io.kubernetes.client.informer.SharedInformer;
22-
import io.kubernetes.client.informer.SharedInformerFactory;
2322
import io.kubernetes.client.openapi.models.V1Pod;
2423
import io.kubernetes.client.openapi.models.V1PodList;
2524
import io.kubernetes.client.spring.extended.controller.annotation.GroupVersionResource;
@@ -49,7 +48,7 @@ KubernetesReconcilerProcessor reconcilerProcessorUnderTesting() {
4948
}
5049

5150
@Bean
52-
SharedInformerFactory sharedInformerFactory() {
51+
TestSharedInformerFactory testSharedInformerFactory() {
5352
return new TestSharedInformerFactory();
5453
}
5554

@@ -59,7 +58,7 @@ SharedInformerFactory sharedInformerFactory() {
5958
apiListTypeClass = V1PodList.class,
6059
groupVersionResource = @GroupVersionResource(resourcePlural = "pods"))
6160
})
62-
static class TestSharedInformerFactory extends SharedInformerFactory {}
61+
static class TestSharedInformerFactory {}
6362

6463
@Bean("testReconciler1")
6564
TestReconciler testReconciler1ToBeInjected() {

0 commit comments

Comments
 (0)