diff --git a/.settings.xml b/.settings.xml
index 6c355129..5e68d0e9 100644
--- a/.settings.xml
+++ b/.settings.xml
@@ -1,66 +1,68 @@
-
-
- repo.spring.io
- ${env.CI_DEPLOY_USERNAME}
- ${env.CI_DEPLOY_PASSWORD}
-
-
-
-
-
- spring
- true
-
-
- spring-snapshots
- Spring Snapshots
- http://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- http://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- http://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- http://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- http://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
+
+
+ repo.spring.io
+ ${env.CI_DEPLOY_USERNAME}
+ ${env.CI_DEPLOY_PASSWORD}
+
+
+
+
+
+ spring
+
+ true
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ http://repo.spring.io/libs-snapshot-local
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ http://repo.spring.io/libs-milestone-local
+
+ false
+
+
+
+ spring-releases
+ Spring Releases
+ http://repo.spring.io/release
+
+ false
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ http://repo.spring.io/libs-snapshot-local
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ http://repo.spring.io/libs-milestone-local
+
+ false
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index a79e8f16..27e2bfd6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
org.springframework.cloud
spring-cloud-build
- 1.3.3.BUILD-SNAPSHOT
+ 2.0.0.BUILD-SNAPSHOT
@@ -34,7 +34,7 @@
Spring Cloud Kubernetes
http://cloud.spring.io
- 2016
+ 2017
Pivotal Software, Inc.
@@ -59,17 +59,20 @@
- 1.2.3.RELEASE
- 1.3.2.RELEASE
- 1.2.2.RELEASE
+
+ 2.0.0.BUILD-SNAPSHOT
3.5
2.8.2
- 2.19.1
- 2.19.1
- 3.2.28
- 1.2
+ 2.18.1
+ 2.21.0
+ 3.5.37
+ 1.6
+ 2.4.12
+ 3.0.2
+ 1.1-groovy-2.4
@@ -77,18 +80,25 @@
spring-cloud-kubernetes-core
spring-cloud-kubernetes-config
spring-cloud-kubernetes-discovery
+ spring-cloud-starter-kubernetes
+ spring-cloud-starter-kubernetes-config
+ spring-cloud-kubernetes-examples
+
+
-
+
+
+ org.codehaus.groovy
+ groovy-all
+ ${groovy.version}
+
+
@@ -108,21 +118,23 @@
- org.springframework.cloud
- spring-cloud-netflix-dependencies
- ${spring-cloud-netflix.version}
- pom
- import
+ org.codehaus.groovy
+ groovy-all
+ ${groovy.version}
- org.springframework.cloud
- spring-cloud-sleuth-dependencies
- ${spring-cloud-sleuth.version}
- pom
- import
+ io.rest-assured
+ rest-assured
+ ${restassured.version}
+ test
+
+ org.spockframework
+ spock-spring
+ ${spock-spring.version}
+
@@ -147,7 +159,7 @@
compile
- testCompile
+ compileTests
diff --git a/spring-cloud-kubernetes-archaius/src/main/java/org/springframework/cloud/kubernetes/archaius/ArchaiusConfigMapSourceConfiguration.java b/spring-cloud-kubernetes-archaius/src/main/java/org/springframework/cloud/kubernetes/archaius/ArchaiusConfigMapSourceConfiguration.java
index b7b6651c..d29607b5 100644
--- a/spring-cloud-kubernetes-archaius/src/main/java/org/springframework/cloud/kubernetes/archaius/ArchaiusConfigMapSourceConfiguration.java
+++ b/spring-cloud-kubernetes-archaius/src/main/java/org/springframework/cloud/kubernetes/archaius/ArchaiusConfigMapSourceConfiguration.java
@@ -82,7 +82,7 @@ public class ArchaiusConfigMapSourceConfiguration implements InitializingBean, D
}
watch = StringUtils.isEmpty(namespace)
? client.configMaps().withName(name).watch(watcher)
- : client.configMaps().inNamespace(namespace).withName(namespace).watch(watcher);
+ : client.configMaps().inNamespace(namespace).withName(name).watch(watcher);
started.set(true);
}
diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml
index 34ce24a7..15be8504 100644
--- a/spring-cloud-kubernetes-config/pom.xml
+++ b/spring-cloud-kubernetes-config/pom.xml
@@ -17,6 +17,16 @@
io.fabric8
kubernetes-client
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
org.springframework.cloud
@@ -32,6 +42,11 @@
spring-boot-actuator
true
+
+ org.springframework.boot
+ spring-boot-actuator-autoconfigure
+ true
+
org.springframework.boot
spring-boot-autoconfigure
@@ -42,6 +57,11 @@
spring-cloud-context
+
+ org.springframework.security
+ spring-security-rsa
+
+
org.projectlombok
lombok
@@ -50,6 +70,24 @@
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.9.4
+ test
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.9.4
+ test
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.9.0
+ test
+
org.springframework.boot
spring-boot-starter-test
@@ -59,22 +97,62 @@
org.springframework.boot
spring-boot-starter-web
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
io.fabric8
kubernetes-client
test-jar
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
io.fabric8
mockwebserver
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
io.fabric8
kubernetes-server-mock
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
org.spockframework
diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java
index ff8f3138..f07f4ced 100644
--- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java
+++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java
@@ -31,7 +31,6 @@ import io.fabric8.kubernetes.client.KubernetesClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
-import org.springframework.boot.yaml.SpringProfileDocumentMatcher;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.StringUtils;
@@ -76,29 +75,41 @@ public class ConfigMapPropertySource extends KubernetesPropertySource {
: client.configMaps().inNamespace(namespace).withName(name).get();
if (map != null) {
- for (Map.Entry entry : map.getData().entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if (key.equals(APPLICATION_YAML) || key.equals(APPLICATION_YML)) {
- result.putAll(yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP).apply(value));
- } else if (key.equals(APPLICATION_PROPERTIES)) {
- result.putAll(KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP).apply(value));
- } else {
- result.put(key, value);
- }
- }
+ result.putAll(processAllEntries(map.getData(), profiles));
}
} catch (Exception e) {
LOG.warn("Can't read configMap with name: [" + name + "] in namespace:[" + namespace + "]. Ignoring", e);
}
}
- // read for secrets mount
- putPathConfig(result, config.getPaths());
-
+ Map configsFromPaths = new HashMap<>();
+ putPathConfig(configsFromPaths, config.getPaths());
+ result.putAll(processAllEntries(configsFromPaths, profiles));
return result;
}
+ private static Map processAllEntries(Map input,
+ String[] profiles) {
+ return input.entrySet().stream()
+ .map(e -> extractProperties(e.getKey(), e.getValue(), profiles))
+ .filter(m -> !m.isEmpty())
+ .flatMap(m -> m.entrySet().stream())
+ .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
+ }
+
+ private static Map extractProperties(String resourceName, String content, String[] profiles) {
+ Map result = new HashMap<>();
+
+ if (resourceName.equals(APPLICATION_YAML) || resourceName.equals(APPLICATION_YML)) {
+ result.putAll(yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP).apply(content));
+ } else if (resourceName.equals(APPLICATION_PROPERTIES)) {
+ result.putAll(KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP).apply(content));
+ } else {
+ result.put(resourceName, content);
+ }
+ return result;
+ }
+
private static Map asObjectMap(Map source) {
return source.entrySet()
.stream()
@@ -108,11 +119,6 @@ public class ConfigMapPropertySource extends KubernetesPropertySource {
private static Function yamlParserGenerator(final String[] profiles) {
return s -> {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
- if (profiles == null) {
- yamlFactory.setDocumentMatchers(new SpringProfileDocumentMatcher());
- } else {
- yamlFactory.setDocumentMatchers(new SpringProfileDocumentMatcher(profiles));
- }
yamlFactory.setResources(new ByteArrayResource(s.getBytes()));
return yamlFactory.getObject();
};
diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java
index 1a3e5fee..2258ba52 100644
--- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java
+++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration.java
@@ -17,6 +17,11 @@
package org.springframework.cloud.kubernetes.config.reload;
import io.fabric8.kubernetes.client.KubernetesClient;
+import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
+import org.springframework.boot.actuate.info.InfoEndpoint;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator;
@@ -39,7 +44,9 @@ import org.springframework.scheduling.annotation.EnableScheduling;
*/
@Configuration
@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
+@AutoConfigureAfter({InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, RefreshAutoConfiguration.class})
@EnableConfigurationProperties(ConfigReloadProperties.class)
+
public class ConfigReloadAutoConfiguration {
/**
diff --git a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy
index 547f7ee7..fbf99c18 100644
--- a/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy
+++ b/spring-cloud-kubernetes-config/src/test/groovy/org/springframework/cloud/kubernetes/config/CoreTest.groovy
@@ -21,7 +21,7 @@ import io.fabric8.kubernetes.api.model.SecretBuilder
import io.fabric8.kubernetes.api.model.ConfigMapBuilder
import io.fabric8.kubernetes.client.Config
import io.fabric8.kubernetes.client.KubernetesClient
-import io.fabric8.kubernetes.server.mock.KubernetesMockServer
+import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java
index 072e8671..21398d55 100644
--- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java
+++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsSpringBootTest.java
@@ -47,7 +47,8 @@ import static org.junit.Assert.assertEquals;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = App.class,
properties = { "spring.application.name=configmap-example",
- "spring.cloud.kubernetes.reload.enabled=false"})
+ "spring.cloud.kubernetes.reload.enabled=false"}
+ )
public class ConfigMapsSpringBootTest {
@ClassRule
diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java
index c14af6c5..4e00980e 100644
--- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java
+++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java
@@ -17,6 +17,7 @@
package org.springframework.cloud.kubernetes.config;
+import io.fabric8.kubernetes.client.utils.IOHelpers;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -88,8 +89,13 @@ public class ConfigMapsTest {
createConfigMapFile(apiPath, "api.url", "http://localhost/api");
createConfigMapFile(apiPath, "foo.bar", "42");
+ final Path filesPath = tmp.resolve("cm/files");
+
+ createConfigMapFile(filesPath, "application.yaml", readResourceFile("application.yaml"));
+ createConfigMapFile(filesPath, "application.properties", readResourceFile("application.properties"));
+
// parse ConfigMaps
- cmConfProperties.setPaths(Arrays.asList(dbPath.toString(), apiPath.toString()));
+ cmConfProperties.setPaths(Arrays.asList(dbPath.toString(), apiPath.toString(), filesPath.toString()));
ConfigMapPropertySource cmps = new ConfigMapPropertySource(client, "testapp", cmConfProperties);
// assert as expected
@@ -98,7 +104,26 @@ public class ConfigMapsTest {
assertEquals("http://localhost/api", cmps.getProperty("api.url"));
assertFalse(cmps.containsProperty("no.such.property"));
- FileSystemUtils.deleteRecursively(tmp.toFile());
+ assertEquals("a", cmps.getProperty("dummy.property.string1"));
+ assertEquals("1", cmps.getProperty("dummy.property.int1"));
+ assertEquals("true", cmps.getProperty("dummy.property.bool1"));
+
+ assertEquals("a", cmps.getProperty("dummy.property.string2"));
+ assertEquals("1", cmps.getProperty("dummy.property.int2"));
+ assertEquals("true", cmps.getProperty("dummy.property.bool2"));
+
+ FileSystemUtils.deleteRecursively(tmp.toFile());
+ }
+
+ private String readResourceFile(String file) {
+ String resource;
+ try {
+ resource = IOHelpers.readFully(getClass().getClassLoader().getResourceAsStream(file));
+ }
+ catch (IOException e) {
+ resource = "";
+ }
+ return resource;
}
private void createConfigMapFile(Path basePath, String key, String value) throws IOException {
diff --git a/spring-cloud-kubernetes-config/src/test/resources/application.properties b/spring-cloud-kubernetes-config/src/test/resources/application.properties
new file mode 100644
index 00000000..09cecf84
--- /dev/null
+++ b/spring-cloud-kubernetes-config/src/test/resources/application.properties
@@ -0,0 +1,3 @@
+dummy.property.string1=a
+dummy.property.int1=1
+dummy.property.bool1=true
\ No newline at end of file
diff --git a/spring-cloud-kubernetes-config/src/test/resources/application.yaml b/spring-cloud-kubernetes-config/src/test/resources/application.yaml
new file mode 100644
index 00000000..5a7a342c
--- /dev/null
+++ b/spring-cloud-kubernetes-config/src/test/resources/application.yaml
@@ -0,0 +1,5 @@
+dummy:
+ property:
+ string2: "a"
+ int2: 1
+ bool2: true
\ No newline at end of file
diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml
index a5e8086a..94bafd20 100644
--- a/spring-cloud-kubernetes-core/pom.xml
+++ b/spring-cloud-kubernetes-core/pom.xml
@@ -32,6 +32,16 @@
io.fabric8
kubernetes-client
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
org.springframework.boot
@@ -81,6 +91,16 @@
io.fabric8
mockwebserver
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
org.spockframework
diff --git a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java
index bae47bce..73fed416 100644
--- a/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java
+++ b/spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java
@@ -41,7 +41,7 @@ public class KubernetesAutoConfiguration {
@Bean
@ConditionalOnMissingBean(Config.class)
public Config kubernetesClientConfig(KubernetesClientProperties kubernetesClientProperties) {
- Config base = new Config();
+ Config base = Config.autoConfigure(null);
Config properties = new ConfigBuilder(base)
//Only set values that have been explicitly specified
.withMasterUrl(or(kubernetesClientProperties.getMasterUrl(), base.getMasterUrl()))
diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml
index 97ab8ea5..751dc34b 100644
--- a/spring-cloud-kubernetes-dependencies/pom.xml
+++ b/spring-cloud-kubernetes-dependencies/pom.xml
@@ -5,7 +5,7 @@
spring-cloud-dependencies-parent
org.springframework.cloud
- 1.3.3.BUILD-SNAPSHOT
+ 2.0.0.BUILD-SNAPSHOT
spring-cloud-kubernetes-dependencies
@@ -14,12 +14,10 @@
Spring Cloud Kubernetes :: Dependencies
Spring Cloud Kubernetes Dependencies
- 1.1.13.Final
- 1.3.2
- 2.4.1
- 0.0.13
- 3.0.2
- 1.0-groovy-2.3
+ 1.4.0.Final
+ 1.15.2
+ 3.1.8
+ 0.1.0
@@ -46,13 +44,13 @@
org.springframework.cloud
- spring-cloud-kubernetes-archaius
+ spring-cloud-kubernetes-discovery
${project.version}
-
+
-
- org.springframework.cloud
- spring-cloud-starter-kubernetes
- ${project.version}
-
-
-
- org.springframework.cloud
- spring-cloud-starter-kubernetes-config
- ${project.version}
-
-
org.springframework.cloud
spring-cloud-starter-kubernetes-netflix
@@ -104,6 +88,19 @@
org.springframework.cloud
spring-cloud-starter-kubernetes-all
${project.version}
+ -->
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes
+ ${project.version}
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes-config
+ ${project.version}
@@ -137,6 +134,16 @@
mockwebserver
${mockwebserver.version}
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
@@ -145,20 +152,19 @@
${kubernetes-client.version}
test-jar
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
-
- io.rest-assured
- rest-assured
- ${restassured.version}
- test
-
-
- org.spockframework
- spock-spring
- ${spock-spring.version}
-
diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml
index c2f2dd12..0819df40 100644
--- a/spring-cloud-kubernetes-discovery/pom.xml
+++ b/spring-cloud-kubernetes-discovery/pom.xml
@@ -44,12 +44,10 @@
org.springframework.cloud
spring-cloud-commons
- true
org.springframework.cloud
spring-cloud-context
- true
@@ -70,12 +68,32 @@
kubernetes-client
test-jar
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
io.fabric8
mockwebserver
test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java
index 812ce1dd..f0f334f7 100644
--- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java
@@ -16,83 +16,129 @@
package org.springframework.cloud.kubernetes.discovery;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import io.fabric8.kubernetes.api.model.EndpointAddress;
+import io.fabric8.kubernetes.api.model.EndpointSubset;
import io.fabric8.kubernetes.api.model.Endpoints;
+import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.utils.Utils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.util.Assert;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
public class KubernetesDiscoveryClient implements DiscoveryClient {
- private static final String HOSTNAME = "HOSTNAME";
+ private static final Log log = LogFactory.getLog(KubernetesDiscoveryClient.class);
+ private static final String HOSTNAME = "HOSTNAME";
- private KubernetesClient client;
- private KubernetesDiscoveryProperties properties;
+ private KubernetesClient client;
+ private KubernetesDiscoveryProperties properties;
- public KubernetesDiscoveryClient(KubernetesClient client, KubernetesDiscoveryProperties properties) {
- this.client = client;
- this.properties = properties;
- }
+ public KubernetesDiscoveryClient(KubernetesClient client,
+ KubernetesDiscoveryProperties kubernetesDiscoveryProperties) {
+ this.client = client;
+ this.properties = properties;
+ }
- public KubernetesClient getClient() {
- return client;
- }
+ public KubernetesClient getClient() {
+ return client;
+ }
- public void setClient(KubernetesClient client) {
- this.client = client;
- }
+ public void setClient(KubernetesClient client) {
+ this.client = client;
+ }
- @Override
- public String description() {
- return "Kubernetes Discovery Client";
- }
+ @Override
+ public String description() {
+ return "Kubernetes Discovery Client";
+ }
- @Override
- public ServiceInstance getLocalServiceInstance() {
- String serviceName = properties.getServiceName();
- String podName = System.getenv(HOSTNAME);
- ServiceInstance defaultInstance = new DefaultServiceInstance(serviceName, "localhost", 8080, false);
+ public ServiceInstance getLocalServiceInstance() {
+ String serviceName = properties.getServiceName();
+ String podName = System.getenv(HOSTNAME);
+ ServiceInstance defaultInstance = new DefaultServiceInstance(serviceName,
+ "localhost",
+ 8080,
+ false);
- Endpoints endpoints = client.endpoints().withName(serviceName).get();
- if (Utils.isNullOrEmpty(podName) || endpoints == null) {
- return defaultInstance;
- }
- try {
- return endpoints.getSubsets()
- .stream()
- .filter(s -> s.getAddresses().get(0).getTargetRef().getName().equals(podName))
- .map(s -> (ServiceInstance) new KubernetesServiceInstance(serviceName,
- s.getAddresses().stream().findFirst().orElseThrow(IllegalStateException::new),
- s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new),
- false))
- .findFirst().orElse(defaultInstance);
- } catch (Throwable t) {
- return defaultInstance;
- }
- }
+ Endpoints endpoints = client.endpoints().withName(serviceName).get();
+ Optional service = Optional.ofNullable(client.services().withName(serviceName).get());
+ final Map labels;
+ if (service.isPresent()) {
+ labels = service.get().getMetadata().getLabels();
+ } else {
+ labels = null;
+ }
+ if (Utils.isNullOrEmpty(podName) || endpoints == null) {
+ return defaultInstance;
+ }
+ try {
+ List subsets = endpoints.getSubsets();
- @Override
- public List getInstances(String serviceId) {
- Assert.notNull(serviceId, "[Assertion failed] - the object argument must be null");
- return Optional.ofNullable(client.endpoints().withName(serviceId).get()).orElse(new Endpoints())
- .getSubsets()
- .stream()
- .flatMap(s -> s.getAddresses().stream().map(a -> (ServiceInstance) new KubernetesServiceInstance(serviceId, a ,s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new), false)))
- .collect(Collectors.toList());
+ if (subsets != null) {
+ for (EndpointSubset s : subsets) {
+ List addresses = s.getAddresses();
+ for (EndpointAddress a : addresses) {
+ return new KubernetesServiceInstance(serviceName,
+ a,
+ s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new),
+ labels,
+ false);
+ }
+ }
+ }
+ return defaultInstance;
- }
+ } catch (Throwable t) {
+ return defaultInstance;
+ }
+ }
- @Override
- public List getServices() {
- return client.services().list()
- .getItems()
- .stream().map(s -> s.getMetadata().getName())
- .collect(Collectors.toList());
- }
+ @Override
+ public List getInstances(String serviceId) {
+ Assert.notNull(serviceId,
+ "[Assertion failed] - the object argument must be null");
+ Optional service = Optional.ofNullable(client.services().withName(serviceId).get());
+ final Map labels;
+ if (service.isPresent()) {
+ labels = service.get().getMetadata().getLabels();
+ } else {
+ labels = null;
+ }
+
+ Optional endpoints = Optional.ofNullable(client.endpoints().withName(serviceId).get());
+ List subsets = endpoints.get().getSubsets();
+ List instances = new ArrayList<>();
+ if (subsets != null) {
+ for (EndpointSubset s : subsets) {
+ List addresses = s.getAddresses();
+ for (EndpointAddress a : addresses) {
+ instances.add(new KubernetesServiceInstance(serviceId,
+ a,
+ s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new),
+ labels,
+ false));
+ }
+ }
+ }
+
+ return instances;
+ }
+
+ @Override
+ public List getServices() {
+ return client.services().list()
+ .getItems()
+ .stream().map(s -> s.getMetadata().getName())
+ .collect(Collectors.toList());
+ }
}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java
new file mode 100644
index 00000000..7295daeb
--- /dev/null
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java
@@ -0,0 +1,45 @@
+package org.springframework.cloud.kubernetes.discovery;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.kubernetes.registry.KubernetesRegistration;
+import org.springframework.cloud.kubernetes.registry.KubernetesServiceRegistry;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+@Configuration
+public class KubernetesDiscoveryClientAutoConfiguration {
+
+ @Bean
+ public DiscoveryClient discoveryClient(KubernetesClient client,
+ KubernetesDiscoveryProperties properties) {
+ return new KubernetesDiscoveryClient(client, properties);
+ }
+
+ @Bean
+ public KubernetesServiceRegistry getServiceRegistry() {
+ return new KubernetesServiceRegistry();
+ }
+
+ @Bean
+ public KubernetesRegistration getRegistration(KubernetesClient client,
+ KubernetesDiscoveryProperties properties) {
+ return new KubernetesRegistration(client, properties);
+ }
+
+ @Bean
+ @Primary
+ public KubernetesDiscoveryProperties getKubernetesDiscoveryProperties() {
+ return new KubernetesDiscoveryProperties();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ @ConditionalOnProperty(name = "spring.cloud.kubernetes.discovery.catalog-services-watch.enabled", matchIfMissing = true)
+ public KubernetesCatalogWatch kubernetesCatalogWatch(KubernetesDiscoveryClient client) {
+ return new KubernetesCatalogWatch(client);
+ }
+}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfiguration.java
deleted file mode 100644
index 925532a5..00000000
--- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientConfiguration.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 to the original authors.
- *
- * 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 org.springframework.cloud.kubernetes.discovery;
-
-import io.fabric8.kubernetes.client.KubernetesClient;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@EnableConfigurationProperties(KubernetesDiscoveryProperties.class)
-@ConditionalOnProperty(value = "spring.cloud.kubernetes.discovery.enabled", matchIfMissing = true)
-public class KubernetesDiscoveryClientConfiguration {
-
- @Bean
- @ConditionalOnMissingBean
- public KubernetesDiscoveryClient kubernetesDiscoveryClient(KubernetesClient client, KubernetesDiscoveryProperties properties) {
- return new KubernetesDiscoveryClient(client, properties);
- }
-
- @Bean
- public KubernetesDiscoveryLifecycle kubernetesDiscoveryLifecycle(KubernetesClient client, KubernetesDiscoveryProperties properties) {
- return new KubernetesDiscoveryLifecycle(client, properties);
- }
-
- @Bean
- @ConditionalOnMissingBean
- @ConditionalOnProperty(name = "spring.cloud.kubernetes.discovery.catalog-services-watch.enabled", matchIfMissing = true)
- public KubernetesCatalogWatch kubernetesCatalogWatch(KubernetesDiscoveryClient client) {
- return new KubernetesCatalogWatch(client);
- }
-}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryLifecycle.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryLifecycle.java
deleted file mode 100644
index 274a8982..00000000
--- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryLifecycle.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2016 to the original authors.
- *
- * 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 org.springframework.cloud.kubernetes.discovery;
-
-import io.fabric8.kubernetes.client.KubernetesClient;
-import org.springframework.cloud.client.discovery.AbstractDiscoveryLifecycle;
-import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class KubernetesDiscoveryLifecycle extends AbstractDiscoveryLifecycle {
-
- private KubernetesClient client;
- private KubernetesDiscoveryProperties properties;
-
- private AtomicBoolean running = new AtomicBoolean(false);
-
- public KubernetesDiscoveryLifecycle(KubernetesClient client, KubernetesDiscoveryProperties properties) {
- this.client = client;
- this.properties = properties;
- }
-
- @Override
- public void start() {
- if (!isEnabled()) {
- return;
- }
- if (running.compareAndSet(false, true)) {
- register();
- getContext().publishEvent(new InstanceRegisteredEvent<>(this,
- getConfiguration()));
- }
- }
-
- @Override
- public boolean isRunning() {
- return this.running.get();
- }
-
-
- @Override
- protected int getConfiguredPort() {
- return client.getMasterUrl().getPort();
- }
-
- @Override
- protected void setConfiguredPort(int port) {
-
- }
-
- @Override
- protected Object getConfiguration() {
- return properties;
- }
-
- @Override
- protected void register() {
- }
-
- @Override
- protected void deregister() {
- }
-
- @Override
- protected boolean isEnabled() {
- return properties.isEnabled();
- }
-}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java
index 35ef9378..d431771c 100644
--- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryProperties.java
@@ -18,34 +18,33 @@ package org.springframework.cloud.kubernetes.discovery;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
@ConfigurationProperties("spring.cloud.kubernetes.discovery")
-public class KubernetesDiscoveryProperties {
+public class KubernetesDiscoveryProperties extends AutoServiceRegistrationProperties {
- private boolean enabled = true;
+ private boolean enabled = true;
- @Value("${spring.application.name:unknown}")
- private String serviceName = "unknown";
+ @Value("${spring.application.name:unknown}")
+ private String serviceName = "unknown";
- private int catalogServicesWatchDelay = 30000;
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public String getServiceName() {
- return serviceName;
- }
-
- public int getCatalogServicesWatchDelay() {
- return catalogServicesWatchDelay;
+ public boolean isEnabled() {
+ return enabled;
}
- public void setCatalogServicesWatchDelay(int catalogServicesWatchDelay) {
- this.catalogServicesWatchDelay = catalogServicesWatchDelay;
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ @Override
+ public String toString() {
+ return "KubernetesDiscoveryProperties{" +
+ "enabled=" + enabled +
+ ", serviceName='" + serviceName + '\'' +
+ '}';
}
}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java
index 6d4be1d2..ec1eddb8 100644
--- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java
@@ -16,75 +16,77 @@
package org.springframework.cloud.kubernetes.discovery;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+
import io.fabric8.kubernetes.api.model.EndpointAddress;
import io.fabric8.kubernetes.api.model.EndpointPort;
import org.springframework.cloud.client.ServiceInstance;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.Map;
-
-import static io.fabric8.kubernetes.client.utils.Utils.isNotNullOrEmpty;
-import static io.fabric8.kubernetes.client.utils.Utils.isNullOrEmpty;
-
public class KubernetesServiceInstance implements ServiceInstance {
- private static final String HTTP_PREFIX = "http://";
- private static final String HTTPS_PREFIX = "https://";
- private static final String COLN = ":";
+ private static final String HTTP_PREFIX = "http://";
+ private static final String HTTPS_PREFIX = "https://";
+ private static final String COLN = ":";
- private final String serviceId;
- private final EndpointAddress endpointAddress;
- private final EndpointPort endpointPort;
- private final Boolean secure;
+ private final String serviceId;
+ private final EndpointAddress endpointAddress;
+ private final EndpointPort endpointPort;
+ private final Boolean secure;
+ private final Map metadata;
- public KubernetesServiceInstance(String serviceId, EndpointAddress endpointAddress, EndpointPort endpointPort, Boolean secure) {
- this.serviceId = serviceId;
- this.endpointAddress = endpointAddress;
- this.endpointPort = endpointPort;
- this.secure = secure;
- }
+ public KubernetesServiceInstance(String serviceId,
+ EndpointAddress endpointAddress,
+ EndpointPort endpointPort,
+ Map metadata,
+ Boolean secure) {
+ this.serviceId = serviceId;
+ this.endpointAddress = endpointAddress;
+ this.endpointPort = endpointPort;
+ this.metadata = metadata;
+ this.secure = secure;
+ }
- @Override
- public String getServiceId() {
- return serviceId;
- }
+ @Override
+ public String getServiceId() {
+ return serviceId;
+ }
- @Override
- public String getHost() {
- return endpointAddress.getIp();
- }
+ @Override
+ public String getHost() {
+ return endpointAddress.getIp();
+ }
- @Override
- public int getPort() {
- return endpointPort.getPort();
- }
+ @Override
+ public int getPort() {
+ return endpointPort.getPort();
+ }
- @Override
- public boolean isSecure() {
- return secure;
- }
+ @Override
+ public boolean isSecure() {
+ return secure;
+ }
- @Override
- public URI getUri() {
- StringBuilder sb = new StringBuilder();
+ @Override
+ public URI getUri() {
+ StringBuilder sb = new StringBuilder();
- if (isSecure()) {
- sb.append(HTTPS_PREFIX);
- } else {
- sb.append(HTTP_PREFIX);
- }
+ if (isSecure()) {
+ sb.append(HTTPS_PREFIX);
+ } else {
+ sb.append(HTTP_PREFIX);
+ }
- sb.append(getHost()).append(COLN).append(getPort());
- try {
- return new URI(sb.toString());
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
+ sb.append(getHost()).append(COLN).append(getPort());
+ try {
+ return new URI(sb.toString());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
- public Map getMetadata() {
- return Collections.EMPTY_MAP;
- }
+ public Map getMetadata() {
+ return metadata;
+ }
}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java
new file mode 100644
index 00000000..43084b4d
--- /dev/null
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesAutoServiceRegistration.java
@@ -0,0 +1,103 @@
+package org.springframework.cloud.kubernetes.registry;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent;
+import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.Ordered;
+
+public class KubernetesAutoServiceRegistration implements AutoServiceRegistration,
+ SmartLifecycle,
+ Ordered {
+
+ private static final Log log = LogFactory.getLog(KubernetesAutoServiceRegistration.class);
+
+ private AtomicBoolean running = new AtomicBoolean(false);
+
+ private int order = 0;
+
+ private AtomicInteger port = new AtomicInteger(0);
+
+ private ApplicationContext context;
+
+ private KubernetesServiceRegistry serviceRegistry;
+
+ private KubernetesRegistration registration;
+
+ public KubernetesAutoServiceRegistration(ApplicationContext context,
+ KubernetesServiceRegistry serviceRegistry,
+ KubernetesRegistration registration) {
+ this.context = context;
+ this.serviceRegistry = serviceRegistry;
+ this.registration = registration;
+ }
+
+ @Override
+ public boolean isAutoStartup() {
+ return true;
+ }
+
+ @Override
+ public void stop(Runnable callback) {
+ stop();
+ callback.run();
+ }
+
+ @Override
+ public void start() {
+ this.serviceRegistry.register(this.registration);
+
+ this.context.publishEvent(
+ new InstanceRegisteredEvent<>(this,
+ this.registration.getProperties()));
+ this.running.set(true);
+ }
+
+ @Override
+ public void stop() {
+ this.serviceRegistry.deregister(this.registration);
+ this.running.set(false);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return this.running.get();
+ }
+
+ @Override
+ public int getPhase() {
+ return 0;
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+
+ @EventListener(ServletWebServerInitializedEvent.class)
+ public void onApplicationEvent(ServletWebServerInitializedEvent event) {
+ // TODO: take SSL into account
+ int localPort = event.getWebServer().getPort();
+ if (this.port.get() == 0) {
+ log.info("Updating port to " + localPort);
+ this.port.compareAndSet(0,
+ localPort);
+ start();
+ }
+ }
+
+ @EventListener(ContextClosedEvent.class)
+ public void onApplicationEvent(ContextClosedEvent event) {
+ if (event.getApplicationContext() == context) {
+ stop();
+ }
+ }
+}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java
new file mode 100644
index 00000000..5c1e766d
--- /dev/null
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesRegistration.java
@@ -0,0 +1,79 @@
+package org.springframework.cloud.kubernetes.registry;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties;
+
+public class KubernetesRegistration implements Registration, Closeable {
+
+
+ private final KubernetesClient client;
+ private KubernetesDiscoveryProperties properties;
+ private AtomicBoolean running = new AtomicBoolean(false);
+
+ public KubernetesRegistration(KubernetesClient client,
+ KubernetesDiscoveryProperties properties) {
+ this.client = client;
+ this.properties = properties;
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.client.close();
+ }
+
+ @Override
+ public String getServiceId() {
+ return properties.getServiceName();
+ }
+
+ @Override
+ public String getHost() {
+ return client.getMasterUrl().getHost();
+ }
+
+ @Override
+ public int getPort() {
+ return 0;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return false;
+ }
+
+ @Override
+ public URI getUri() {
+ try {
+ return client.getMasterUrl().toURI();
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public KubernetesDiscoveryProperties getProperties() {
+ return properties;
+ }
+
+ @Override
+ public Map getMetadata() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "KubernetesRegistration{" +
+ "client=" + client +
+ ", properties=" + properties +
+ ", running=" + running +
+ '}';
+ }
+}
diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java
new file mode 100644
index 00000000..62b7b891
--- /dev/null
+++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/registry/KubernetesServiceRegistry.java
@@ -0,0 +1,41 @@
+package org.springframework.cloud.kubernetes.registry;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+
+public class KubernetesServiceRegistry implements ServiceRegistry {
+
+ private static final Log log = LogFactory.getLog(KubernetesServiceRegistry.class);
+
+ public KubernetesServiceRegistry() {
+ }
+
+ @Override
+ public void register(KubernetesRegistration registration) {
+ log.info("Registering : " + registration);
+ }
+
+ @Override
+ public void deregister(KubernetesRegistration registration) {
+ log.info("DeRegistering : " + registration);
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public void setStatus(KubernetesRegistration registration,
+ String status) {
+ log.info("Set Status for : " + registration + " Status: " + status);
+
+ }
+
+ @Override
+ public T getStatus(KubernetesRegistration registration) {
+ log.info("Get Status for : " + registration );
+ return null;
+ }
+}
diff --git a/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories
index a542fcb2..2eec90f0 100644
--- a/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-kubernetes-discovery/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,5 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration
# Discovery Client Configuration
org.springframework.cloud.client.discovery.EnableDiscoveryClient=\
-org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientConfiguration
+org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClient
diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchtConfigurationTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java
similarity index 94%
rename from spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchtConfigurationTest.java
rename to spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java
index c5a49942..29d3f211 100644
--- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchtConfigurationTest.java
+++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogServicesWatchConfigurationTest.java
@@ -24,7 +24,7 @@ import static org.mockito.Mockito.mock;
/**
* @author Oleg Vyukov
*/
-public class KubernetesCatalogServicesWatchtConfigurationTest {
+public class KubernetesCatalogServicesWatchConfigurationTest {
private ConfigurableApplicationContext context;
@@ -51,7 +51,7 @@ public class KubernetesCatalogServicesWatchtConfigurationTest {
this.context = new SpringApplicationBuilder(
PropertyPlaceholderAutoConfiguration.class,
KubernetesClientTestConfiguration.class,
- KubernetesDiscoveryClientConfiguration.class).web(false)
+ KubernetesDiscoveryClientAutoConfiguration.class).web(false)
.properties(env).run();
}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/README.md b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/README.md
index cb4c86a8..f8e8d246 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/README.md
+++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/README.md
@@ -1,3 +1,21 @@
+# Setting up the Environment
+
+To play with these examples, you can install locally Kubernetes & Docker using `[Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/)` within a Virtual Machine
+managed by a hypervisor (Xhyve, Virtualbox or KVM) if your machine is not a native Unix operating system.
+
+
+When the minikube is installed on your machine, you can start kubernetes using this command:
+```
+minikube start
+```
+
+You also probably want to configure your docker client to point the minikube docker deamon with:
+```
+eval $(minikube docker-env)
+```
+
+This will make sure that the docker images that you build are available to the minikube environment.
+
# Hello World Example
This Spring Boot application exposes an endpoint that we can call to receive a `Hello World` message as response. The application is configured using the
@@ -6,25 +24,18 @@ This Spring Boot application exposes an endpoint that we can call to receive a `
The uberjar of the Spring Boot application is packaged within a Docker image using the [Fabric8 Maven plugin](maven.fabric8.io) and next deployed top of the Kubernetes management platform as a pod
using the replication controller created by the plugin.
-To play with the example, it is required to have access to a Kubernetes Management Platform which is available on GCE. If you don't have an account on GCE,
-you can install locally Kubernetes & Docker using `[Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/)` within a Virtual Machine
-managed by a hypervisor (Xhyve, Virtualbox or KVM) if your machine is not a native Unix operating system.
-The script to install `minikube` is
-```
-curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.17.1/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
-```
-
-When the client is installed on your machine, you can start kubernetes using this command:
-```
-minikube start
-```
+Once you have the environment set up (minikube or kubectl configured against a kubernetes cluster)
-Next, you can play with this Spring Boot application in the cloud using the following maven command to deploy it:
+You can play with this Spring Boot application in the cloud using the following maven command to deploy it:
```
mvn clean package fabric8:deploy -Pkubernetes
```
+**Note**: Unfortuntaly, when you deploy using the fabric8 plugin, the readyness and liveness probes fail to point to the right actuator URL due a lack of support for spring boot.
+This push you to edit the generated deployment inside kubernetes and change these probes which points to "path": "/health" to "path": "/actuator/health".
+This will make your deployment go green. This issue is already reported into the fabric8 community: https://github.com/fabric8io/fabric8-maven-plugin/issues/1178
+
When the application has been deployed, you can access its service or endpoint url using this command:
```
minikube service kubernetes-hello-world --url
@@ -35,19 +46,15 @@ And next you can curl the endpoint using the url returned by the previous comman
```
curl http://IP_OR_HOSTNAME/
```
+
+then
+
+```
+curl http://IP_OR_HOSTNAME/services
+```
+
+Should return you the list of available services discovered by the DiscoveryClient
-## Integration test
-
-To deploy the resources required on Kubernetes/OpenShift and to test if the service deployed can answer to requests, we will use the [Arquillian Kubernetes Cube](https://github.com/arquillian/arquillian-cube/blob/master/docs/kubernetes.adoc) framework.
-This testing framework uses the Kubernetes Java API to communicate with the platform, deploy the resources (pod, service, deployment, ...) generated by the Fabric8 maven plugin.
-When the service becomes available, the method defines within thr Junit test will call the endpoint to verify that it receives as response the string
-`Hello World`
-
-Remark : If you run the integration test against OpenShift, create first the namespace/project `it` that arquillian will use to deploy the resources using the oc client
-`oc new-project it`.
-
-When you are logged to the OpenShift platform, execute the following maven command to run the Integration Test against OpenShift
-
```
mvn clean install -Pintegration
```
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml
index 3d064335..cce0a591 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml
+++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml
@@ -35,6 +35,17 @@
${project.version}
+
+ org.springframework.cloud
+ spring-cloud-kubernetes-discovery
+ ${project.version}
+
+
+
+ org.springframework.cloud
+ spring-cloud-commons
+
+
org.springframework.boot
spring-boot-starter
@@ -57,23 +68,23 @@
- org.jboss.arquillian.junit
- arquillian-junit-standalone
+ junit
+ junit
test
- org.arquillian.cube
- arquillian-cube-requirement
+ org.assertj
+ assertj-core
test
- org.arquillian.cube
- arquillian-cube-kubernetes
+ org.springframework.boot
+ spring-boot-test
test
- org.arquillian.cube
- arquillian-cube-openshift
+ org.springframework
+ spring-test
test
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
index 51b1b5b6..4fa2c3a6 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
+++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
@@ -18,16 +18,17 @@ package org.springframework.cloud.kubernetes.examples;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
*
*/
@SpringBootApplication
+@EnableDiscoveryClient
public class App {
- public static void main(String[] args) {
- SpringApplication.run(App.class, args);
- }
-
+ public static void main(String[] args) {
+ SpringApplication.run(App.class,
+ args);
+ }
}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java
index 063e2e3e..5f6c3f99 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java
+++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java
@@ -1,14 +1,30 @@
package org.springframework.cloud.kubernetes.examples;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
+ private static final Log log = LogFactory.getLog(HelloController.class);
+
+ @Autowired
+ private DiscoveryClient discoveryClient;
+
@RequestMapping("/")
public String hello() {
return "Hello World";
}
+ @RequestMapping("/services")
+ public List services() {
+ return this.discoveryClient.getServices();
+ }
}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java
new file mode 100644
index 00000000..b69ea538
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/ApplicationTestIT.java
@@ -0,0 +1,27 @@
+package org.springframework.cloud.kubernetes.examples;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = App.class)
+public class ApplicationTestIT {
+
+ @Autowired
+ private ApplicationContext context;
+
+ /*
+ * This test proves that the application can be loaded successful and that all @configurations and dependencies are there
+ */
+ @Test
+ public void contextLoads() throws Exception {
+ assertThat(context).isNotNull();
+ }
+}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/HelloWorldIT.java b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/HelloWorldIT.java
deleted file mode 100644
index d848ec7f..00000000
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/java/org/springframework/cloud/kubernetes/examples/HelloWorldIT.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.springframework.cloud.kubernetes.examples;
-
-
-import org.arquillian.cube.kubernetes.annotations.PortForward;
-import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes;
-import org.arquillian.cube.requirement.ArquillianConditionalRunner;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.net.URL;
-
-import javax.inject.Named;
-
-import io.fabric8.kubernetes.api.model.Pod;
-import io.fabric8.kubernetes.api.model.Service;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-
-@RunWith(ArquillianConditionalRunner.class)
-@RequiresKubernetes
-public class HelloWorldIT {
-
- @ArquillianResource
- @Named("kubernetes-hello-world") //The service name is "${project.artifactId}".substring(0,23)
- @PortForward
- URL url;
-
- @Test
- public void service_should_be_accessible() throws IOException {
- OkHttpClient client = new OkHttpClient();
- Request request = new Request.Builder().get().url(url).build();
- Response response = client.newCall(request).execute();
- Assert.assertTrue(response.isSuccessful());
- }
-}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/arquillian.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/arquillian.xml
deleted file mode 100644
index 570f95f9..00000000
--- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/test/resources/arquillian.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- it
-
- openshift.yml
- true
-
-
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/README.md b/spring-cloud-kubernetes-examples/kubernetes-reload-example/README.md
new file mode 100644
index 00000000..7283a047
--- /dev/null
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/README.md
@@ -0,0 +1,70 @@
+
+# Setting up the Environment
+
+To play with these examples, you can install locally Kubernetes & Docker using `[Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/)` within a Virtual Machine
+managed by a hypervisor (Xhyve, Virtualbox or KVM) if your machine is not a native Unix operating system.
+
+
+When the minikube is installed on your machine, you can start kubernetes using this command:
+```
+minikube start
+```
+
+You also probably want to configure your docker client to point the minikube docker deamon with:
+```
+eval $(minikube docker-env)
+```
+
+This will make sure that the docker images that you build are available to the minikube environment.
+
+## Kubernetes Reload Example
+
+This example demonstrate how to use the reload feature to change the configuration of a spring-boot application at runtime.
+
+The application consists of a timed bean that periodically prints a message to the console.
+The message can be changed using a config map.
+
+### Running the example
+Once you have your environment set up, you can deploy the application using the fabric8 maven plugin:
+
+```
+mvn clean install fabric8:build fabric8:deploy -Pintegration
+```
+
+**Note**: Unfortuntaly, when you deploy using the fabric8 plugin, the readyness and liveness probes fail to point to the right actuator URL due a lack of support for spring boot.
+This push you to edit the generated deployment inside kubernetes and change these probes which points to "path": "/health" to "path": "/actuator/health".
+This will make your deployment go green. This issue is already reported into the fabric8 community: https://github.com/fabric8io/fabric8-maven-plugin/issues/1178
+
+### Changing the configuration
+
+Create a yaml file with the following contents:
+
+```yml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: reload-example
+data:
+ application.properties: |-
+ bean.message=Hello World!
+ another.property=value
+```
+
+A sample config map is provided with this example in the *config-map.yml* file.
+
+To deploy the config map, just run the following command on Kubernetes:
+
+```
+kubectl create -f config-map.yml
+```
+
+As soon as the config map is deployed, the output of the application changes accordingly.
+The config map can be now edited with the following command:
+
+```
+kubectl edit configmap reload-example
+```
+
+Changes are applied immediately when using the *event* reload mode.
+
+The name of the config map (*"reload-example"*) matches the name of the application as declared in the *application.properties* file.
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
index 61686ad4..4e6f83c0 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
@@ -1,109 +1,102 @@
-
- spring-cloud-kubernetes-examples
- org.springframework.cloud
- 0.2.1.BUILD-SNAPSHOT
-
- 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">
+
+ spring-cloud-kubernetes-examples
+ org.springframework.cloud
+ 0.2.1.BUILD-SNAPSHOT
+
+ 4.0.0
- spring-cloud-kubernetes-example-reload
+ spring-cloud-kubernetes-example-reload
- Spring Cloud Kubernetes :: Examples :: Reload ConfigMap
- Example demonstrating how to use the configuration reload feature.
+ Spring Cloud Kubernetes :: Examples :: Reload ConfigMap
+ Example demonstrating how to use the configuration reload feature.
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- pom
- import
- ${spring-boot.version}
-
-
-
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ pom
+ import
+ ${spring-boot.version}
+
+
+
-
- 5.2.4.Final
-
+
+ 5.2.4.Final
+
-
+
- org.springframework.boot
- spring-boot-starter
-
+ org.springframework.boot
+ spring-boot-starter
+
org.springframework.boot
spring-boot-actuator
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-tomcat
-
-
-
-
- org.springframework.boot
- spring-boot-starter-undertow
-
+
+ org.springframework.boot
+ spring-boot-actuator-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
org.springframework.cloud
spring-cloud-starter-kubernetes-config
${project.version}
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate-validator.version}
+
-
- org.hibernate
- hibernate-validator
- ${hibernate-validator.version}
-
+
-
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
-
-
- repackage
-
-
-
-
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${maven-deploy-plugin.version}
+
+ true
+
+
-
-
- org.apache.maven.plugins
- maven-deploy-plugin
- ${maven-deploy-plugin.version}
-
- true
-
-
-
-
- io.fabric8
- fabric8-maven-plugin
- ${fabric8.maven.plugin.version}
-
-
- fmp
-
- resource
-
-
-
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${fabric8.maven.plugin.version}
+
+
+ fmp
+
+ resource
+
+
+
@@ -116,9 +109,9 @@
-
-
-
+
+
+
@@ -143,7 +136,7 @@
spring-cloud-reload
-
+
spring-cloud-reload
NodePort
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md b/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md
deleted file mode 100644
index d3c54216..00000000
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md
+++ /dev/null
@@ -1,54 +0,0 @@
-## Kubernetes Reload Example
-
-This example demonstrate how to use the reload feature to change the configuration of a spring-boot application at runtime.
-
-The application consists of a timed bean that periodically prints a message to the console.
-The message can be changed using a config map.
-
-### Running the example
-
-When using Openshift, you must assign the `view` role to the *default* service account in the current project:
-
-```
-oc policy add-role-to-user view --serviceaccount=default
-```
-
-You can deploy the application using the fabric8 maven plugin:
-
-```
-mvn clean install fabric8:build fabric8:deploy -Pintegration
-```
-
-### Changing the configuration
-
-Create a yaml file with the following contents:
-
-```yml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: reload-example
-data:
- application.properties: |-
- bean.message=Hello World!
- another.property=value
-```
-
-A sample config map is provided with this example in the *config-map.yml* file.
-
-To deploy the config map, just run the following command on Openshift (just replace `oc` with `kubectl` if you are using plain Kubernetes):
-
-```
-oc create -f config-map.yml
-```
-
-As soon as the config map is deployed, the output of the application changes accordingly.
-The config map can be now edited with the following command:
-
-```
-oc edit configmap reload-example
-```
-
-Changes are applied immediately when using the *event* reload mode.
-
-The name of the config map (*"reload-example"*) matches the name of the application as declared in the *application.properties* file.
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
index 000892e0..580c8435 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/java/org/springframework/cloud/kubernetes/examples/App.java
@@ -18,6 +18,7 @@ package org.springframework.cloud.kubernetes.examples;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/application.properties b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/application.properties
index ca0bfe4a..e45b7c66 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/application.properties
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/src/main/resources/application.properties
@@ -1,5 +1,7 @@
spring.application.name=reload-example
-
+management.endpoint.health.enabled=true
+management.endpoint.info.enabled=true
+management.endpoint.restart.enabled=true
spring.cloud.kubernetes.reload.enabled=true
#spring.cloud.kubernetes.reload.strategy=restart_context
diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml
index e48fcf74..4805dbfc 100644
--- a/spring-cloud-kubernetes-examples/pom.xml
+++ b/spring-cloud-kubernetes-examples/pom.xml
@@ -18,8 +18,8 @@
kubernetes-reload-example
kubernetes-hello-world-example
- kubernetes-circuitbreaker-ribbon-example
- kubernetes-zipkin-example
+