Skip to content

Commit 9518285

Browse files
authored
Fix 1831 (#1863)
* fix issue Signed-off-by: wind57 <[email protected]> * refactor Signed-off-by: wind57 <[email protected]> * fix issue Signed-off-by: wind57 <[email protected]> * review comments Signed-off-by: wind57 <[email protected]> --------- Signed-off-by: wind57 <[email protected]>
1 parent b5c8a61 commit 9518285

File tree

5 files changed

+135
-11
lines changed

5 files changed

+135
-11
lines changed

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtils.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,11 @@ public static <T> void registerSingle(ConfigurableBootstrapContext bootstrapCont
339339
String name, ApplicationListener<?> listener) {
340340
bootstrapContext.registerIfAbsent(cls, BootstrapRegistry.InstanceSupplier.of(instance));
341341
bootstrapContext.addCloseListener(event -> {
342-
if (event.getApplicationContext().getBeanFactory().getSingleton(name) == null) {
343-
event.getApplicationContext()
344-
.getBeanFactory()
345-
.registerSingleton(name, event.getBootstrapContext().get(cls));
342+
343+
T singleton = event.getBootstrapContext().get(cls);
344+
345+
if (event.getApplicationContext().getBeanFactory().getSingleton(name) == null && singleton != null) {
346+
event.getApplicationContext().getBeanFactory().registerSingleton(name, singleton);
346347
event.getApplicationContext().addApplicationListener(listener);
347348
}
348349
});

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/KubernetesConfigDataLocationResolver.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
public abstract class KubernetesConfigDataLocationResolver
5353
implements ConfigDataLocationResolver<KubernetesConfigDataResource>, Ordered {
5454

55+
private static final Class<KubernetesClientProperties> PROPERTIES_CLASS = KubernetesClientProperties.class;
56+
5557
private static final boolean RETRY_IS_PRESENT = isPresent("org.springframework.retry.annotation.Retryable", null);
5658

5759
private final Log log;
@@ -139,8 +141,7 @@ private void registerProperties(ConfigDataLocationResolverContext resolverContex
139141
SecretsConfigProperties secretsProperties) {
140142

141143
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
142-
registerSingle(bootstrapContext, KubernetesClientProperties.class, clientProperties,
143-
"configDataKubernetesClientProperties");
144+
registerSingle(bootstrapContext, PROPERTIES_CLASS, clientProperties, "configDataKubernetesClientProperties");
144145

145146
if (configMapProperties != null) {
146147
registerSingle(bootstrapContext, ConfigMapConfigProperties.class, configMapProperties,
@@ -174,15 +175,14 @@ private static PropertyHolder of(ConfigDataLocationResolverContext context) {
174175
private static KubernetesClientProperties clientProperties(ConfigDataLocationResolverContext context,
175176
String namespace) {
176177
KubernetesClientProperties kubernetesClientProperties;
178+
ConfigurableBootstrapContext bootstrapContext = context.getBootstrapContext();
177179

178-
if (context.getBootstrapContext().isRegistered(KubernetesClientProperties.class)) {
179-
kubernetesClientProperties = context.getBootstrapContext()
180-
.get(KubernetesClientProperties.class)
181-
.withNamespace(namespace);
180+
if (bootstrapContext.isRegistered(PROPERTIES_CLASS) && bootstrapContext.get(PROPERTIES_CLASS) != null) {
181+
kubernetesClientProperties = bootstrapContext.get(PROPERTIES_CLASS).withNamespace(namespace);
182182
}
183183
else {
184184
kubernetesClientProperties = context.getBinder()
185-
.bindOrCreate(KubernetesClientProperties.PREFIX, Bindable.of(KubernetesClientProperties.class))
185+
.bindOrCreate(KubernetesClientProperties.PREFIX, Bindable.of(PROPERTIES_CLASS))
186186
.withNamespace(namespace);
187187
}
188188

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.kubernetes;
18+
19+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20+
import org.springframework.boot.context.config.ConfigDataLocation;
21+
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
22+
import org.springframework.boot.context.config.Profiles;
23+
import org.springframework.boot.logging.DeferredLogFactory;
24+
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
25+
import org.springframework.cloud.kubernetes.commons.config.KubernetesConfigDataLocationResolver;
26+
27+
/**
28+
* @author wind57
29+
*/
30+
@ConditionalOnProperty(value = "dummy.config.loader.enabled", havingValue = "true", matchIfMissing = false)
31+
class DummyConfigDataLocationResolver extends KubernetesConfigDataLocationResolver {
32+
33+
DummyConfigDataLocationResolver(DeferredLogFactory factory) {
34+
super(factory);
35+
}
36+
37+
@Override
38+
protected void registerBeans(ConfigDataLocationResolverContext resolverContext, ConfigDataLocation location,
39+
Profiles profiles, PropertyHolder propertyHolder, KubernetesNamespaceProvider namespaceProvider) {
40+
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.kubernetes.fabric8.discovery;
18+
19+
import com.github.tomakehurst.wiremock.WireMockServer;
20+
import com.github.tomakehurst.wiremock.client.WireMock;
21+
import org.assertj.core.api.Assertions;
22+
import org.junit.jupiter.api.AfterAll;
23+
import org.junit.jupiter.api.BeforeAll;
24+
import org.junit.jupiter.api.Test;
25+
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.boot.autoconfigure.SpringBootApplication;
28+
import org.springframework.boot.test.context.SpringBootTest;
29+
import org.springframework.context.ApplicationContext;
30+
31+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
32+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
33+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
34+
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
35+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
36+
37+
/**
38+
* Test that proves that this
39+
* <a href="https://github.com/spring-cloud/spring-cloud-kubernetes/issues/1831">issue</a>
40+
* is fixed.
41+
*
42+
* @author wind57
43+
*/
44+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
45+
properties = { "spring.main.cloud-platform=KUBERNETES",
46+
"spring.config.import=kubernetes:, optional:configserver:", "dummy.config.loader.enabled=true" })
47+
class Fabric8ConfigServerTest {
48+
49+
private static WireMockServer wireMockServer;
50+
51+
@Autowired
52+
private ApplicationContext applicationContext;
53+
54+
@BeforeAll
55+
static void beforeAll() {
56+
wireMockServer = new WireMockServer(options().port(8888));
57+
wireMockServer.start();
58+
WireMock.configureFor("localhost", wireMockServer.port());
59+
}
60+
61+
@AfterAll
62+
static void after() {
63+
WireMock.shutdownServer();
64+
wireMockServer.stop();
65+
}
66+
67+
@Test
68+
void test() {
69+
stubFor(get(urlEqualTo("/application/default")).willReturn(aResponse().withStatus(200).withBody("{}")));
70+
Assertions.assertThat(applicationContext).isNotNull();
71+
}
72+
73+
@SpringBootApplication
74+
protected static class TestConfig {
75+
76+
}
77+
78+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
org.springframework.boot.context.config.ConfigDataLocationResolver=\
2+
org.springframework.cloud.kubernetes.DummyConfigDataLocationResolver

0 commit comments

Comments
 (0)