Updates formatting and license header
This commit is contained in:
27
pom.xml
27
pom.xml
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,36 +17,35 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
|
||||
public abstract class AbstractConfigProperties {
|
||||
|
||||
protected boolean enabled = true;
|
||||
protected String name;
|
||||
protected String namespace;
|
||||
protected boolean enabled = true;
|
||||
protected String name;
|
||||
protected String namespace;
|
||||
|
||||
public abstract String getConfigurationTarget();
|
||||
public abstract String getConfigurationTarget();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -20,11 +20,12 @@ package org.springframework.cloud.kubernetes.config;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.api.model.Secret;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -34,22 +35,25 @@ import org.springframework.context.annotation.Import;
|
||||
@ConditionalOnClass({ ConfigMap.class, Secret.class })
|
||||
public class BootstrapConfiguration {
|
||||
|
||||
@Configuration
|
||||
@Import(KubernetesAutoConfiguration.class)
|
||||
@EnableConfigurationProperties({ ConfigMapConfigProperties.class, SecretsConfigProperties.class })
|
||||
@ConditionalOnProperty(name = "spring.cloud.kubernetes.config.enabled", matchIfMissing = true)
|
||||
protected static class KubernetesPropertySourceConfiguration {
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
@Configuration
|
||||
@Import(KubernetesAutoConfiguration.class)
|
||||
@EnableConfigurationProperties({ ConfigMapConfigProperties.class,
|
||||
SecretsConfigProperties.class })
|
||||
@ConditionalOnProperty(name = "spring.cloud.kubernetes.config.enabled", matchIfMissing = true)
|
||||
protected static class KubernetesPropertySourceConfiguration {
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
|
||||
@Bean
|
||||
public ConfigMapPropertySourceLocator configMapPropertySourceLocator(ConfigMapConfigProperties properties) {
|
||||
return new ConfigMapPropertySourceLocator(client, properties);
|
||||
}
|
||||
@Bean
|
||||
public ConfigMapPropertySourceLocator configMapPropertySourceLocator(
|
||||
ConfigMapConfigProperties properties) {
|
||||
return new ConfigMapPropertySourceLocator(client, properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecretsPropertySourceLocator secretsPropertySourceLocator(SecretsConfigProperties properties) {
|
||||
return new SecretsPropertySourceLocator(client, properties);
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public SecretsPropertySourceLocator secretsPropertySourceLocator(
|
||||
SecretsConfigProperties properties) {
|
||||
return new SecretsPropertySourceLocator(client, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -21,13 +21,14 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ConfigurationProperties("spring.cloud.kubernetes.config")
|
||||
public class ConfigMapConfigProperties extends AbstractConfigProperties {
|
||||
|
||||
private static final String TARGET = "Config Map";
|
||||
private static final String TARGET = "Config Map";
|
||||
|
||||
private boolean enableApi = true;
|
||||
private List<String> paths = new LinkedList<>();
|
||||
@@ -58,28 +59,32 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A list of Source to use
|
||||
* If the user has not specified any Source properties, then a single Source
|
||||
* is constructed based on the supplied name and namespace
|
||||
* @return A list of Source to use If the user has not specified any Source
|
||||
* properties, then a single Source is constructed based on the supplied name and
|
||||
* namespace
|
||||
*
|
||||
* These are the actual name/namespace pairs that are used to create a ConfigMapPropertySource
|
||||
* These are the actual name/namespace pairs that are used to create a
|
||||
* ConfigMapPropertySource
|
||||
*/
|
||||
public List<NormalizedSource> determineSources() {
|
||||
if (sources.isEmpty()) {
|
||||
return new ArrayList<NormalizedSource>() {{
|
||||
add(new NormalizedSource(name, namespace));
|
||||
}};
|
||||
return new ArrayList<NormalizedSource>() {
|
||||
{
|
||||
add(new NormalizedSource(name, namespace));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return sources.stream().map(s -> s.normalize(name, namespace)).collect(Collectors.toList());
|
||||
return sources.stream().map(s -> s.normalize(name, namespace))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigurationTarget() {
|
||||
return TARGET;
|
||||
}
|
||||
public String getConfigurationTarget() {
|
||||
return TARGET;
|
||||
}
|
||||
|
||||
public static class Source {
|
||||
public static class Source {
|
||||
|
||||
/**
|
||||
* The name of the ConfigMap
|
||||
@@ -120,10 +125,10 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
|
||||
}
|
||||
|
||||
public NormalizedSource normalize(String defaultName, String defaultNamespace) {
|
||||
final String normalizedName =
|
||||
StringUtils.isEmpty(this.name) ? defaultName : this.name;
|
||||
final String normalizedNamespace =
|
||||
StringUtils.isEmpty(this.namespace) ? defaultNamespace : this.namespace;
|
||||
final String normalizedName = StringUtils.isEmpty(this.name) ? defaultName
|
||||
: this.name;
|
||||
final String normalizedNamespace = StringUtils.isEmpty(this.namespace)
|
||||
? defaultNamespace : this.namespace;
|
||||
|
||||
return new NormalizedSource(normalizedName, normalizedNamespace);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,13 +17,6 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.ABSTAIN;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.FOUND;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.NOT_FOUND;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@@ -33,58 +26,72 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.ABSTAIN;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.FOUND;
|
||||
import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus.NOT_FOUND;
|
||||
|
||||
public class ConfigMapPropertySource extends KubernetesPropertySource {
|
||||
private static final Log LOG = LogFactory.getLog(ConfigMapPropertySource.class);
|
||||
private static final Log LOG = LogFactory.getLog(ConfigMapPropertySource.class);
|
||||
|
||||
private static final String APPLICATION_YML = "application.yml";
|
||||
private static final String APPLICATION_YAML = "application.yaml";
|
||||
private static final String APPLICATION_PROPERTIES = "application.properties";
|
||||
private static final String APPLICATION_YML = "application.yml";
|
||||
private static final String APPLICATION_YAML = "application.yaml";
|
||||
private static final String APPLICATION_PROPERTIES = "application.properties";
|
||||
|
||||
private static final String PREFIX = "configmap";
|
||||
private static final String PREFIX = "configmap";
|
||||
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name, ConfigMapConfigProperties config) {
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name,
|
||||
ConfigMapConfigProperties config) {
|
||||
this(client, name, null, config);
|
||||
}
|
||||
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name, String[] profiles, ConfigMapConfigProperties config) {
|
||||
this(client, name, null, profiles, config);
|
||||
}
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name,
|
||||
String[] profiles, ConfigMapConfigProperties config) {
|
||||
this(client, name, null, profiles, config);
|
||||
}
|
||||
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name, String namespace, String[] profiles, ConfigMapConfigProperties config) {
|
||||
super(getName(client, name, namespace), asObjectMap(getData(client, name, namespace, profiles, config)));
|
||||
}
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name, String namespace,
|
||||
String[] profiles, ConfigMapConfigProperties config) {
|
||||
super(getName(client, name, namespace),
|
||||
asObjectMap(getData(client, name, namespace, profiles, config)));
|
||||
}
|
||||
|
||||
private static String getName(KubernetesClient client, String name, String namespace) {
|
||||
return new StringBuilder()
|
||||
.append(PREFIX)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(name)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(namespace == null || namespace.isEmpty() ? client.getNamespace() : namespace)
|
||||
.toString();
|
||||
}
|
||||
private static String getName(KubernetesClient client, String name,
|
||||
String namespace) {
|
||||
return new StringBuilder().append(PREFIX)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR).append(name)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(namespace == null || namespace.isEmpty() ? client.getNamespace()
|
||||
: namespace)
|
||||
.toString();
|
||||
}
|
||||
|
||||
private static Map<String, String> getData(KubernetesClient client, String name, String namespace,
|
||||
String[] profiles, ConfigMapConfigProperties config) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
private static Map<String, String> getData(KubernetesClient client, String name,
|
||||
String namespace, String[] profiles, ConfigMapConfigProperties config) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
if (config.isEnableApi()) {
|
||||
try {
|
||||
ConfigMap map = StringUtils.isEmpty(namespace)
|
||||
? client.configMaps().withName(name).get()
|
||||
: client.configMaps().inNamespace(namespace).withName(name).get();
|
||||
? client.configMaps().withName(name).get()
|
||||
: client.configMaps().inNamespace(namespace).withName(name).get();
|
||||
|
||||
if (map != null) {
|
||||
result.putAll(processAllEntries(map.getData(), profiles));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Can't read configMap with name: [" + name + "] in namespace:[" + namespace + "]. Ignoring", e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Can't read configMap with name: [" + name + "] in namespace:["
|
||||
+ namespace + "]. Ignoring", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,29 +99,35 @@ public class ConfigMapPropertySource extends KubernetesPropertySource {
|
||||
putPathConfig(configsFromPaths, config.getPaths());
|
||||
result.putAll(processAllEntries(configsFromPaths, profiles));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> processAllEntries(Map<String, String> input,
|
||||
String[] profiles) {
|
||||
String[] profiles) {
|
||||
|
||||
Set<Entry<String, String>> entrySet = input.entrySet();
|
||||
if(entrySet.size() == 1) {
|
||||
if (entrySet.size() == 1) {
|
||||
Entry<String, String> singleEntry = entrySet.iterator().next();
|
||||
String propertyName = singleEntry.getKey();
|
||||
String propertyValue = singleEntry.getValue();
|
||||
if (propertyName.endsWith(".yml") || propertyName.endsWith(".yaml")) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("The single property with name: [" + propertyName + "] will be treated as a yaml file");
|
||||
LOG.debug("The single property with name: [" + propertyName
|
||||
+ "] will be treated as a yaml file");
|
||||
}
|
||||
|
||||
return yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP).apply(propertyValue);
|
||||
} else if (propertyName.endsWith(".properties")) {
|
||||
return yamlParserGenerator(profiles).andThen(PROPERTIES_TO_MAP)
|
||||
.apply(propertyValue);
|
||||
}
|
||||
else if (propertyName.endsWith(".properties")) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("The single property with name: [" + propertyName + "] will be treated as a properties file");
|
||||
LOG.debug("The single property with name: [" + propertyName
|
||||
+ "] will be treated as a properties file");
|
||||
}
|
||||
|
||||
return KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP).apply(propertyValue);
|
||||
} else {
|
||||
return KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP)
|
||||
.apply(propertyValue);
|
||||
}
|
||||
else {
|
||||
return defaultProcessAllEntries(input, profiles);
|
||||
}
|
||||
}
|
||||
@@ -123,42 +136,48 @@ public class ConfigMapPropertySource extends KubernetesPropertySource {
|
||||
}
|
||||
|
||||
private static Map<String, String> defaultProcessAllEntries(Map<String, String> input,
|
||||
String[] profiles) {
|
||||
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()));
|
||||
.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<String, String> extractProperties(String resourceName, String content, String[] profiles) {
|
||||
private static Map<String, String> extractProperties(String resourceName,
|
||||
String content, String[] profiles) {
|
||||
Map<String, String> 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 {
|
||||
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;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Map<String, Object> asObjectMap(Map<String, String> source) {
|
||||
return source.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
private static Map<String, Object> asObjectMap(Map<String, String> source) {
|
||||
return source.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
private static Function<String, Properties> yamlParserGenerator(final String[] profiles) {
|
||||
private static Function<String, Properties> yamlParserGenerator(
|
||||
final String[] profiles) {
|
||||
return s -> {
|
||||
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
|
||||
yamlFactory.setDocumentMatchers(properties -> {
|
||||
String profileProperty = properties.getProperty("spring.profiles");
|
||||
if (profileProperty != null && profileProperty.length() > 0) {
|
||||
return asList(profiles).contains(profileProperty) ? FOUND : NOT_FOUND;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ABSTAIN;
|
||||
}
|
||||
});
|
||||
@@ -167,20 +186,19 @@ public class ConfigMapPropertySource extends KubernetesPropertySource {
|
||||
};
|
||||
}
|
||||
|
||||
private static final Function<String, Properties> KEY_VALUE_TO_PROPERTIES = s -> {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(new ByteArrayInputStream(s.getBytes()));
|
||||
return properties;
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Function<Properties, Map<String,String>> PROPERTIES_TO_MAP = p -> p.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> String.valueOf(e.getKey()),
|
||||
e -> String.valueOf(e.getValue())));
|
||||
private static final Function<String, Properties> KEY_VALUE_TO_PROPERTIES = s -> {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(new ByteArrayInputStream(s.getBytes()));
|
||||
return properties;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Function<Properties, Map<String, String>> PROPERTIES_TO_MAP = p -> p
|
||||
.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()),
|
||||
e -> String.valueOf(e.getValue())));
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,11 +17,10 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace;
|
||||
import java.util.List;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapConfigProperties.NormalizedSource;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -31,47 +30,50 @@ import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace;
|
||||
|
||||
@Order(0)
|
||||
public class ConfigMapPropertySourceLocator implements PropertySourceLocator {
|
||||
private final KubernetesClient client;
|
||||
private final ConfigMapConfigProperties properties;
|
||||
private final KubernetesClient client;
|
||||
private final ConfigMapConfigProperties properties;
|
||||
|
||||
public ConfigMapPropertySourceLocator(KubernetesClient client, ConfigMapConfigProperties properties) {
|
||||
this.client = client;
|
||||
this.properties = properties;
|
||||
}
|
||||
public ConfigMapPropertySourceLocator(KubernetesClient client,
|
||||
ConfigMapConfigProperties properties) {
|
||||
this.client = client;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertySource locate(Environment environment) {
|
||||
if (environment instanceof ConfigurableEnvironment) {
|
||||
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
|
||||
@Override
|
||||
public PropertySource locate(Environment environment) {
|
||||
if (environment instanceof ConfigurableEnvironment) {
|
||||
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
|
||||
|
||||
List<ConfigMapConfigProperties.NormalizedSource> sources =
|
||||
properties.determineSources();
|
||||
List<ConfigMapConfigProperties.NormalizedSource> sources = properties
|
||||
.determineSources();
|
||||
if (sources.size() == 1) {
|
||||
return getMapPropertySourceForSingleConfigMap(env, sources.get(0));
|
||||
}
|
||||
|
||||
CompositePropertySource composite = new CompositePropertySource("composite-configmap");
|
||||
sources.forEach(s ->
|
||||
composite.addFirstPropertySource(getMapPropertySourceForSingleConfigMap(env, s))
|
||||
);
|
||||
CompositePropertySource composite = new CompositePropertySource(
|
||||
"composite-configmap");
|
||||
sources.forEach(s -> composite.addFirstPropertySource(
|
||||
getMapPropertySourceForSingleConfigMap(env, s)));
|
||||
|
||||
return composite;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MapPropertySource getMapPropertySourceForSingleConfigMap(
|
||||
ConfigurableEnvironment environment, NormalizedSource normalizedSource) {
|
||||
ConfigurableEnvironment environment, NormalizedSource normalizedSource) {
|
||||
|
||||
String configurationTarget = properties.getConfigurationTarget();
|
||||
return new ConfigMapPropertySource(
|
||||
client,
|
||||
getApplicationName(environment, normalizedSource.getName(), configurationTarget),
|
||||
getApplicationNamespace(client, normalizedSource.getNamespace(), configurationTarget),
|
||||
environment.getActiveProfiles(),
|
||||
properties
|
||||
);
|
||||
String configurationTarget = properties.getConfigurationTarget();
|
||||
return new ConfigMapPropertySource(client,
|
||||
getApplicationName(environment, normalizedSource.getName(),
|
||||
configurationTarget),
|
||||
getApplicationNamespace(client, normalizedSource.getNamespace(),
|
||||
configurationTarget),
|
||||
environment.getActiveProfiles(), properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.config;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.config.Constants.FALLBACK_APPLICATION_NAME;
|
||||
import static org.springframework.cloud.kubernetes.config.Constants.SPRING_APPLICATION_NAME;
|
||||
|
||||
@@ -14,36 +31,38 @@ public class ConfigUtils {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(ConfigUtils.class);
|
||||
|
||||
public static <C extends AbstractConfigProperties> String getApplicationName(Environment env,
|
||||
String configName, String configurationTarget) {
|
||||
String name = configName;
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
//TODO: use relaxed binding
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(configurationTarget +
|
||||
" name has not been set, taking it from property/env " +
|
||||
SPRING_APPLICATION_NAME + " (default=" + FALLBACK_APPLICATION_NAME + ")");
|
||||
}
|
||||
public static <C extends AbstractConfigProperties> String getApplicationName(
|
||||
Environment env, String configName, String configurationTarget) {
|
||||
String name = configName;
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
// TODO: use relaxed binding
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(configurationTarget
|
||||
+ " name has not been set, taking it from property/env "
|
||||
+ SPRING_APPLICATION_NAME + " (default="
|
||||
+ FALLBACK_APPLICATION_NAME + ")");
|
||||
}
|
||||
|
||||
name = env.getProperty(SPRING_APPLICATION_NAME, FALLBACK_APPLICATION_NAME);
|
||||
}
|
||||
name = env.getProperty(SPRING_APPLICATION_NAME, FALLBACK_APPLICATION_NAME);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static <C extends AbstractConfigProperties> String getApplicationNamespace(
|
||||
KubernetesClient client, String configNamespace, String configurationTarget) {
|
||||
String namespace = configNamespace;
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(
|
||||
configurationTarget + " namespace has not been set, taking it from client (ns="+client.getNamespace()+")");
|
||||
}
|
||||
public static <C extends AbstractConfigProperties> String getApplicationNamespace(
|
||||
KubernetesClient client, String configNamespace, String configurationTarget) {
|
||||
String namespace = configNamespace;
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(configurationTarget
|
||||
+ " namespace has not been set, taking it from client (ns="
|
||||
+ client.getNamespace() + ")");
|
||||
}
|
||||
|
||||
namespace = client.getNamespace();
|
||||
}
|
||||
namespace = client.getNamespace();
|
||||
}
|
||||
|
||||
return namespace;
|
||||
}
|
||||
return namespace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,10 +17,10 @@
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
final class Constants {
|
||||
static final String SPRING_APPLICATION_NAME = "spring.application.name";
|
||||
static final String FALLBACK_APPLICATION_NAME = "application";
|
||||
static final String PROPERTY_SOURCE_NAME_SEPARATOR = ".";
|
||||
static final String SPRING_APPLICATION_NAME = "spring.application.name";
|
||||
static final String FALLBACK_APPLICATION_NAME = "application";
|
||||
static final String PROPERTY_SOURCE_NAME_SEPARATOR = ".";
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
private Constants() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2017 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -26,39 +26,38 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties("spring.cloud.kubernetes.secrets")
|
||||
public class SecretsConfigProperties extends AbstractConfigProperties {
|
||||
|
||||
private static final String TARGET = "Secret";
|
||||
private static final String TARGET = "Secret";
|
||||
|
||||
private boolean enableApi = false;
|
||||
private Map<String, String> labels = new HashMap<>();
|
||||
private List<String> paths = new LinkedList<>();
|
||||
private boolean enableApi = false;
|
||||
private Map<String, String> labels = new HashMap<>();
|
||||
private List<String> paths = new LinkedList<>();
|
||||
|
||||
public boolean isEnableApi() {
|
||||
return enableApi;
|
||||
}
|
||||
|
||||
public boolean isEnableApi() {
|
||||
return enableApi;
|
||||
}
|
||||
public void setEnableApi(boolean enableApi) {
|
||||
this.enableApi = enableApi;
|
||||
}
|
||||
|
||||
public void setEnableApi(boolean enableApi) {
|
||||
this.enableApi = enableApi;
|
||||
}
|
||||
public void setLabels(Map<String, String> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
public void setLabels(Map<String, String> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
public Map<String, String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public Map<String, String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
public void setPaths(List<String> paths) {
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
public void setPaths(List<String> paths) {
|
||||
this.paths = paths;
|
||||
}
|
||||
public List<String> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
public List<String> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigurationTarget() {
|
||||
return TARGET;
|
||||
}
|
||||
@Override
|
||||
public String getConfigurationTarget() {
|
||||
return TARGET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -22,99 +22,90 @@ import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Secret;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.*;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationName;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigUtils.getApplicationNamespace;
|
||||
|
||||
public class SecretsPropertySource extends KubernetesPropertySource {
|
||||
private static final Log LOG = LogFactory.getLog(SecretsPropertySource.class);
|
||||
private static final Log LOG = LogFactory.getLog(SecretsPropertySource.class);
|
||||
|
||||
private static final String PREFIX = "secrets";
|
||||
private static final String PREFIX = "secrets";
|
||||
|
||||
public SecretsPropertySource(KubernetesClient client, Environment env, SecretsConfigProperties config) {
|
||||
super(
|
||||
getSourceName(client, env, config),
|
||||
getSourceData(client, env, config)
|
||||
);
|
||||
}
|
||||
public SecretsPropertySource(KubernetesClient client, Environment env,
|
||||
SecretsConfigProperties config) {
|
||||
super(getSourceName(client, env, config), getSourceData(client, env, config));
|
||||
}
|
||||
|
||||
private static String getSourceName(KubernetesClient client, Environment env, SecretsConfigProperties config) {
|
||||
return new StringBuilder()
|
||||
.append(PREFIX)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(getApplicationName(env, config.getName(), config.getConfigurationTarget()))
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(getApplicationNamespace(client, config.getNamespace(),
|
||||
config.getConfigurationTarget()))
|
||||
.toString();
|
||||
}
|
||||
private static String getSourceName(KubernetesClient client, Environment env,
|
||||
SecretsConfigProperties config) {
|
||||
return new StringBuilder().append(PREFIX)
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(getApplicationName(env, config.getName(),
|
||||
config.getConfigurationTarget()))
|
||||
.append(Constants.PROPERTY_SOURCE_NAME_SEPARATOR)
|
||||
.append(getApplicationNamespace(client, config.getNamespace(),
|
||||
config.getConfigurationTarget()))
|
||||
.toString();
|
||||
}
|
||||
|
||||
private static Map<String, Object> getSourceData(KubernetesClient client, Environment env, SecretsConfigProperties config) {
|
||||
String name = getApplicationName(env, config.getName(), config.getConfigurationTarget());
|
||||
String namespace = getApplicationNamespace(client, config.getNamespace(),
|
||||
config.getConfigurationTarget());
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
private static Map<String, Object> getSourceData(KubernetesClient client,
|
||||
Environment env, SecretsConfigProperties config) {
|
||||
String name = getApplicationName(env, config.getName(),
|
||||
config.getConfigurationTarget());
|
||||
String namespace = getApplicationNamespace(client, config.getNamespace(),
|
||||
config.getConfigurationTarget());
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
if (config.isEnableApi()) {
|
||||
try {
|
||||
// Read for secrets api (named)
|
||||
if (config.isEnableApi()) {
|
||||
try {
|
||||
// Read for secrets api (named)
|
||||
Secret secret;
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
secret = client.secrets()
|
||||
.withName(name)
|
||||
.get();
|
||||
} else {
|
||||
secret = client.secrets()
|
||||
.inNamespace(namespace)
|
||||
.withName(name)
|
||||
.get();
|
||||
}
|
||||
putAll(secret, result);
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
secret = client.secrets().withName(name).get();
|
||||
}
|
||||
else {
|
||||
secret = client.secrets().inNamespace(namespace).withName(name).get();
|
||||
}
|
||||
putAll(secret, result);
|
||||
|
||||
// Read for secrets api (label)
|
||||
if (!config.getLabels().isEmpty()) {
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
client.secrets()
|
||||
.withLabels(config.getLabels())
|
||||
.list()
|
||||
.getItems()
|
||||
.forEach(s -> putAll(s, result));
|
||||
} else {
|
||||
client.secrets()
|
||||
.inNamespace(namespace)
|
||||
.withLabels(config.getLabels())
|
||||
.list()
|
||||
.getItems()
|
||||
.forEach(s -> putAll(s, result));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Can't read secret with name: [" + name +
|
||||
"] or labels [" + config.getLabels() +
|
||||
"] in namespace:[" + namespace +
|
||||
"] (cause: " + e.getMessage() + "). Ignoring");
|
||||
}
|
||||
}
|
||||
// Read for secrets api (label)
|
||||
if (!config.getLabels().isEmpty()) {
|
||||
if (StringUtils.isEmpty(namespace)) {
|
||||
client.secrets().withLabels(config.getLabels()).list().getItems()
|
||||
.forEach(s -> putAll(s, result));
|
||||
}
|
||||
else {
|
||||
client.secrets().inNamespace(namespace)
|
||||
.withLabels(config.getLabels()).list().getItems()
|
||||
.forEach(s -> putAll(s, result));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Can't read secret with name: [" + name + "] or labels ["
|
||||
+ config.getLabels() + "] in namespace:[" + namespace
|
||||
+ "] (cause: " + e.getMessage() + "). Ignoring");
|
||||
}
|
||||
}
|
||||
|
||||
// read for secrets mount
|
||||
// read for secrets mount
|
||||
putPathConfig(result, config.getPaths());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************
|
||||
// Helpers
|
||||
// *****************************
|
||||
private static void putAll(Secret secret, Map<String, Object> result) {
|
||||
if (secret != null && secret.getData() != null) {
|
||||
secret.getData().forEach((k, v) -> result.put(
|
||||
k,
|
||||
new String(Base64.getDecoder().decode(v)).trim())
|
||||
);
|
||||
}
|
||||
}
|
||||
// Helpers
|
||||
// *****************************
|
||||
private static void putAll(Secret secret, Map<String, Object> result) {
|
||||
if (secret != null && secret.getData() != null) {
|
||||
secret.getData().forEach((k, v) -> result.put(k,
|
||||
new String(Base64.getDecoder().decode(v)).trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -18,27 +18,27 @@
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
@Order(1)
|
||||
public class SecretsPropertySourceLocator implements PropertySourceLocator {
|
||||
private final KubernetesClient client;
|
||||
private final SecretsConfigProperties properties;
|
||||
private final KubernetesClient client;
|
||||
private final SecretsConfigProperties properties;
|
||||
|
||||
public SecretsPropertySourceLocator(KubernetesClient client, SecretsConfigProperties properties) {
|
||||
this.client = client;
|
||||
this.properties = properties;
|
||||
}
|
||||
public SecretsPropertySourceLocator(KubernetesClient client,
|
||||
SecretsConfigProperties properties) {
|
||||
this.client = client;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapPropertySource locate(Environment environment) {
|
||||
return environment instanceof ConfigurableEnvironment
|
||||
? new SecretsPropertySource(client, environment, properties)
|
||||
: null;
|
||||
}
|
||||
@Override
|
||||
public MapPropertySource locate(Environment environment) {
|
||||
return environment instanceof ConfigurableEnvironment
|
||||
? new SecretsPropertySource(client, environment, properties) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,21 +17,20 @@
|
||||
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;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.cloud.context.restart.RestartEndpoint;
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -44,64 +43,77 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
|
||||
@AutoConfigureAfter({InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, RefreshAutoConfiguration.class})
|
||||
@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class,
|
||||
RefreshEndpointAutoConfiguration.class, RefreshAutoConfiguration.class })
|
||||
@EnableConfigurationProperties(ConfigReloadProperties.class)
|
||||
|
||||
public class ConfigReloadAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Configuration reload must be enabled explicitly.
|
||||
*/
|
||||
@ConditionalOnProperty(value = "spring.cloud.kubernetes.reload.enabled")
|
||||
@ConditionalOnClass({RestartEndpoint.class, ContextRefresher.class})
|
||||
@EnableScheduling
|
||||
@EnableAsync
|
||||
protected static class ConfigReloadAutoConfigurationBeans {
|
||||
/**
|
||||
* Configuration reload must be enabled explicitly.
|
||||
*/
|
||||
@ConditionalOnProperty(value = "spring.cloud.kubernetes.reload.enabled")
|
||||
@ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class })
|
||||
@EnableScheduling
|
||||
@EnableAsync
|
||||
protected static class ConfigReloadAutoConfigurationBeans {
|
||||
|
||||
@Autowired
|
||||
private AbstractEnvironment environment;
|
||||
@Autowired
|
||||
private AbstractEnvironment environment;
|
||||
|
||||
@Autowired
|
||||
private KubernetesClient kubernetesClient;
|
||||
@Autowired
|
||||
private KubernetesClient kubernetesClient;
|
||||
|
||||
@Autowired
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
@Autowired
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
@Autowired
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
|
||||
/**
|
||||
* Provides a bean that listen to configuration changes and fire a reload.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConfigurationChangeDetector propertyChangeWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) {
|
||||
switch (properties.getMode()) {
|
||||
case POLLING:
|
||||
return new PollingConfigurationChangeDetector(environment, properties, kubernetesClient, strategy, configMapPropertySourceLocator, secretsPropertySourceLocator);
|
||||
case EVENT:
|
||||
return new EventBasedConfigurationChangeDetector(environment, properties, kubernetesClient, strategy, configMapPropertySourceLocator, secretsPropertySourceLocator);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported configuration reload mode: " + properties.getMode());
|
||||
}
|
||||
/**
|
||||
* Provides a bean that listen to configuration changes and fire a reload.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConfigurationChangeDetector propertyChangeWatcher(
|
||||
ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) {
|
||||
switch (properties.getMode()) {
|
||||
case POLLING:
|
||||
return new PollingConfigurationChangeDetector(environment, properties,
|
||||
kubernetesClient, strategy, configMapPropertySourceLocator,
|
||||
secretsPropertySourceLocator);
|
||||
case EVENT:
|
||||
return new EventBasedConfigurationChangeDetector(environment, properties,
|
||||
kubernetesClient, strategy, configMapPropertySourceLocator,
|
||||
secretsPropertySourceLocator);
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unsupported configuration reload mode: " + properties.getMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the action to execute when the configuration changes.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, ConfigurableApplicationContext ctx, RestartEndpoint restarter, ContextRefresher refresher) {
|
||||
switch (properties.getStrategy()) {
|
||||
case RESTART_CONTEXT:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), restarter::restart);
|
||||
case REFRESH:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh);
|
||||
case SHUTDOWN:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), ctx::close);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
|
||||
}
|
||||
/**
|
||||
* Provides the action to execute when the configuration changes.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConfigurationUpdateStrategy configurationUpdateStrategy(
|
||||
ConfigReloadProperties properties, ConfigurableApplicationContext ctx,
|
||||
RestartEndpoint restarter, ContextRefresher refresher) {
|
||||
switch (properties.getStrategy()) {
|
||||
case RESTART_CONTEXT:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(),
|
||||
restarter::restart);
|
||||
case REFRESH:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(),
|
||||
refresher::refresh);
|
||||
case SHUTDOWN:
|
||||
return new ConfigurationUpdateStrategy(properties.getStrategy().name(),
|
||||
ctx::close);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported configuration update strategy: "
|
||||
+ properties.getStrategy());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -24,117 +24,120 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties(prefix = "spring.cloud.kubernetes.reload")
|
||||
public class ConfigReloadProperties {
|
||||
|
||||
/**
|
||||
* Enables the Kubernetes configuration reload on change.
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
/**
|
||||
* Enables the Kubernetes configuration reload on change.
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
|
||||
/**
|
||||
* Enables monitoring on config maps to detect changes.
|
||||
*/
|
||||
private boolean monitoringConfigMaps = true;
|
||||
/**
|
||||
* Enables monitoring on config maps to detect changes.
|
||||
*/
|
||||
private boolean monitoringConfigMaps = true;
|
||||
|
||||
/**
|
||||
* Enables monitoring on secrets to detect changes.
|
||||
*/
|
||||
private boolean monitoringSecrets = false;
|
||||
/**
|
||||
* Enables monitoring on secrets to detect changes.
|
||||
*/
|
||||
private boolean monitoringSecrets = false;
|
||||
|
||||
/**
|
||||
* Sets the reload strategy for Kubernetes configuration reload on change.
|
||||
*/
|
||||
private ReloadStrategy strategy = ReloadStrategy.REFRESH;
|
||||
/**
|
||||
* Sets the reload strategy for Kubernetes configuration reload on change.
|
||||
*/
|
||||
private ReloadStrategy strategy = ReloadStrategy.REFRESH;
|
||||
|
||||
/**
|
||||
* Sets the detection mode for Kubernetes configuration reload.
|
||||
*/
|
||||
private ReloadDetectionMode mode = ReloadDetectionMode.EVENT;
|
||||
/**
|
||||
* Sets the detection mode for Kubernetes configuration reload.
|
||||
*/
|
||||
private ReloadDetectionMode mode = ReloadDetectionMode.EVENT;
|
||||
|
||||
/**
|
||||
* Sets the polling period in milliseconds to use when the detection mode is POLLING.
|
||||
*/
|
||||
private Long period = 15000L;
|
||||
/**
|
||||
* Sets the polling period in milliseconds to use when the detection mode is POLLING.
|
||||
*/
|
||||
private Long period = 15000L;
|
||||
|
||||
public ConfigReloadProperties() {
|
||||
}
|
||||
public ConfigReloadProperties() {
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isMonitoringConfigMaps() {
|
||||
return monitoringConfigMaps;
|
||||
}
|
||||
public boolean isMonitoringConfigMaps() {
|
||||
return monitoringConfigMaps;
|
||||
}
|
||||
|
||||
public void setMonitoringConfigMaps(boolean monitoringConfigMaps) {
|
||||
this.monitoringConfigMaps = monitoringConfigMaps;
|
||||
}
|
||||
public void setMonitoringConfigMaps(boolean monitoringConfigMaps) {
|
||||
this.monitoringConfigMaps = monitoringConfigMaps;
|
||||
}
|
||||
|
||||
public boolean isMonitoringSecrets() {
|
||||
return monitoringSecrets;
|
||||
}
|
||||
public boolean isMonitoringSecrets() {
|
||||
return monitoringSecrets;
|
||||
}
|
||||
|
||||
public void setMonitoringSecrets(boolean monitoringSecrets) {
|
||||
this.monitoringSecrets = monitoringSecrets;
|
||||
}
|
||||
public void setMonitoringSecrets(boolean monitoringSecrets) {
|
||||
this.monitoringSecrets = monitoringSecrets;
|
||||
}
|
||||
|
||||
public ReloadStrategy getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
public ReloadStrategy getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
|
||||
public void setStrategy(ReloadStrategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
public void setStrategy(ReloadStrategy strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
public ReloadDetectionMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
public ReloadDetectionMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public Long getPeriod() {
|
||||
return period;
|
||||
}
|
||||
public Long getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(Long period) {
|
||||
this.period = period;
|
||||
}
|
||||
public void setPeriod(Long period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public void setMode(ReloadDetectionMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
public void setMode(ReloadDetectionMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public enum ReloadStrategy {
|
||||
/**
|
||||
* Fire a refresh of beans annotated with @ConfigurationProperties or @RefreshScope.
|
||||
*/
|
||||
REFRESH,
|
||||
public enum ReloadStrategy {
|
||||
/**
|
||||
* Fire a refresh of beans annotated with @ConfigurationProperties
|
||||
* or @RefreshScope.
|
||||
*/
|
||||
REFRESH,
|
||||
|
||||
/**
|
||||
* Restarts the Spring ApplicationContext to apply the new configuration.
|
||||
*/
|
||||
RESTART_CONTEXT,
|
||||
/**
|
||||
* Restarts the Spring ApplicationContext to apply the new configuration.
|
||||
*/
|
||||
RESTART_CONTEXT,
|
||||
|
||||
/**
|
||||
* Shuts down the Spring ApplicationContext to activate a restart of the container.
|
||||
* Make sure that the lifecycle of all non-daemon threads is bound to the ApplicationContext and that
|
||||
* a replication controller or replica set is configured to restart the pod.
|
||||
*/
|
||||
SHUTDOWN
|
||||
}
|
||||
/**
|
||||
* Shuts down the Spring ApplicationContext to activate a restart of the
|
||||
* container. Make sure that the lifecycle of all non-daemon threads is bound to
|
||||
* the ApplicationContext and that a replication controller or replica set is
|
||||
* configured to restart the pod.
|
||||
*/
|
||||
SHUTDOWN
|
||||
}
|
||||
|
||||
public enum ReloadDetectionMode {
|
||||
/**
|
||||
* Enables a polling task that retrieves periodically all external properties and
|
||||
* fire a reload when they change.
|
||||
*/
|
||||
POLLING,
|
||||
public enum ReloadDetectionMode {
|
||||
/**
|
||||
* Enables a polling task that retrieves periodically all external properties and
|
||||
* fire a reload when they change.
|
||||
*/
|
||||
POLLING,
|
||||
|
||||
/**
|
||||
* Listens to Kubernetes events and checks if a reload is needed when configmaps or secrets change.
|
||||
*/
|
||||
EVENT
|
||||
}
|
||||
/**
|
||||
* Listens to Kubernetes events and checks if a reload is needed when configmaps
|
||||
* or secrets change.
|
||||
*/
|
||||
EVENT
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -16,15 +16,18 @@
|
||||
*/
|
||||
package org.springframework.cloud.kubernetes.config.reload;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -33,61 +36,67 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
/**
|
||||
* This is the superclass of all beans that can listen to changes in the configuration and fire a reload.
|
||||
* This is the superclass of all beans that can listen to changes in the configuration and
|
||||
* fire a reload.
|
||||
*/
|
||||
public abstract class ConfigurationChangeDetector {
|
||||
|
||||
protected Log log = LogFactory.getLog(getClass());
|
||||
protected Log log = LogFactory.getLog(getClass());
|
||||
|
||||
protected ConfigurableEnvironment environment;
|
||||
protected ConfigurableEnvironment environment;
|
||||
|
||||
protected ConfigReloadProperties properties;
|
||||
protected ConfigReloadProperties properties;
|
||||
|
||||
protected KubernetesClient kubernetesClient;
|
||||
protected KubernetesClient kubernetesClient;
|
||||
|
||||
protected ConfigurationUpdateStrategy strategy;
|
||||
protected ConfigurationUpdateStrategy strategy;
|
||||
|
||||
public ConfigurationChangeDetector(ConfigurableEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy) {
|
||||
this.environment = environment;
|
||||
this.properties = properties;
|
||||
this.kubernetesClient = kubernetesClient;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
public ConfigurationChangeDetector(ConfigurableEnvironment environment,
|
||||
ConfigReloadProperties properties, KubernetesClient kubernetesClient,
|
||||
ConfigurationUpdateStrategy strategy) {
|
||||
this.environment = environment;
|
||||
this.properties = properties;
|
||||
this.kubernetesClient = kubernetesClient;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
// Ensure the kubernetes client is cleaned up from spare threads when shutting down
|
||||
kubernetesClient.close();
|
||||
}
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
// Ensure the kubernetes client is cleaned up from spare threads when shutting
|
||||
// down
|
||||
kubernetesClient.close();
|
||||
}
|
||||
|
||||
public void reloadProperties() {
|
||||
log.info("Reloading using strategy: " + strategy.getName());
|
||||
strategy.reload();
|
||||
}
|
||||
public void reloadProperties() {
|
||||
log.info("Reloading using strategy: " + strategy.getName());
|
||||
strategy.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two property sources are different.
|
||||
*/
|
||||
protected boolean changed(MapPropertySource mp1, MapPropertySource mp2) {
|
||||
if (mp1 == mp2) return false;
|
||||
if (mp1 == null && mp2 != null || mp1 != null && mp2 == null) return true;
|
||||
/**
|
||||
* Determines if two property sources are different.
|
||||
*/
|
||||
protected boolean changed(MapPropertySource mp1, MapPropertySource mp2) {
|
||||
if (mp1 == mp2)
|
||||
return false;
|
||||
if (mp1 == null && mp2 != null || mp1 != null && mp2 == null)
|
||||
return true;
|
||||
|
||||
Map<String, Object> s1 = mp1.getSource();
|
||||
Map<String, Object> s2 = mp2.getSource();
|
||||
Map<String, Object> s1 = mp1.getSource();
|
||||
Map<String, Object> s2 = mp2.getSource();
|
||||
|
||||
return s1 == null ? s2 != null : !s1.equals(s2);
|
||||
}
|
||||
return s1 == null ? s2 != null : !s1.equals(s2);
|
||||
}
|
||||
|
||||
protected boolean changed(List<? extends MapPropertySource> l1,
|
||||
List<? extends MapPropertySource> l2) {
|
||||
protected boolean changed(List<? extends MapPropertySource> l1,
|
||||
List<? extends MapPropertySource> l2) {
|
||||
|
||||
if(l1.size() != l2.size()) {
|
||||
if (l1.size() != l2.size()) {
|
||||
log.debug("The current number of Confimap PropertySources does not match "
|
||||
+ "the ones loaded from the Kubernetes - No reload will take place");
|
||||
+ "the ones loaded from the Kubernetes - No reload will take place");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i=0; i<l1.size(); i++) {
|
||||
for (int i = 0; i < l1.size(); i++) {
|
||||
if (changed(l1.get(i), l2.get(i))) {
|
||||
return true;
|
||||
}
|
||||
@@ -95,70 +104,72 @@ public abstract class ConfigurationChangeDetector {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds one registered property source of the given type, logging a warning if
|
||||
* multiple property sources of that type are available.
|
||||
*/
|
||||
protected <S extends PropertySource<?>> S findPropertySource(Class<S> sourceClass) {
|
||||
List<S> sources = findPropertySources(sourceClass);
|
||||
if (sources.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (sources.size() > 1) {
|
||||
log.warn("Found more than one property source of type " + sourceClass);
|
||||
}
|
||||
return sources.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all registered property sources of the given type.
|
||||
*/
|
||||
protected <S extends PropertySource<?>> List<S> findPropertySources(Class<S> sourceClass) {
|
||||
List<S> managedSources = new LinkedList<>();
|
||||
|
||||
LinkedList<PropertySource<?>> sources = toLinkedList(environment.getPropertySources());
|
||||
while (!sources.isEmpty()) {
|
||||
PropertySource<?> source = sources.pop();
|
||||
if (source instanceof CompositePropertySource) {
|
||||
CompositePropertySource comp = (CompositePropertySource) source;
|
||||
sources.addAll(comp.getPropertySources());
|
||||
} else if (sourceClass.isInstance(source)) {
|
||||
managedSources.add(sourceClass.cast(source));
|
||||
}
|
||||
}
|
||||
|
||||
return managedSources;
|
||||
}
|
||||
|
||||
private <E> LinkedList<E> toLinkedList(Iterable<E> it) {
|
||||
LinkedList<E> list = new LinkedList<E>();
|
||||
for (E e : it) {
|
||||
list.add(e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
/**
|
||||
* Finds one registered property source of the given type, logging a warning if
|
||||
* multiple property sources of that type are available.
|
||||
*/
|
||||
protected <S extends PropertySource<?>> S findPropertySource(Class<S> sourceClass) {
|
||||
List<S> sources = findPropertySources(sourceClass);
|
||||
if (sources.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (sources.size() > 1) {
|
||||
log.warn("Found more than one property source of type " + sourceClass);
|
||||
}
|
||||
return sources.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of MapPropertySource that correspond to the current state of the system
|
||||
* This only handles the PropertySource objects that are returned
|
||||
* Finds all registered property sources of the given type.
|
||||
*/
|
||||
protected <S extends PropertySource<?>> List<S> findPropertySources(
|
||||
Class<S> sourceClass) {
|
||||
List<S> managedSources = new LinkedList<>();
|
||||
|
||||
LinkedList<PropertySource<?>> sources = toLinkedList(
|
||||
environment.getPropertySources());
|
||||
while (!sources.isEmpty()) {
|
||||
PropertySource<?> source = sources.pop();
|
||||
if (source instanceof CompositePropertySource) {
|
||||
CompositePropertySource comp = (CompositePropertySource) source;
|
||||
sources.addAll(comp.getPropertySources());
|
||||
}
|
||||
else if (sourceClass.isInstance(source)) {
|
||||
managedSources.add(sourceClass.cast(source));
|
||||
}
|
||||
}
|
||||
|
||||
return managedSources;
|
||||
}
|
||||
|
||||
private <E> LinkedList<E> toLinkedList(Iterable<E> it) {
|
||||
LinkedList<E> list = new LinkedList<E>();
|
||||
for (E e : it) {
|
||||
list.add(e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of MapPropertySource that correspond to the current state of the
|
||||
* system This only handles the PropertySource objects that are returned
|
||||
*/
|
||||
protected List<MapPropertySource> locateMapPropertySources(
|
||||
PropertySourceLocator propertySourceLocator, Environment environment) {
|
||||
PropertySourceLocator propertySourceLocator, Environment environment) {
|
||||
|
||||
List<MapPropertySource> result = new ArrayList<>();
|
||||
PropertySource propertySource= propertySourceLocator.locate(environment);
|
||||
if(propertySource instanceof MapPropertySource) {
|
||||
PropertySource propertySource = propertySourceLocator.locate(environment);
|
||||
if (propertySource instanceof MapPropertySource) {
|
||||
result.add((MapPropertySource) propertySource);
|
||||
} else if(propertySource instanceof CompositePropertySource) {
|
||||
result.addAll(((CompositePropertySource) propertySource)
|
||||
.getPropertySources()
|
||||
.stream()
|
||||
.filter(p -> p instanceof MapPropertySource)
|
||||
.map(p -> (MapPropertySource) p)
|
||||
.collect(Collectors.toList()));
|
||||
} else {
|
||||
}
|
||||
else if (propertySource instanceof CompositePropertySource) {
|
||||
result.addAll(((CompositePropertySource) propertySource).getPropertySources()
|
||||
.stream().filter(p -> p instanceof MapPropertySource)
|
||||
.map(p -> (MapPropertySource) p).collect(Collectors.toList()));
|
||||
}
|
||||
else {
|
||||
log.debug("Found property source that cannot be handled: "
|
||||
+ propertySource.getClass());
|
||||
+ propertySource.getClass());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -19,34 +19,35 @@ package org.springframework.cloud.kubernetes.config.reload;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This is the superclass of all named strategies that can be fired when the configuration changes.
|
||||
* This is the superclass of all named strategies that can be fired when the configuration
|
||||
* changes.
|
||||
*/
|
||||
public class ConfigurationUpdateStrategy {
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
private Runnable reloadProcedure;
|
||||
private Runnable reloadProcedure;
|
||||
|
||||
public ConfigurationUpdateStrategy(String name, Runnable reloadProcedure) {
|
||||
Objects.requireNonNull(name, "name cannot be null");
|
||||
Objects.requireNonNull(reloadProcedure, "reloadProcedure cannot be null");
|
||||
this.name = name;
|
||||
this.reloadProcedure = reloadProcedure;
|
||||
}
|
||||
public ConfigurationUpdateStrategy(String name, Runnable reloadProcedure) {
|
||||
Objects.requireNonNull(name, "name cannot be null");
|
||||
Objects.requireNonNull(reloadProcedure, "reloadProcedure cannot be null");
|
||||
this.name = name;
|
||||
this.reloadProcedure = reloadProcedure;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
this.reloadProcedure.run();
|
||||
}
|
||||
public void reload() {
|
||||
this.reloadProcedure.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("ConfigurationUpdateStrategy{");
|
||||
sb.append("name='").append(name).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("ConfigurationUpdateStrategy{");
|
||||
sb.append("name='").append(name).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -16,16 +16,19 @@
|
||||
*/
|
||||
package org.springframework.cloud.kubernetes.config.reload;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMap;
|
||||
import io.fabric8.kubernetes.api.model.Secret;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.KubernetesClientException;
|
||||
import io.fabric8.kubernetes.client.Watch;
|
||||
import io.fabric8.kubernetes.client.Watcher;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySource;
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.config.SecretsPropertySource;
|
||||
@@ -34,117 +37,124 @@ import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
/**
|
||||
* A change detector that subscribes to changes in secrets and configmaps and fire a reload when something changes.
|
||||
* A change detector that subscribes to changes in secrets and configmaps and fire a
|
||||
* reload when something changes.
|
||||
*/
|
||||
public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
|
||||
private Map<String, Watch> watches;
|
||||
private Map<String, Watch> watches;
|
||||
|
||||
public EventBasedConfigurationChangeDetector(AbstractEnvironment environment,
|
||||
ConfigReloadProperties properties,
|
||||
KubernetesClient kubernetesClient,
|
||||
ConfigurationUpdateStrategy strategy,
|
||||
ConfigMapPropertySourceLocator configMapPropertySourceLocator,
|
||||
SecretsPropertySourceLocator secretsPropertySourceLocator) {
|
||||
super(environment, properties, kubernetesClient, strategy);
|
||||
public EventBasedConfigurationChangeDetector(AbstractEnvironment environment,
|
||||
ConfigReloadProperties properties, KubernetesClient kubernetesClient,
|
||||
ConfigurationUpdateStrategy strategy,
|
||||
ConfigMapPropertySourceLocator configMapPropertySourceLocator,
|
||||
SecretsPropertySourceLocator secretsPropertySourceLocator) {
|
||||
super(environment, properties, kubernetesClient, strategy);
|
||||
|
||||
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
|
||||
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
|
||||
this.watches = new HashMap<>();
|
||||
}
|
||||
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
|
||||
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
|
||||
this.watches = new HashMap<>();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void watch() {
|
||||
boolean activated = false;
|
||||
@PostConstruct
|
||||
public void watch() {
|
||||
boolean activated = false;
|
||||
|
||||
if (properties.isMonitoringConfigMaps()) {
|
||||
try {
|
||||
String name = "config-maps-watch";
|
||||
watches.put(name, kubernetesClient.configMaps()
|
||||
.watch(new Watcher<ConfigMap>() {
|
||||
@Override
|
||||
public void eventReceived(Action action, ConfigMap configMap) {
|
||||
onEvent(configMap);
|
||||
}
|
||||
if (properties.isMonitoringConfigMaps()) {
|
||||
try {
|
||||
String name = "config-maps-watch";
|
||||
watches.put(name,
|
||||
kubernetesClient.configMaps().watch(new Watcher<ConfigMap>() {
|
||||
@Override
|
||||
public void eventReceived(Action action,
|
||||
ConfigMap configMap) {
|
||||
onEvent(configMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(KubernetesClientException e) {
|
||||
}
|
||||
}));
|
||||
activated = true;
|
||||
log.info("Added new Kubernetes watch: "+name);
|
||||
} catch (Exception e) {
|
||||
log.error("Error while establishing a connection to watch config maps: configuration may remain stale", e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onClose(KubernetesClientException e) {
|
||||
}
|
||||
}));
|
||||
activated = true;
|
||||
log.info("Added new Kubernetes watch: " + name);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error(
|
||||
"Error while establishing a connection to watch config maps: configuration may remain stale",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (properties.isMonitoringSecrets()) {
|
||||
try {
|
||||
activated = false;
|
||||
String name = "secrets-watch";
|
||||
watches.put(name, kubernetesClient.secrets()
|
||||
.watch(new Watcher<Secret>() {
|
||||
@Override
|
||||
public void eventReceived(Action action, Secret secret) {
|
||||
onEvent(secret);
|
||||
}
|
||||
if (properties.isMonitoringSecrets()) {
|
||||
try {
|
||||
activated = false;
|
||||
String name = "secrets-watch";
|
||||
watches.put(name, kubernetesClient.secrets().watch(new Watcher<Secret>() {
|
||||
@Override
|
||||
public void eventReceived(Action action, Secret secret) {
|
||||
onEvent(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(KubernetesClientException e) {
|
||||
}
|
||||
}));
|
||||
activated = true;
|
||||
log.info("Added new Kubernetes watch: " + name);
|
||||
} catch (Exception e) {
|
||||
log.error("Error while establishing a connection to watch secrets: configuration may remain stale", e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onClose(KubernetesClientException e) {
|
||||
}
|
||||
}));
|
||||
activated = true;
|
||||
log.info("Added new Kubernetes watch: " + name);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error(
|
||||
"Error while establishing a connection to watch secrets: configuration may remain stale",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (activated) {
|
||||
log.info("Kubernetes event-based configuration change detector activated");
|
||||
}
|
||||
}
|
||||
if (activated) {
|
||||
log.info("Kubernetes event-based configuration change detector activated");
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void unwatch() {
|
||||
if (this.watches != null) {
|
||||
for (Map.Entry<String, Watch> entry : this.watches.entrySet()) {
|
||||
try {
|
||||
log.debug("Closing the watch "+ entry.getKey());
|
||||
entry.getValue().close();
|
||||
@PreDestroy
|
||||
public void unwatch() {
|
||||
if (this.watches != null) {
|
||||
for (Map.Entry<String, Watch> entry : this.watches.entrySet()) {
|
||||
try {
|
||||
log.debug("Closing the watch " + entry.getKey());
|
||||
entry.getValue().close();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error while closing the watch connection", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while closing the watch connection", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onEvent(ConfigMap configMap) {
|
||||
private void onEvent(ConfigMap configMap) {
|
||||
boolean changed = changed(
|
||||
locateMapPropertySources(configMapPropertySourceLocator, environment),
|
||||
findPropertySources(ConfigMapPropertySource.class)
|
||||
);
|
||||
if(changed) {
|
||||
locateMapPropertySources(configMapPropertySourceLocator, environment),
|
||||
findPropertySources(ConfigMapPropertySource.class));
|
||||
if (changed) {
|
||||
log.info("Detected change in config maps");
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void onEvent(Secret secret) {
|
||||
MapPropertySource currentSecretSource = findPropertySource(SecretsPropertySource.class);
|
||||
if (currentSecretSource != null) {
|
||||
MapPropertySource newSecretSource = secretsPropertySourceLocator.locate(environment);
|
||||
if (changed(currentSecretSource, newSecretSource)) {
|
||||
log.info("Detected change in secrets");
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onEvent(Secret secret) {
|
||||
MapPropertySource currentSecretSource = findPropertySource(
|
||||
SecretsPropertySource.class);
|
||||
if (currentSecretSource != null) {
|
||||
MapPropertySource newSecretSource = secretsPropertySourceLocator
|
||||
.locate(environment);
|
||||
if (changed(currentSecretSource, newSecretSource)) {
|
||||
log.info("Detected change in secrets");
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -16,11 +16,14 @@
|
||||
*/
|
||||
package org.springframework.cloud.kubernetes.config.reload;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySource;
|
||||
import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.config.SecretsPropertySource;
|
||||
@@ -30,61 +33,63 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
/**
|
||||
* A change detector that periodically retrieves secrets and configmaps and fire a reload when something changes.
|
||||
* A change detector that periodically retrieves secrets and configmaps and fire a reload
|
||||
* when something changes.
|
||||
*/
|
||||
public class PollingConfigurationChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
protected Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
|
||||
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
private SecretsPropertySourceLocator secretsPropertySourceLocator;
|
||||
|
||||
public PollingConfigurationChangeDetector(AbstractEnvironment environment,
|
||||
ConfigReloadProperties properties,
|
||||
KubernetesClient kubernetesClient,
|
||||
ConfigurationUpdateStrategy strategy,
|
||||
ConfigMapPropertySourceLocator configMapPropertySourceLocator,
|
||||
SecretsPropertySourceLocator secretsPropertySourceLocator) {
|
||||
super(environment, properties, kubernetesClient, strategy);
|
||||
public PollingConfigurationChangeDetector(AbstractEnvironment environment,
|
||||
ConfigReloadProperties properties, KubernetesClient kubernetesClient,
|
||||
ConfigurationUpdateStrategy strategy,
|
||||
ConfigMapPropertySourceLocator configMapPropertySourceLocator,
|
||||
SecretsPropertySourceLocator secretsPropertySourceLocator) {
|
||||
super(environment, properties, kubernetesClient, strategy);
|
||||
|
||||
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
|
||||
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
|
||||
}
|
||||
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
|
||||
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
log.info("Kubernetes polling configuration change detector activated");
|
||||
}
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
log.info("Kubernetes polling configuration change detector activated");
|
||||
}
|
||||
|
||||
@Scheduled(initialDelayString = "${spring.cloud.kubernetes.reload.period:15000}", fixedDelayString = "${spring.cloud.kubernetes.reload.period:15000}")
|
||||
public void executeCycle() {
|
||||
@Scheduled(initialDelayString = "${spring.cloud.kubernetes.reload.period:15000}", fixedDelayString = "${spring.cloud.kubernetes.reload.period:15000}")
|
||||
public void executeCycle() {
|
||||
|
||||
boolean changedConfigMap = false;
|
||||
if (properties.isMonitoringConfigMaps()) {
|
||||
List<? extends MapPropertySource> currentConfigMapSources
|
||||
= findPropertySources(ConfigMapPropertySource.class);
|
||||
boolean changedConfigMap = false;
|
||||
if (properties.isMonitoringConfigMaps()) {
|
||||
List<? extends MapPropertySource> currentConfigMapSources = findPropertySources(
|
||||
ConfigMapPropertySource.class);
|
||||
|
||||
if (!currentConfigMapSources.isEmpty()) {
|
||||
if (!currentConfigMapSources.isEmpty()) {
|
||||
changedConfigMap = changed(
|
||||
locateMapPropertySources(configMapPropertySourceLocator, environment),
|
||||
currentConfigMapSources
|
||||
);
|
||||
}
|
||||
}
|
||||
locateMapPropertySources(configMapPropertySourceLocator,
|
||||
environment),
|
||||
currentConfigMapSources);
|
||||
}
|
||||
}
|
||||
|
||||
boolean changedSecrets = false;
|
||||
if (properties.isMonitoringSecrets()) {
|
||||
MapPropertySource currentSecretSource = findPropertySource(SecretsPropertySource.class);
|
||||
if (currentSecretSource != null) {
|
||||
MapPropertySource newSecretSource = secretsPropertySourceLocator.locate(environment);
|
||||
changedSecrets = changed(currentSecretSource, newSecretSource);
|
||||
}
|
||||
}
|
||||
boolean changedSecrets = false;
|
||||
if (properties.isMonitoringSecrets()) {
|
||||
MapPropertySource currentSecretSource = findPropertySource(
|
||||
SecretsPropertySource.class);
|
||||
if (currentSecretSource != null) {
|
||||
MapPropertySource newSecretSource = secretsPropertySourceLocator
|
||||
.locate(environment);
|
||||
changedSecrets = changed(currentSecretSource, newSecretSource);
|
||||
}
|
||||
}
|
||||
|
||||
if (changedConfigMap || changedSecrets) {
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
if (changedConfigMap || changedSecrets) {
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.config;
|
||||
|
||||
import io.fabric8.kubernetes.client.utils.IOHelpers;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -30,6 +30,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -44,11 +45,9 @@ import static org.junit.Assert.assertEquals;
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = App.class,
|
||||
properties = { "spring.application.name=configmap-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false"}
|
||||
)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"spring.application.name=configmap-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false" })
|
||||
public class ConfigMapsSpringBootTest {
|
||||
|
||||
@ClassRule
|
||||
@@ -68,23 +67,23 @@ public class ConfigMapsSpringBootTest {
|
||||
public static void setUpBeforeClass() {
|
||||
mockClient = server.getClient();
|
||||
|
||||
//Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
|
||||
mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
|
||||
"false");
|
||||
System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
|
||||
|
||||
HashMap<String,String> data = new HashMap<>();
|
||||
data.put("bean.greeting","Hello ConfigMap, %s!");
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME).andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(APPLICATION_NAME).endMetadata()
|
||||
.addToData(data)
|
||||
.build())
|
||||
.always();
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
data.put("bean.greeting", "Hello ConfigMap, %s!");
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME)
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(APPLICATION_NAME).endMetadata().addToData(data).build())
|
||||
.always();
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
RestAssured.baseURI = String.format("http://localhost:%d/api/greeting", port);
|
||||
@@ -92,23 +91,22 @@ public class ConfigMapsSpringBootTest {
|
||||
|
||||
@Test
|
||||
public void testConfig() {
|
||||
assertEquals(config.getMasterUrl(),mockClient.getConfiguration().getMasterUrl());
|
||||
assertEquals(config.getNamespace(),mockClient.getNamespace());
|
||||
assertEquals(config.getMasterUrl(), mockClient.getConfiguration().getMasterUrl());
|
||||
assertEquals(config.getNamespace(), mockClient.getNamespace());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
when().get()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("content", is("Hello ConfigMap, World!"));
|
||||
when().get().then().statusCode(200).body("content",
|
||||
is("Hello ConfigMap, World!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigMap() {
|
||||
ConfigMap configmap = mockClient.configMaps().inNamespace("test").withName(APPLICATION_NAME).get();
|
||||
HashMap<String,String> keys = (HashMap<String, String>) configmap.getData();
|
||||
assertEquals(keys.get("bean.greeting"),"Hello ConfigMap, %s!");
|
||||
ConfigMap configmap = mockClient.configMaps().inNamespace("test")
|
||||
.withName(APPLICATION_NAME).get();
|
||||
HashMap<String, String> keys = (HashMap<String, String>) configmap.getData();
|
||||
assertEquals(keys.get("bean.greeting"), "Hello ConfigMap, %s!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,17 +17,6 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapList;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapListBuilder;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
|
||||
import io.fabric8.kubernetes.client.utils.IOHelpers;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -35,14 +24,22 @@ import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapList;
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapListBuilder;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.*;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile;
|
||||
|
||||
/**
|
||||
* @author Charles Moulliard
|
||||
@@ -54,7 +51,8 @@ public class ConfigMapsTest {
|
||||
|
||||
@Test
|
||||
public void testConfigMapList() {
|
||||
server.expect().withPath("/api/v1/namespaces/ns1/configmaps").andReturn(200, new ConfigMapListBuilder().build()).once();
|
||||
server.expect().withPath("/api/v1/namespaces/ns1/configmaps")
|
||||
.andReturn(200, new ConfigMapListBuilder().build()).once();
|
||||
|
||||
KubernetesClient client = server.getClient();
|
||||
|
||||
@@ -65,19 +63,21 @@ public class ConfigMapsTest {
|
||||
|
||||
@Test
|
||||
public void testConfigMapGet() {
|
||||
server.expect().withPath("/api/v1/namespaces/ns2/configmaps").andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName("reload-example").endMetadata()
|
||||
.addToData("KEY","123")
|
||||
.build())
|
||||
.once();
|
||||
server.expect().withPath("/api/v1/namespaces/ns2/configmaps")
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata()
|
||||
.withName("reload-example").endMetadata()
|
||||
.addToData("KEY", "123").build())
|
||||
.once();
|
||||
|
||||
KubernetesClient client = server.getClient();
|
||||
ConfigMapList configMapList = client.configMaps().inNamespace("ns2").list();
|
||||
assertNotNull(configMapList);
|
||||
assertEquals(1, configMapList.getAdditionalProperties().size());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,String> data = (Map<String, String>) configMapList.getAdditionalProperties().get("data");
|
||||
assertEquals("123",data.get("KEY"));
|
||||
Map<String, String> data = (Map<String, String>) configMapList
|
||||
.getAdditionalProperties().get("data");
|
||||
assertEquals("123", data.get("KEY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,20 +85,18 @@ public class ConfigMapsTest {
|
||||
String configMapName = "app-properties-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("application.properties",readResourceFile("application.properties"))
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(configMapName).endMetadata()
|
||||
.addToData("application.properties",
|
||||
readResourceFile("application.properties"))
|
||||
.build())
|
||||
.once();
|
||||
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties());
|
||||
|
||||
assertEquals("a", cmps.getProperty("dummy.property.string1"));
|
||||
assertEquals("1", cmps.getProperty("dummy.property.int1"));
|
||||
@@ -110,20 +108,19 @@ public class ConfigMapsTest {
|
||||
String configMapName = "app-yaml-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("application.yaml",readResourceFile("application.yaml"))
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName(configMapName)
|
||||
.endMetadata()
|
||||
.addToData("application.yaml",
|
||||
readResourceFile("application.yaml"))
|
||||
.build())
|
||||
.once();
|
||||
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties());
|
||||
|
||||
assertEquals("a", cmps.getProperty("dummy.property.string2"));
|
||||
assertEquals("1", cmps.getProperty("dummy.property.int2"));
|
||||
@@ -135,20 +132,16 @@ public class ConfigMapsTest {
|
||||
String configMapName = "single-non-standard-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("adhoc.yml",readResourceFile("adhoc.yml"))
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(configMapName).endMetadata()
|
||||
.addToData("adhoc.yml", readResourceFile("adhoc.yml")).build())
|
||||
.once();
|
||||
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties());
|
||||
|
||||
assertEquals("a", cmps.getProperty("dummy.property.string3"));
|
||||
assertEquals("1", cmps.getProperty("dummy.property.int3"));
|
||||
@@ -160,22 +153,18 @@ public class ConfigMapsTest {
|
||||
String configMapName = "single-unparseable-properties-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("application.properties","somevalue")
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName(configMapName)
|
||||
.endMetadata()
|
||||
.addToData("application.properties", "somevalue").build())
|
||||
.once();
|
||||
|
||||
new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
new ConfigMapPropertySource(server.getClient().inNamespace(namespace),
|
||||
configMapName, new ConfigMapConfigProperties());
|
||||
|
||||
//no exception is thrown for unparseable content
|
||||
// no exception is thrown for unparseable content
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,22 +172,18 @@ public class ConfigMapsTest {
|
||||
String configMapName = "single-unparseable-yaml-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("application.yaml","somevalue")
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName(configMapName)
|
||||
.endMetadata().addToData("application.yaml", "somevalue")
|
||||
.build())
|
||||
.once();
|
||||
|
||||
new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
new ConfigMapPropertySource(server.getClient().inNamespace(namespace),
|
||||
configMapName, new ConfigMapConfigProperties());
|
||||
|
||||
//no exception is thrown for unparseable content
|
||||
// no exception is thrown for unparseable content
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,28 +191,28 @@ public class ConfigMapsTest {
|
||||
String configMapName = "app-multiple-properties-test";
|
||||
String namespace = "app-props";
|
||||
server.expect()
|
||||
.withPath(
|
||||
String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, configMapName)
|
||||
)
|
||||
.andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(configMapName).endMetadata()
|
||||
.addToData("application.properties",readResourceFile("application.properties"))
|
||||
.addToData("adhoc.properties",readResourceFile("adhoc.properties"))
|
||||
.build()
|
||||
)
|
||||
.once();
|
||||
.withPath(String.format("/api/v1/namespaces/%s/configmaps/%s", namespace,
|
||||
configMapName))
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName(configMapName)
|
||||
.endMetadata()
|
||||
.addToData("application.properties",
|
||||
readResourceFile("application.properties"))
|
||||
.addToData("adhoc.properties",
|
||||
readResourceFile("adhoc.properties"))
|
||||
.build())
|
||||
.once();
|
||||
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties()
|
||||
);
|
||||
server.getClient().inNamespace(namespace), configMapName,
|
||||
new ConfigMapConfigProperties());
|
||||
|
||||
//application.properties should be read correctly
|
||||
// application.properties should be read correctly
|
||||
assertEquals("a", cmps.getProperty("dummy.property.string1"));
|
||||
assertEquals("1", cmps.getProperty("dummy.property.int1"));
|
||||
assertEquals("true", cmps.getProperty("dummy.property.bool1"));
|
||||
|
||||
//the adhoc.properties file should not be parsed
|
||||
// the adhoc.properties file should not be parsed
|
||||
assertNull(cmps.getProperty("dummy.property.bool2"));
|
||||
assertNull(cmps.getProperty("dummy.property.bool2"));
|
||||
assertNull(cmps.getProperty("dummy.property.bool2"));
|
||||
@@ -250,12 +235,16 @@ public class ConfigMapsTest {
|
||||
|
||||
final Path filesPath = tmp.resolve("cm/files");
|
||||
|
||||
createConfigMapFile(filesPath, "application.yaml", readResourceFile("application.yaml"));
|
||||
createConfigMapFile(filesPath, "application.properties", readResourceFile("application.properties"));
|
||||
createConfigMapFile(filesPath, "application.yaml",
|
||||
readResourceFile("application.yaml"));
|
||||
createConfigMapFile(filesPath, "application.properties",
|
||||
readResourceFile("application.properties"));
|
||||
|
||||
// parse ConfigMaps
|
||||
cmConfProperties.setPaths(Arrays.asList(dbPath.toString(), apiPath.toString(), filesPath.toString()));
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(client, "testapp", cmConfProperties);
|
||||
cmConfProperties.setPaths(Arrays.asList(dbPath.toString(), apiPath.toString(),
|
||||
filesPath.toString()));
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(client, "testapp",
|
||||
cmConfProperties);
|
||||
|
||||
// assert as expected
|
||||
assertEquals("42", cmps.getProperty("foo.bar"));
|
||||
@@ -271,11 +260,12 @@ public class ConfigMapsTest {
|
||||
assertEquals("1", cmps.getProperty("dummy.property.int2"));
|
||||
assertEquals("true", cmps.getProperty("dummy.property.bool2"));
|
||||
|
||||
FileSystemUtils.deleteRecursively(tmp.toFile());
|
||||
FileSystemUtils.deleteRecursively(tmp.toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigMapGetSingleApplicationPropertiesFromVolume() throws IOException {
|
||||
public void testConfigMapGetSingleApplicationPropertiesFromVolume()
|
||||
throws IOException {
|
||||
KubernetesClient client = server.getClient();
|
||||
ConfigMapConfigProperties cmConfProperties = new ConfigMapConfigProperties();
|
||||
cmConfProperties.setEnableApi(false);
|
||||
@@ -286,11 +276,13 @@ public class ConfigMapsTest {
|
||||
|
||||
final Path filesPath = tmp.resolve("cm/files");
|
||||
|
||||
createConfigMapFile(filesPath, "adhoc.properties", readResourceFile("adhoc.properties"));
|
||||
createConfigMapFile(filesPath, "adhoc.properties",
|
||||
readResourceFile("adhoc.properties"));
|
||||
|
||||
// parse ConfigMaps
|
||||
cmConfProperties.setPaths(Collections.singletonList(filesPath.toString()));
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(client, "testapp", cmConfProperties);
|
||||
ConfigMapPropertySource cmps = new ConfigMapPropertySource(client, "testapp",
|
||||
cmConfProperties);
|
||||
|
||||
// assert as expected
|
||||
assertEquals("a", cmps.getProperty("dummy.property.string4"));
|
||||
@@ -300,7 +292,8 @@ public class ConfigMapsTest {
|
||||
FileSystemUtils.deleteRecursively(tmp.toFile());
|
||||
}
|
||||
|
||||
private void createConfigMapFile(Path basePath, String key, String value) throws IOException {
|
||||
private void createConfigMapFile(Path basePath, String key, String value)
|
||||
throws IOException {
|
||||
Files.createDirectories(basePath);
|
||||
final Path apiUrlFile = Files.createFile(basePath.resolve(key));
|
||||
Files.write(apiUrlFile, value.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,35 +17,35 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile;
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
|
||||
import io.restassured.RestAssured;
|
||||
import java.util.HashMap;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.config.example.App;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile;
|
||||
|
||||
/**
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = App.class,
|
||||
properties = { "spring.application.name=configmap-with-profile-no-active-profiles-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false"}
|
||||
)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"spring.application.name=configmap-with-profile-no-active-profiles-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false" })
|
||||
public class ConfigMapsWithProfilesNoActiveProfileSpringBootTest {
|
||||
|
||||
@ClassRule
|
||||
@@ -65,38 +65,35 @@ public class ConfigMapsWithProfilesNoActiveProfileSpringBootTest {
|
||||
public static void setUpBeforeClass() {
|
||||
mockClient = server.getClient();
|
||||
|
||||
//Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
|
||||
mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
|
||||
"false");
|
||||
System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
|
||||
|
||||
HashMap<String,String> data = new HashMap<>();
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
data.put("application.yml", readResourceFile("application-with-profiles.yaml"));
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME).andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(APPLICATION_NAME).endMetadata()
|
||||
.addToData(data)
|
||||
.build())
|
||||
.always();
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME)
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(APPLICATION_NAME).endMetadata().addToData(data).build())
|
||||
.always();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
RestAssured.baseURI = String.format("http://localhost:%d/api/greeting", port);
|
||||
when().get()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("content", is("Hello ConfigMap default, World!"));
|
||||
when().get().then().statusCode(200).body("content",
|
||||
is("Hello ConfigMap default, World!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFarewellEndpoint() {
|
||||
RestAssured.baseURI = String.format("http://localhost:%d/api/farewell", port);
|
||||
when().get()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("content", is("Goodbye ConfigMap default, World!"));
|
||||
when().get().then().statusCode(200).body("content",
|
||||
is("Goodbye ConfigMap default, World!"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,20 +17,18 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.config;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.*;
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
|
||||
import io.restassured.RestAssured;
|
||||
import java.util.HashMap;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -38,15 +36,17 @@ import org.springframework.cloud.kubernetes.config.example.App;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile;
|
||||
|
||||
/**
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = App.class,
|
||||
properties = { "spring.application.name=configmap-with-profile-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false"}
|
||||
)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"spring.application.name=configmap-with-profile-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false" })
|
||||
@ActiveProfiles("development")
|
||||
public class ConfigMapsWithProfilesSpringBootTest {
|
||||
|
||||
@@ -67,37 +67,34 @@ public class ConfigMapsWithProfilesSpringBootTest {
|
||||
public static void setUpBeforeClass() {
|
||||
mockClient = server.getClient();
|
||||
|
||||
//Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
|
||||
mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
|
||||
"false");
|
||||
System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
|
||||
|
||||
HashMap<String,String> data = new HashMap<>();
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
data.put("application.yml", readResourceFile("application-with-profiles.yaml"));
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME).andReturn(200, new ConfigMapBuilder()
|
||||
.withNewMetadata().withName(APPLICATION_NAME).endMetadata()
|
||||
.addToData(data)
|
||||
.build())
|
||||
.always();
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME)
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(APPLICATION_NAME).endMetadata().addToData(data).build())
|
||||
.always();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
RestAssured.baseURI = String.format("http://localhost:%d/api/greeting", port);
|
||||
when().get()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("content", is("Hello ConfigMap dev, World!"));
|
||||
when().get().then().statusCode(200).body("content",
|
||||
is("Hello ConfigMap dev, World!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFarewellEndpoint() {
|
||||
RestAssured.baseURI = String.format("http://localhost:%d/api/farewell", port);
|
||||
when().get()
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("content", is("Goodbye ConfigMap default, World!"));
|
||||
when().get().then().statusCode(200).body("content",
|
||||
is("Goodbye ConfigMap default, World!"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.config;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -19,14 +19,13 @@ package org.springframework.cloud.kubernetes.config.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.config.example2;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.config.example2;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.ConfigBuilder;
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -26,81 +32,98 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.ConfigBuilder;
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
|
||||
@EnableConfigurationProperties(KubernetesClientProperties.class)
|
||||
public class KubernetesAutoConfiguration {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesAutoConfiguration.class);
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesAutoConfiguration.class);
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Config.class)
|
||||
public Config kubernetesClientConfig(KubernetesClientProperties kubernetesClientProperties) {
|
||||
Config base = Config.autoConfigure(null);
|
||||
Config properties = new ConfigBuilder(base)
|
||||
//Only set values that have been explicitly specified
|
||||
.withMasterUrl(or(kubernetesClientProperties.getMasterUrl(), base.getMasterUrl()))
|
||||
.withApiVersion(or(kubernetesClientProperties.getApiVersion(), base.getApiVersion()))
|
||||
.withNamespace(or(kubernetesClientProperties.getNamespace(), base.getNamespace()))
|
||||
.withUsername(or(kubernetesClientProperties.getUsername(), base.getUsername()))
|
||||
.withPassword(or(kubernetesClientProperties.getPassword(), base.getPassword()))
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Config.class)
|
||||
public Config kubernetesClientConfig(
|
||||
KubernetesClientProperties kubernetesClientProperties) {
|
||||
Config base = Config.autoConfigure(null);
|
||||
Config properties = new ConfigBuilder(base)
|
||||
// Only set values that have been explicitly specified
|
||||
.withMasterUrl(or(kubernetesClientProperties.getMasterUrl(),
|
||||
base.getMasterUrl()))
|
||||
.withApiVersion(or(kubernetesClientProperties.getApiVersion(),
|
||||
base.getApiVersion()))
|
||||
.withNamespace(or(kubernetesClientProperties.getNamespace(),
|
||||
base.getNamespace()))
|
||||
.withUsername(
|
||||
or(kubernetesClientProperties.getUsername(), base.getUsername()))
|
||||
.withPassword(
|
||||
or(kubernetesClientProperties.getPassword(), base.getPassword()))
|
||||
|
||||
.withCaCertFile(or(kubernetesClientProperties.getCaCertFile(), base.getCaCertFile()))
|
||||
.withCaCertData(or(kubernetesClientProperties.getCaCertData(), base.getCaCertData()))
|
||||
.withCaCertFile(or(kubernetesClientProperties.getCaCertFile(),
|
||||
base.getCaCertFile()))
|
||||
.withCaCertData(or(kubernetesClientProperties.getCaCertData(),
|
||||
base.getCaCertData()))
|
||||
|
||||
.withClientKeyFile(or(kubernetesClientProperties.getClientKeyFile(), base.getClientKeyFile()))
|
||||
.withClientKeyData(or(kubernetesClientProperties.getClientKeyData(), base.getClientKeyData()))
|
||||
.withClientKeyFile(or(kubernetesClientProperties.getClientKeyFile(),
|
||||
base.getClientKeyFile()))
|
||||
.withClientKeyData(or(kubernetesClientProperties.getClientKeyData(),
|
||||
base.getClientKeyData()))
|
||||
|
||||
.withClientCertFile(or(kubernetesClientProperties.getClientCertFile(), base.getClientCertFile()))
|
||||
.withClientCertData(or(kubernetesClientProperties.getClientCertData(), base.getClientCertData()))
|
||||
.withClientCertFile(or(kubernetesClientProperties.getClientCertFile(),
|
||||
base.getClientCertFile()))
|
||||
.withClientCertData(or(kubernetesClientProperties.getClientCertData(),
|
||||
base.getClientCertData()))
|
||||
|
||||
//No magic is done for the properties below so we leave them as is.
|
||||
.withClientKeyAlgo(or(kubernetesClientProperties.getClientKeyAlgo(), base.getClientKeyAlgo()))
|
||||
.withClientKeyPassphrase(or(kubernetesClientProperties.getClientKeyPassphrase(), base.getClientKeyPassphrase()))
|
||||
.withConnectionTimeout(or(kubernetesClientProperties.getConnectionTimeout(), base.getConnectionTimeout()))
|
||||
.withRequestTimeout(or(kubernetesClientProperties.getRequestTimeout(), base.getRequestTimeout()))
|
||||
.withRollingTimeout(or(kubernetesClientProperties.getRollingTimeout(), base.getRollingTimeout()))
|
||||
.withTrustCerts(or(kubernetesClientProperties.isTrustCerts(), base.isTrustCerts()))
|
||||
.build();
|
||||
// No magic is done for the properties below so we leave them as is.
|
||||
.withClientKeyAlgo(or(kubernetesClientProperties.getClientKeyAlgo(),
|
||||
base.getClientKeyAlgo()))
|
||||
.withClientKeyPassphrase(
|
||||
or(kubernetesClientProperties.getClientKeyPassphrase(),
|
||||
base.getClientKeyPassphrase()))
|
||||
.withConnectionTimeout(
|
||||
or(kubernetesClientProperties.getConnectionTimeout(),
|
||||
base.getConnectionTimeout()))
|
||||
.withRequestTimeout(or(kubernetesClientProperties.getRequestTimeout(),
|
||||
base.getRequestTimeout()))
|
||||
.withRollingTimeout(or(kubernetesClientProperties.getRollingTimeout(),
|
||||
base.getRollingTimeout()))
|
||||
.withTrustCerts(or(kubernetesClientProperties.isTrustCerts(),
|
||||
base.isTrustCerts()))
|
||||
.build();
|
||||
|
||||
if (properties.getNamespace() == null || properties.getNamespace().isEmpty()) {
|
||||
LOG.warn("No namespace has been detected. Please specify KUBERNETES_NAMESPACE env var, or use a later kubernetes version (1.3 or later)");
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
if (properties.getNamespace() == null || properties.getNamespace().isEmpty()) {
|
||||
LOG.warn(
|
||||
"No namespace has been detected. Please specify KUBERNETES_NAMESPACE env var, or use a later kubernetes version (1.3 or later)");
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KubernetesClient kubernetesClient(Config config) {
|
||||
return new DefaultKubernetesClient(config);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KubernetesClient kubernetesClient(Config config) {
|
||||
return new DefaultKubernetesClient(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public StandardPodUtils kubernetesPodUtils(KubernetesClient client) {
|
||||
return new StandardPodUtils(client);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public StandardPodUtils kubernetesPodUtils(KubernetesClient client) {
|
||||
return new StandardPodUtils(client);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(HealthIndicator.class)
|
||||
protected static class KubernetesActuatorConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KubernetesHealthIndicator kubernetesHealthIndicator(PodUtils podUtils) {
|
||||
return new KubernetesHealthIndicator(podUtils);
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
@ConditionalOnClass(HealthIndicator.class)
|
||||
protected static class KubernetesActuatorConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KubernetesHealthIndicator kubernetesHealthIndicator(PodUtils podUtils) {
|
||||
return new KubernetesHealthIndicator(podUtils);
|
||||
}
|
||||
}
|
||||
|
||||
private static <D> D or(D dis, D dat) {
|
||||
if (dis != null) {
|
||||
return dis;
|
||||
} else {
|
||||
return dat;
|
||||
}
|
||||
}
|
||||
private static <D> D or(D dis, D dat) {
|
||||
if (dis != null) {
|
||||
return dis;
|
||||
}
|
||||
else {
|
||||
return dat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
@@ -21,184 +22,184 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties("spring.cloud.kubernetes.client")
|
||||
public class KubernetesClientProperties {
|
||||
|
||||
private Boolean trustCerts;
|
||||
private String masterUrl;
|
||||
private String apiVersion;
|
||||
private String namespace;
|
||||
private String caCertFile;
|
||||
private String caCertData;
|
||||
private String clientCertFile;
|
||||
private String clientCertData;
|
||||
private String clientKeyFile;
|
||||
private String clientKeyData;
|
||||
private String clientKeyAlgo;
|
||||
private String clientKeyPassphrase;
|
||||
private String username;
|
||||
private String password;
|
||||
private Integer watchReconnectInterval;
|
||||
private Integer watchReconnectLimit;
|
||||
private Integer connectionTimeout;
|
||||
private Integer requestTimeout;
|
||||
private Long rollingTimeout;
|
||||
private Integer loggingInterval;
|
||||
private Boolean trustCerts;
|
||||
private String masterUrl;
|
||||
private String apiVersion;
|
||||
private String namespace;
|
||||
private String caCertFile;
|
||||
private String caCertData;
|
||||
private String clientCertFile;
|
||||
private String clientCertData;
|
||||
private String clientKeyFile;
|
||||
private String clientKeyData;
|
||||
private String clientKeyAlgo;
|
||||
private String clientKeyPassphrase;
|
||||
private String username;
|
||||
private String password;
|
||||
private Integer watchReconnectInterval;
|
||||
private Integer watchReconnectLimit;
|
||||
private Integer connectionTimeout;
|
||||
private Integer requestTimeout;
|
||||
private Long rollingTimeout;
|
||||
private Integer loggingInterval;
|
||||
|
||||
public String getClientCertData() {
|
||||
return clientCertData;
|
||||
}
|
||||
public String getClientCertData() {
|
||||
return clientCertData;
|
||||
}
|
||||
|
||||
public void setClientCertData(String clientCertData) {
|
||||
this.clientCertData = clientCertData;
|
||||
}
|
||||
public void setClientCertData(String clientCertData) {
|
||||
this.clientCertData = clientCertData;
|
||||
}
|
||||
|
||||
public Boolean isTrustCerts() {
|
||||
return trustCerts;
|
||||
}
|
||||
public Boolean isTrustCerts() {
|
||||
return trustCerts;
|
||||
}
|
||||
|
||||
public void setTrustCerts(Boolean trustCerts) {
|
||||
this.trustCerts = trustCerts;
|
||||
}
|
||||
public void setTrustCerts(Boolean trustCerts) {
|
||||
this.trustCerts = trustCerts;
|
||||
}
|
||||
|
||||
public String getMasterUrl() {
|
||||
return masterUrl;
|
||||
}
|
||||
public String getMasterUrl() {
|
||||
return masterUrl;
|
||||
}
|
||||
|
||||
public void setMasterUrl(String masterUrl) {
|
||||
this.masterUrl = masterUrl;
|
||||
}
|
||||
public void setMasterUrl(String masterUrl) {
|
||||
this.masterUrl = masterUrl;
|
||||
}
|
||||
|
||||
public String getApiVersion() {
|
||||
return apiVersion;
|
||||
}
|
||||
public String getApiVersion() {
|
||||
return apiVersion;
|
||||
}
|
||||
|
||||
public void setApiVersion(String apiVersion) {
|
||||
this.apiVersion = apiVersion;
|
||||
}
|
||||
public void setApiVersion(String apiVersion) {
|
||||
this.apiVersion = apiVersion;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public String getCaCertFile() {
|
||||
return caCertFile;
|
||||
}
|
||||
public String getCaCertFile() {
|
||||
return caCertFile;
|
||||
}
|
||||
|
||||
public void setCaCertFile(String caCertFile) {
|
||||
this.caCertFile = caCertFile;
|
||||
}
|
||||
public void setCaCertFile(String caCertFile) {
|
||||
this.caCertFile = caCertFile;
|
||||
}
|
||||
|
||||
public String getCaCertData() {
|
||||
return caCertData;
|
||||
}
|
||||
public String getCaCertData() {
|
||||
return caCertData;
|
||||
}
|
||||
|
||||
public void setCaCertData(String caCertData) {
|
||||
this.caCertData = caCertData;
|
||||
}
|
||||
public void setCaCertData(String caCertData) {
|
||||
this.caCertData = caCertData;
|
||||
}
|
||||
|
||||
public String getClientCertFile() {
|
||||
return clientCertFile;
|
||||
}
|
||||
public String getClientCertFile() {
|
||||
return clientCertFile;
|
||||
}
|
||||
|
||||
public void setClientCertFile(String clientCertFile) {
|
||||
this.clientCertFile = clientCertFile;
|
||||
}
|
||||
public void setClientCertFile(String clientCertFile) {
|
||||
this.clientCertFile = clientCertFile;
|
||||
}
|
||||
|
||||
public String getClientKeyFile() {
|
||||
return clientKeyFile;
|
||||
}
|
||||
public String getClientKeyFile() {
|
||||
return clientKeyFile;
|
||||
}
|
||||
|
||||
public void setClientKeyFile(String clientKeyFile) {
|
||||
this.clientKeyFile = clientKeyFile;
|
||||
}
|
||||
public void setClientKeyFile(String clientKeyFile) {
|
||||
this.clientKeyFile = clientKeyFile;
|
||||
}
|
||||
|
||||
public String getClientKeyData() {
|
||||
return clientKeyData;
|
||||
}
|
||||
public String getClientKeyData() {
|
||||
return clientKeyData;
|
||||
}
|
||||
|
||||
public void setClientKeyData(String clientKeyData) {
|
||||
this.clientKeyData = clientKeyData;
|
||||
}
|
||||
public void setClientKeyData(String clientKeyData) {
|
||||
this.clientKeyData = clientKeyData;
|
||||
}
|
||||
|
||||
public String getClientKeyAlgo() {
|
||||
return clientKeyAlgo;
|
||||
}
|
||||
public String getClientKeyAlgo() {
|
||||
return clientKeyAlgo;
|
||||
}
|
||||
|
||||
public void setClientKeyAlgo(String clientKeyAlgo) {
|
||||
this.clientKeyAlgo = clientKeyAlgo;
|
||||
}
|
||||
public void setClientKeyAlgo(String clientKeyAlgo) {
|
||||
this.clientKeyAlgo = clientKeyAlgo;
|
||||
}
|
||||
|
||||
public String getClientKeyPassphrase() {
|
||||
return clientKeyPassphrase;
|
||||
}
|
||||
public String getClientKeyPassphrase() {
|
||||
return clientKeyPassphrase;
|
||||
}
|
||||
|
||||
public void setClientKeyPassphrase(String clientKeyPassphrase) {
|
||||
this.clientKeyPassphrase = clientKeyPassphrase;
|
||||
}
|
||||
public void setClientKeyPassphrase(String clientKeyPassphrase) {
|
||||
this.clientKeyPassphrase = clientKeyPassphrase;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Integer getWatchReconnectInterval() {
|
||||
return watchReconnectInterval;
|
||||
}
|
||||
public Integer getWatchReconnectInterval() {
|
||||
return watchReconnectInterval;
|
||||
}
|
||||
|
||||
public void setWatchReconnectInterval(Integer watchReconnectInterval) {
|
||||
this.watchReconnectInterval = watchReconnectInterval;
|
||||
}
|
||||
public void setWatchReconnectInterval(Integer watchReconnectInterval) {
|
||||
this.watchReconnectInterval = watchReconnectInterval;
|
||||
}
|
||||
|
||||
public Integer getWatchReconnectLimit() {
|
||||
return watchReconnectLimit;
|
||||
}
|
||||
public Integer getWatchReconnectLimit() {
|
||||
return watchReconnectLimit;
|
||||
}
|
||||
|
||||
public void setWatchReconnectLimit(Integer watchReconnectLimit) {
|
||||
this.watchReconnectLimit = watchReconnectLimit;
|
||||
}
|
||||
public void setWatchReconnectLimit(Integer watchReconnectLimit) {
|
||||
this.watchReconnectLimit = watchReconnectLimit;
|
||||
}
|
||||
|
||||
public Integer getConnectionTimeout() {
|
||||
return connectionTimeout;
|
||||
}
|
||||
public Integer getConnectionTimeout() {
|
||||
return connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Integer connectionTimeout) {
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
public void setConnectionTimeout(Integer connectionTimeout) {
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
public Integer getRequestTimeout() {
|
||||
return requestTimeout;
|
||||
}
|
||||
public Integer getRequestTimeout() {
|
||||
return requestTimeout;
|
||||
}
|
||||
|
||||
public void setRequestTimeout(Integer requestTimeout) {
|
||||
this.requestTimeout = requestTimeout;
|
||||
}
|
||||
public void setRequestTimeout(Integer requestTimeout) {
|
||||
this.requestTimeout = requestTimeout;
|
||||
}
|
||||
|
||||
public Long getRollingTimeout() {
|
||||
return rollingTimeout;
|
||||
}
|
||||
public Long getRollingTimeout() {
|
||||
return rollingTimeout;
|
||||
}
|
||||
|
||||
public void setRollingTimeout(Long rollingTimeout) {
|
||||
this.rollingTimeout = rollingTimeout;
|
||||
}
|
||||
public void setRollingTimeout(Long rollingTimeout) {
|
||||
this.rollingTimeout = rollingTimeout;
|
||||
}
|
||||
|
||||
public Integer getLoggingInterval() {
|
||||
return loggingInterval;
|
||||
}
|
||||
public Integer getLoggingInterval() {
|
||||
return loggingInterval;
|
||||
}
|
||||
|
||||
public void setLoggingInterval(Integer loggingInterval) {
|
||||
this.loggingInterval = loggingInterval;
|
||||
}
|
||||
public void setLoggingInterval(Integer loggingInterval) {
|
||||
this.loggingInterval = loggingInterval;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
|
||||
public class KubernetesHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private PodUtils utils;
|
||||
private PodUtils utils;
|
||||
|
||||
public KubernetesHealthIndicator(PodUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
public KubernetesHealthIndicator(PodUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try {
|
||||
Pod current = utils.currentPod().get();
|
||||
if (current != null) {
|
||||
builder.up()
|
||||
.withDetail("inside", true)
|
||||
.withDetail("namespace", current.getMetadata().getNamespace())
|
||||
.withDetail("podName", current.getMetadata().getName())
|
||||
.withDetail("podIp", current.getStatus().getPodIP())
|
||||
.withDetail("serviceAccount", current.getSpec().getServiceAccountName())
|
||||
.withDetail("nodeName", current.getSpec().getNodeName())
|
||||
.withDetail("hostIp", current.getStatus().getHostIP());
|
||||
} else {
|
||||
builder.up()
|
||||
.withDetail("inside", false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
builder.down(e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
try {
|
||||
Pod current = utils.currentPod().get();
|
||||
if (current != null) {
|
||||
builder.up().withDetail("inside", true)
|
||||
.withDetail("namespace", current.getMetadata().getNamespace())
|
||||
.withDetail("podName", current.getMetadata().getName())
|
||||
.withDetail("podIp", current.getStatus().getPodIP())
|
||||
.withDetail("serviceAccount",
|
||||
current.getSpec().getServiceAccountName())
|
||||
.withDetail("nodeName", current.getSpec().getNodeName())
|
||||
.withDetail("hostIp", current.getStatus().getHostIP());
|
||||
}
|
||||
else {
|
||||
builder.up().withDetail("inside", false);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
builder.down(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class LazilyInstantiate<T> implements Supplier<T> {
|
||||
|
||||
public static <T> LazilyInstantiate<T> using(Supplier<T> supplier) {
|
||||
return new LazilyInstantiate<T>(supplier);
|
||||
}
|
||||
public static <T> LazilyInstantiate<T> using(Supplier<T> supplier) {
|
||||
return new LazilyInstantiate<T>(supplier);
|
||||
}
|
||||
|
||||
public synchronized T get() {
|
||||
return current.get();
|
||||
}
|
||||
public synchronized T get() {
|
||||
return current.get();
|
||||
}
|
||||
|
||||
private LazilyInstantiate(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
this.current = () -> swapper();
|
||||
}
|
||||
private LazilyInstantiate(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
this.current = () -> swapper();
|
||||
}
|
||||
|
||||
private final Supplier<T> supplier;
|
||||
private Supplier<T> current;
|
||||
private final Supplier<T> supplier;
|
||||
private Supplier<T> current;
|
||||
|
||||
private T swapper() {
|
||||
T obj = supplier.get();
|
||||
current = () -> obj;
|
||||
return obj;
|
||||
}
|
||||
private T swapper() {
|
||||
T obj = supplier.get();
|
||||
current = () -> obj;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
|
||||
public interface PodUtils {
|
||||
|
||||
/**
|
||||
* @return A supplier of the currentPod {@link Pod}. The supplier will hold the currentPod {@Pod} if inside Kubernetes
|
||||
* or false, otherwise.
|
||||
*/
|
||||
Supplier<Pod> currentPod();
|
||||
/**
|
||||
* @return A supplier of the currentPod {@link Pod}. The supplier will hold the
|
||||
* currentPod {@Pod} if inside Kubernetes or false, otherwise.
|
||||
*/
|
||||
Supplier<Pod> currentPod();
|
||||
|
||||
/**
|
||||
* @return true if called from within Kubernetes, false otherwise.
|
||||
*/
|
||||
Boolean isInsideKubernetes();
|
||||
/**
|
||||
* @return true if called from within Kubernetes, false otherwise.
|
||||
*/
|
||||
Boolean isInsideKubernetes();
|
||||
}
|
||||
|
||||
@@ -1,79 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class StandardPodUtils implements PodUtils {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(StandardPodUtils.class);
|
||||
public static final String HOSTNAME = "HOSTNAME";
|
||||
private static final Log LOG = LogFactory.getLog(StandardPodUtils.class);
|
||||
public static final String HOSTNAME = "HOSTNAME";
|
||||
|
||||
private final KubernetesClient client;
|
||||
private final String hostName;
|
||||
private Supplier<Pod> current;
|
||||
private final KubernetesClient client;
|
||||
private final String hostName;
|
||||
private Supplier<Pod> current;
|
||||
|
||||
public StandardPodUtils(KubernetesClient client) {
|
||||
if (client == null) {
|
||||
throw new IllegalArgumentException("Must provide an instance of KubernetesClient");
|
||||
}
|
||||
public StandardPodUtils(KubernetesClient client) {
|
||||
if (client == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must provide an instance of KubernetesClient");
|
||||
}
|
||||
|
||||
this.client = client;
|
||||
this.hostName = System.getenv(HOSTNAME);
|
||||
this.current = LazilyInstantiate.using(() -> internalGetPod());
|
||||
}
|
||||
this.client = client;
|
||||
this.hostName = System.getenv(HOSTNAME);
|
||||
this.current = LazilyInstantiate.using(() -> internalGetPod());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Pod> currentPod() {
|
||||
return current;
|
||||
}
|
||||
@Override
|
||||
public Supplier<Pod> currentPod() {
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isInsideKubernetes() {
|
||||
return currentPod().get() != null;
|
||||
}
|
||||
@Override
|
||||
public Boolean isInsideKubernetes() {
|
||||
return currentPod().get() != null;
|
||||
}
|
||||
|
||||
private synchronized Pod internalGetPod() {
|
||||
try {
|
||||
if (isServiceAccountFound() && isHostNameEnvVarPresent()) {
|
||||
return client.pods().withName(hostName).get();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOG.warn("Failed to get pod with name:[" + hostName + "]. You should look into this if things aren't working as you expect. Are you missing serviceaccount permissions?", t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private synchronized Pod internalGetPod() {
|
||||
try {
|
||||
if (isServiceAccountFound() && isHostNameEnvVarPresent()) {
|
||||
return client.pods().withName(hostName).get();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.warn("Failed to get pod with name:[" + hostName
|
||||
+ "]. You should look into this if things aren't working as you expect. Are you missing serviceaccount permissions?",
|
||||
t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHostNameEnvVarPresent() {
|
||||
return hostName != null && !hostName.isEmpty();
|
||||
}
|
||||
private boolean isHostNameEnvVarPresent() {
|
||||
return hostName != null && !hostName.isEmpty();
|
||||
}
|
||||
|
||||
private boolean isServiceAccountFound() {
|
||||
return Paths.get(Config.KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH).toFile().exists() &&
|
||||
Paths.get(Config.KUBERNETES_SERVICE_ACCOUNT_CA_CRT_PATH).toFile().exists();
|
||||
}
|
||||
private boolean isServiceAccountFound() {
|
||||
return Paths.get(Config.KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH).toFile().exists()
|
||||
&& Paths.get(Config.KUBERNETES_SERVICE_ACCOUNT_CA_CRT_PATH).toFile()
|
||||
.exists();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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.profile;
|
||||
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
|
||||
import org.springframework.cloud.kubernetes.LazilyInstantiate;
|
||||
import org.springframework.cloud.kubernetes.StandardPodUtils;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
@@ -25,34 +28,33 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
public class KubernetesApplicationContextInitializer implements
|
||||
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
|
||||
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
|
||||
|
||||
private static final int ORDER = 100;
|
||||
private static final int ORDER = 100;
|
||||
|
||||
private final Supplier<KubernetesProfileApplicationListener> listenerSupplier;
|
||||
private final Supplier<KubernetesProfileApplicationListener> listenerSupplier;
|
||||
|
||||
public KubernetesApplicationContextInitializer() {
|
||||
this(LazilyInstantiate.using(() ->
|
||||
//If we are inside Kubernetes this should be perfectly valid.
|
||||
//If not then we won't add the Kubernetes profile anyway.
|
||||
new KubernetesProfileApplicationListener(
|
||||
new StandardPodUtils(new DefaultKubernetesClient()))
|
||||
));
|
||||
// If we are inside Kubernetes this should be perfectly valid.
|
||||
// If not then we won't add the Kubernetes profile anyway.
|
||||
new KubernetesProfileApplicationListener(
|
||||
new StandardPodUtils(new DefaultKubernetesClient()))));
|
||||
}
|
||||
|
||||
public KubernetesApplicationContextInitializer(
|
||||
Supplier<KubernetesProfileApplicationListener> listenerSupplier) {
|
||||
Supplier<KubernetesProfileApplicationListener> listenerSupplier) {
|
||||
this.listenerSupplier = listenerSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
listenerSupplier.get().addKubernetesProfile(applicationContext.getEnvironment());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,79 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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.profile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.kubernetes.PodUtils;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.cloud.kubernetes.PodUtils;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
public class KubernetesProfileApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
|
||||
public class KubernetesProfileApplicationListener
|
||||
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesProfileApplicationListener.class);
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(KubernetesProfileApplicationListener.class);
|
||||
|
||||
private static final String KUBERNETES_PROFILE = "kubernetes";
|
||||
private static final int OFFSET = 1;
|
||||
private static final int ORDER = Ordered.HIGHEST_PRECEDENCE + OFFSET;
|
||||
private final PodUtils utils;
|
||||
private static final String KUBERNETES_PROFILE = "kubernetes";
|
||||
private static final int OFFSET = 1;
|
||||
private static final int ORDER = Ordered.HIGHEST_PRECEDENCE + OFFSET;
|
||||
private final PodUtils utils;
|
||||
|
||||
public KubernetesProfileApplicationListener(PodUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
public KubernetesProfileApplicationListener(PodUtils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
ConfigurableEnvironment environment = event.getEnvironment();
|
||||
addKubernetesProfile(environment);
|
||||
}
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
ConfigurableEnvironment environment = event.getEnvironment();
|
||||
addKubernetesProfile(environment);
|
||||
}
|
||||
|
||||
void addKubernetesProfile(ConfigurableEnvironment environment) {
|
||||
if (utils.isInsideKubernetes()) {
|
||||
if (hasKubernetesProfile(environment)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("'kubernetes' already in list of active profiles");
|
||||
}
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding 'kubernetes' to list of active profiles");
|
||||
}
|
||||
environment.addActiveProfile(KUBERNETES_PROFILE);
|
||||
}
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.warn("Not running inside kubernetes. Skipping 'kubernetes' profile activation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
void addKubernetesProfile(ConfigurableEnvironment environment) {
|
||||
if (utils.isInsideKubernetes()) {
|
||||
if (hasKubernetesProfile(environment)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("'kubernetes' already in list of active profiles");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding 'kubernetes' to list of active profiles");
|
||||
}
|
||||
environment.addActiveProfile(KUBERNETES_PROFILE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.warn(
|
||||
"Not running inside kubernetes. Skipping 'kubernetes' profile activation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasKubernetesProfile(Environment environment) {
|
||||
for (String activeProfile : environment.getActiveProfiles()) {
|
||||
if (KUBERNETES_PROFILE.equalsIgnoreCase(activeProfile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private boolean hasKubernetesProfile(Environment environment) {
|
||||
for (String activeProfile : environment.getActiveProfiles()) {
|
||||
if (KUBERNETES_PROFILE.equalsIgnoreCase(activeProfile)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -19,11 +20,11 @@ import org.junit.Test;
|
||||
|
||||
public class StandardPodUtilsTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorThrowsIllegalArgumentExceptionWhenKubeClientNull() {
|
||||
// expect an IllegalArgumentException if KubernetesClient argument is
|
||||
// null
|
||||
new StandardPodUtils(null);
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorThrowsIllegalArgumentExceptionWhenKubeClientNull() {
|
||||
// expect an IllegalArgumentException if KubernetesClient argument is
|
||||
// null
|
||||
new StandardPodUtils(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.profile;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.registry;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.registry;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.registry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.api.model.EndpointsBuilder
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.api.model.*;
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.examples;
|
||||
|
||||
import java.util.List;
|
||||
@@ -5,7 +22,6 @@ 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;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.examples;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -5,7 +22,6 @@ 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.*;
|
||||
@@ -14,14 +30,15 @@ import static org.assertj.core.api.Assertions.*;
|
||||
@SpringBootTest(classes = App.class)
|
||||
public class ApplicationTestIT {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
@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();
|
||||
}
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -18,7 +18,6 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -28,8 +27,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
@EnableScheduling
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -23,14 +23,14 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConfigurationProperties(prefix = "dummy")
|
||||
public class DummyConfig {
|
||||
|
||||
private String message = "this is a dummy message";
|
||||
private String message = "this is a dummy message";
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -23,17 +23,17 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class MyBean {
|
||||
|
||||
@Autowired
|
||||
private MyConfig myConfig;
|
||||
@Autowired
|
||||
private MyConfig myConfig;
|
||||
|
||||
@Autowired
|
||||
private DummyConfig dummyConfig;
|
||||
@Autowired
|
||||
private DummyConfig dummyConfig;
|
||||
|
||||
@Scheduled(fixedDelay = 5000)
|
||||
public void hello() {
|
||||
System.out.println("The first message is: " + myConfig.getMessage());
|
||||
System.out.println("The other message is: " + dummyConfig.getMessage());
|
||||
}
|
||||
@Scheduled(fixedDelay = 5000)
|
||||
public void hello() {
|
||||
System.out.println("The first message is: " + myConfig.getMessage());
|
||||
System.out.println("The other message is: " + dummyConfig.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -23,14 +23,14 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConfigurationProperties(prefix = "bean")
|
||||
public class MyConfig {
|
||||
|
||||
private String message = "a message that can be changed live";
|
||||
private String message = "a message that can be changed live";
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/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">
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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.leader;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.leader;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.leader;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.leader;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.leader;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.leader;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -30,86 +30,88 @@ import com.netflix.client.config.IClientConfigKey;
|
||||
|
||||
public abstract class KubernetesConfigKey<T> implements IClientConfigKey<T> {
|
||||
|
||||
public static final IClientConfigKey<String> Namespace = new KubernetesConfigKey<String>("KubernetesNamespace"){};
|
||||
public static final IClientConfigKey<String> PortName = new KubernetesConfigKey<String>("PortName"){};
|
||||
public static final IClientConfigKey<String> Namespace = new KubernetesConfigKey<String>("KubernetesNamespace") {
|
||||
};
|
||||
public static final IClientConfigKey<String> PortName = new KubernetesConfigKey<String>("PortName") {
|
||||
};
|
||||
|
||||
private static final Set<IClientConfigKey> keys = new HashSet<IClientConfigKey>();
|
||||
private static final Set<IClientConfigKey> keys = new HashSet<IClientConfigKey>();
|
||||
|
||||
static {
|
||||
for (Field f: KubernetesConfigKey.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers()) //&& Modifier.isPublic(f.getModifiers())
|
||||
&& IClientConfigKey.class.isAssignableFrom(f.getType())) {
|
||||
try {
|
||||
keys.add((IClientConfigKey) f.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static {
|
||||
for (Field f : KubernetesConfigKey.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers()) //&& Modifier.isPublic(f.getModifiers())
|
||||
&& IClientConfigKey.class.isAssignableFrom(f.getType())) {
|
||||
try {
|
||||
keys.add((IClientConfigKey) f.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated see {@link #keys()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static IClientConfigKey[] values() {
|
||||
return keys().toArray(new IClientConfigKey[0]);
|
||||
}
|
||||
/**
|
||||
* @deprecated see {@link #keys()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static IClientConfigKey[] values() {
|
||||
return keys().toArray(new IClientConfigKey[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* return all the public static keys defined in this class
|
||||
*/
|
||||
public static Set<IClientConfigKey> keys() {
|
||||
return keys;
|
||||
}
|
||||
/**
|
||||
* return all the public static keys defined in this class
|
||||
*/
|
||||
public static Set<IClientConfigKey> keys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public static IClientConfigKey valueOf(final String name) {
|
||||
for (IClientConfigKey key: keys()) {
|
||||
if (key.key().equals(name)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return new IClientConfigKey() {
|
||||
@Override
|
||||
public String key() {
|
||||
return name;
|
||||
}
|
||||
public static IClientConfigKey valueOf(final String name) {
|
||||
for (IClientConfigKey key : keys()) {
|
||||
if (key.key().equals(name)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return new IClientConfigKey() {
|
||||
@Override
|
||||
public String key() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class type() {
|
||||
return String.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Class type() {
|
||||
return String.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final String configKey;
|
||||
private final Class<T> type;
|
||||
private final String configKey;
|
||||
private final Class<T> type;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected KubernetesConfigKey(String configKey) {
|
||||
this.configKey = configKey;
|
||||
Type superclass = getClass().getGenericSuperclass();
|
||||
Assert.isTrue(superclass instanceof ParameterizedType,
|
||||
superclass + " isn't parameterized");
|
||||
Type runtimeType = ((ParameterizedType) superclass).getActualTypeArguments()[0];
|
||||
type = (Class<T>) Types.rawType(runtimeType);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
protected KubernetesConfigKey(String configKey) {
|
||||
this.configKey = configKey;
|
||||
Type superclass = getClass().getGenericSuperclass();
|
||||
Assert.isTrue(superclass instanceof ParameterizedType,
|
||||
superclass + " isn't parameterized");
|
||||
Type runtimeType = ((ParameterizedType) superclass).getActualTypeArguments()[0];
|
||||
type = (Class<T>) Types.rawType(runtimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> type() {
|
||||
return type;
|
||||
}
|
||||
@Override
|
||||
public Class<T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/* (non-Javadoc)
|
||||
* @see com.netflix.niws.client.ClientConfig#key()
|
||||
*/
|
||||
@Override
|
||||
public String key() {
|
||||
return configKey;
|
||||
}
|
||||
@Override
|
||||
public String key() {
|
||||
return configKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return configKey;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return configKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -20,6 +20,7 @@ package org.springframework.cloud.kubernetes.ribbon;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -27,14 +28,14 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class KubernetesRibbonClientConfiguration {
|
||||
|
||||
public KubernetesRibbonClientConfiguration() {
|
||||
}
|
||||
public KubernetesRibbonClientConfiguration() {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(KubernetesClient client, IClientConfig config) {
|
||||
KubernetesServerList serverList = new KubernetesServerList(client);
|
||||
serverList.initWithNiwsConfig(config);
|
||||
return serverList;
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(KubernetesClient client, IClientConfig config) {
|
||||
KubernetesServerList serverList = new KubernetesServerList(client);
|
||||
serverList.initWithNiwsConfig(config);
|
||||
return serverList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -17,86 +17,89 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.ribbon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.EndpointAddress;
|
||||
import io.fabric8.kubernetes.api.model.EndpointPort;
|
||||
import io.fabric8.kubernetes.api.model.EndpointSubset;
|
||||
import io.fabric8.kubernetes.api.model.Endpoints;
|
||||
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;
|
||||
|
||||
public class KubernetesServerList extends AbstractServerList<Server>
|
||||
implements ServerList<Server> {
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
private static final int FIRST = 0;
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesServerList.class);
|
||||
|
||||
public class KubernetesServerList extends AbstractServerList<Server> implements ServerList<Server> {
|
||||
private final KubernetesClient client;
|
||||
|
||||
private static final int FIRST = 0;
|
||||
private static final Log LOG = LogFactory.getLog(KubernetesServerList.class);
|
||||
private String serviceId;
|
||||
|
||||
private final KubernetesClient client;
|
||||
private String namespace;
|
||||
private String portName;
|
||||
|
||||
private String serviceId;
|
||||
public KubernetesServerList(KubernetesClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
private String namespace;
|
||||
private String portName;
|
||||
public void initWithNiwsConfig(IClientConfig clientConfig) {
|
||||
this.serviceId = clientConfig.getClientName();
|
||||
this.namespace = clientConfig.getPropertyAsString(KubernetesConfigKey.Namespace,
|
||||
client.getNamespace());
|
||||
this.portName = clientConfig.getPropertyAsString(KubernetesConfigKey.PortName,
|
||||
null);
|
||||
}
|
||||
|
||||
public List<Server> getInitialListOfServers() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public KubernetesServerList(KubernetesClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
Endpoints endpoints = namespace != null
|
||||
? client.endpoints().inNamespace(namespace).withName(serviceId).get()
|
||||
: client.endpoints().withName(serviceId).get();
|
||||
|
||||
public void initWithNiwsConfig(IClientConfig clientConfig) {
|
||||
this.serviceId = clientConfig.getClientName();
|
||||
this.namespace = clientConfig.getPropertyAsString(KubernetesConfigKey.Namespace, client.getNamespace());
|
||||
this.portName = clientConfig.getPropertyAsString(KubernetesConfigKey.PortName, null);
|
||||
}
|
||||
List<Server> result = new ArrayList<Server>();
|
||||
if (endpoints != null) {
|
||||
|
||||
public List<Server> getInitialListOfServers() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Found [" + endpoints.getSubsets().size()
|
||||
+ "] endpoints in namespace [" + namespace + "] for name ["
|
||||
+ serviceId + "] and portName [" + portName + "]");
|
||||
}
|
||||
for (EndpointSubset subset : endpoints.getSubsets()) {
|
||||
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
Endpoints endpoints = namespace != null
|
||||
? client.endpoints().inNamespace(namespace).withName(serviceId).get()
|
||||
: client.endpoints().withName(serviceId).get();
|
||||
|
||||
List<Server> result = new ArrayList<Server>();
|
||||
if (endpoints != null) {
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Found [" + endpoints.getSubsets().size() + "] endpoints in namespace [" +
|
||||
namespace + "] for name [" + serviceId + "] and portName [" + portName + "]");
|
||||
}
|
||||
for (EndpointSubset subset : endpoints.getSubsets()) {
|
||||
|
||||
if (subset.getPorts().size() == 1) {
|
||||
EndpointPort port = subset.getPorts().get(FIRST);
|
||||
for (EndpointAddress address : subset.getAddresses()) {
|
||||
result.add(new Server(address.getIp(), port.getPort()));
|
||||
}
|
||||
} else {
|
||||
for (EndpointPort port : subset.getPorts()) {
|
||||
if (Utils.isNullOrEmpty(portName) || portName.endsWith(port.getName())) {
|
||||
for (EndpointAddress address : subset.getAddresses()) {
|
||||
result.add(new Server(address.getIp(), port.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Did not find any endpoints in ribbon in namespace [" + namespace + "] for name [" +
|
||||
serviceId + "] and portName [" + portName + "]");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (subset.getPorts().size() == 1) {
|
||||
EndpointPort port = subset.getPorts().get(FIRST);
|
||||
for (EndpointAddress address : subset.getAddresses()) {
|
||||
result.add(new Server(address.getIp(), port.getPort()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (EndpointPort port : subset.getPorts()) {
|
||||
if (Utils.isNullOrEmpty(portName)
|
||||
|| portName.endsWith(port.getName())) {
|
||||
for (EndpointAddress address : subset.getAddresses()) {
|
||||
result.add(new Server(address.getIp(), port.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.warn("Did not find any endpoints in ribbon in namespace [" + namespace
|
||||
+ "] for name [" + serviceId + "] and portName [" + portName + "]");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,36 +1,55 @@
|
||||
package org.springframework.cloud.kubernetes.ribbon;
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.ribbon;
|
||||
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Set;
|
||||
|
||||
final class Types {
|
||||
|
||||
private Types() {
|
||||
//Utlity
|
||||
}
|
||||
private Types() {
|
||||
// Utlity
|
||||
}
|
||||
|
||||
static Class rawType(Type type) {
|
||||
if (type instanceof Class) {
|
||||
return (Class) type;
|
||||
} else if (type instanceof TypeVariable) {
|
||||
return rawType(firstOrObject(((TypeVariable) type).getBounds()));
|
||||
} else if (type instanceof WildcardType) {
|
||||
return rawType(firstOrObject(((WildcardType) type).getUpperBounds()));
|
||||
} else if (type instanceof GenericArrayType) {
|
||||
return rawType(((GenericArrayType) type).getGenericComponentType());
|
||||
}
|
||||
return Object.class;
|
||||
}
|
||||
static Class rawType(Type type) {
|
||||
if (type instanceof Class) {
|
||||
return (Class) type;
|
||||
}
|
||||
else if (type instanceof TypeVariable) {
|
||||
return rawType(firstOrObject(((TypeVariable) type).getBounds()));
|
||||
}
|
||||
else if (type instanceof WildcardType) {
|
||||
return rawType(firstOrObject(((WildcardType) type).getUpperBounds()));
|
||||
}
|
||||
else if (type instanceof GenericArrayType) {
|
||||
return rawType(((GenericArrayType) type).getGenericComponentType());
|
||||
}
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
private static Type firstOrObject(Type[] types) {
|
||||
if (types.length > 0) {
|
||||
return rawType(types[0]);
|
||||
} else {
|
||||
return Void.class;
|
||||
}
|
||||
}
|
||||
private static Type firstOrObject(Type[] types) {
|
||||
if (types.length > 0) {
|
||||
return rawType(types[0]);
|
||||
}
|
||||
else {
|
||||
return Void.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
|
||||
@@ -1,27 +1,47 @@
|
||||
package org.springframework.cloud.kubernetes.ribbon;
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.ribbon;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class KubernetesConfigKeyTest {
|
||||
|
||||
private class TypeOne<T> {}
|
||||
private class TypeOne<T> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public <T extends TypeOne, I> void testTypes() {
|
||||
//with class
|
||||
KubernetesConfigKey<String> key1 = new KubernetesConfigKey<String>("key1"){};
|
||||
@Test
|
||||
public <T extends TypeOne, I> void testTypes() {
|
||||
// with class
|
||||
KubernetesConfigKey<String> key1 = new KubernetesConfigKey<String>("key1") {
|
||||
};
|
||||
|
||||
//with type variable
|
||||
KubernetesConfigKey<T> key2 = new KubernetesConfigKey<T>("key2"){};
|
||||
// with type variable
|
||||
KubernetesConfigKey<T> key2 = new KubernetesConfigKey<T>("key2") {
|
||||
};
|
||||
|
||||
//with type variable with no bounds
|
||||
KubernetesConfigKey<I> key3 = new KubernetesConfigKey<I>("key3"){};
|
||||
// with type variable with no bounds
|
||||
KubernetesConfigKey<I> key3 = new KubernetesConfigKey<I>("key3") {
|
||||
};
|
||||
|
||||
Assert.assertEquals(String.class, key1.type());
|
||||
Assert.assertEquals(TypeOne.class, key2.type());
|
||||
Assert.assertEquals(Object.class, key3.type());
|
||||
}
|
||||
Assert.assertEquals(String.class, key1.type());
|
||||
Assert.assertEquals(TypeOne.class, key2.type());
|
||||
Assert.assertEquals(Object.class, key3.type());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -30,6 +30,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -44,12 +45,11 @@ import static org.junit.Assert.fail;
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = TestApplication.class,
|
||||
properties = {
|
||||
"spring.application.name=testapp",
|
||||
"spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true",
|
||||
"spring.cloud.kubernetes.config.namespace=testns"})
|
||||
@SpringBootTest(classes = TestApplication.class, properties = {
|
||||
"spring.application.name=testapp",
|
||||
"spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true",
|
||||
"spring.cloud.kubernetes.config.namespace=testns" })
|
||||
@EnableAutoConfiguration
|
||||
@EnableDiscoveryClient
|
||||
public class RibbonFallbackTest {
|
||||
@@ -76,11 +76,13 @@ public class RibbonFallbackTest {
|
||||
public static void setUpBefore() throws Exception {
|
||||
mockClient = mockServer.getClient();
|
||||
|
||||
//Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
|
||||
mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
|
||||
"false");
|
||||
|
||||
mockEndpoint = new DefaultMockServer(false);
|
||||
mockEndpoint.start();
|
||||
@@ -89,28 +91,27 @@ public class RibbonFallbackTest {
|
||||
@Test
|
||||
public void testFallBackGreetingEndpoint() {
|
||||
/**
|
||||
* Scenario tested
|
||||
* 1. Register the mock endpoint of the service into KubeMockServer and call /greeting service
|
||||
* 2. Unregister the mock endpoint and verify that Ribbon doesn't have any instances anymore in its list
|
||||
* 3. Re register the mock endpoint and play step 1)
|
||||
* Scenario tested 1. Register the mock endpoint of the service into
|
||||
* KubeMockServer and call /greeting service 2. Unregister the mock endpoint and
|
||||
* verify that Ribbon doesn't have any instances anymore in its list 3. Re
|
||||
* register the mock endpoint and play step 1)
|
||||
**/
|
||||
|
||||
LOG.info(">>>>>>>>>> BEGIN PART 1 <<<<<<<<<<<<<");
|
||||
|
||||
// As Ribbon refreshes its list every serverListRefreshInterval ms,
|
||||
// we configure the API Server endpoint to reply to exactly serviceOccurrence attempts
|
||||
// we configure the API Server endpoint to reply to exactly serviceOccurrence
|
||||
// attempts
|
||||
// to be sure that Ribbon will get the mockendpoint to access it for the call
|
||||
mockServer.expect().get()
|
||||
.withPath("/api/v1/namespaces/testns/endpoints/testapp")
|
||||
.andReturn(200, newEndpoint("testapp-a","testns", mockEndpoint))
|
||||
.times(serviceOccurrence);
|
||||
mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp")
|
||||
.andReturn(200, newEndpoint("testapp-a", "testns", mockEndpoint))
|
||||
.times(serviceOccurrence);
|
||||
|
||||
mockEndpoint.expect().get()
|
||||
.withPath("/greeting")
|
||||
.andReturn(200, "Hello from A")
|
||||
.once();
|
||||
mockEndpoint.expect().get().withPath("/greeting").andReturn(200, "Hello from A")
|
||||
.once();
|
||||
|
||||
String response = restTemplate.getForObject("http://testapp/greeting", String.class);
|
||||
String response = restTemplate.getForObject("http://testapp/greeting",
|
||||
String.class);
|
||||
Assert.assertEquals("Hello from A", response);
|
||||
LOG.info(">>>>>>>>>> END PART 1 <<<<<<<<<<<<<");
|
||||
|
||||
@@ -118,53 +119,66 @@ public class RibbonFallbackTest {
|
||||
try {
|
||||
ensureEndpointsNoLongerReturnedByAPIServer();
|
||||
restTemplate.getForObject("http://testapp/greeting", String.class);
|
||||
fail("Ribbon was supposed to throw an Exception due to not knowing of any endpoints to route the request to");
|
||||
} catch (Exception e) {
|
||||
fail("Ribbon was supposed to throw an Exception due to not knowing of any endpoints to route the request to");
|
||||
}
|
||||
catch (Exception e) {
|
||||
// No endpoint is available anymore and Ribbon list is empty
|
||||
Assert.assertEquals("No instances available for testapp", e.getMessage());
|
||||
}
|
||||
LOG.info(">>>>>>>>>> END PART 2 <<<<<<<<<<<<<");
|
||||
|
||||
LOG.info(">>>>>>>>>> BEGIN PART 3 <<<<<<<<<<<<<");
|
||||
mockServer.expect().get()
|
||||
.withPath("/api/v1/namespaces/testns/endpoints/testapp")
|
||||
.andReturn(200, newEndpoint("testapp-a","testns", mockEndpoint))
|
||||
.always();
|
||||
mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp")
|
||||
.andReturn(200, newEndpoint("testapp-a", "testns", mockEndpoint))
|
||||
.always();
|
||||
|
||||
// the purpose of sleeping here is to make sure that even after some refreshes to it's list
|
||||
// the purpose of sleeping here is to make sure that even after some refreshes to
|
||||
// it's list
|
||||
// Ribbon still has endpoints to route to
|
||||
// This is different than the first part of the test because the API server has now been
|
||||
// configured to always respond with some endpoints as opposed to only a certain amount of
|
||||
// This is different than the first part of the test because the API server has
|
||||
// now been
|
||||
// configured to always respond with some endpoints as opposed to only a certain
|
||||
// amount of
|
||||
// requests which was the case in part 1
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch(InterruptedException ex) {
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
mockEndpoint.expect().get().withPath("/greeting").andReturn(200, "Hello from A").once();
|
||||
mockEndpoint.expect().get().withPath("/greeting").andReturn(200, "Hello from A")
|
||||
.once();
|
||||
response = restTemplate.getForObject("http://testapp/greeting", String.class);
|
||||
Assert.assertEquals("Hello from A",response);
|
||||
Assert.assertEquals("Hello from A", response);
|
||||
LOG.info(">>>>>>>>>> END PART 3 <<<<<<<<<<<<<");
|
||||
}
|
||||
|
||||
// This works because the (mock) API server is configured to return the endpoints exactly
|
||||
// serviceOccurrence times while Ribbon refreshes it's list every serverListRefreshInterval milliseconds
|
||||
private void ensureEndpointsNoLongerReturnedByAPIServer() throws InterruptedException {
|
||||
// This works because the (mock) API server is configured to return the endpoints
|
||||
// exactly
|
||||
// serviceOccurrence times while Ribbon refreshes it's list every
|
||||
// serverListRefreshInterval milliseconds
|
||||
private void ensureEndpointsNoLongerReturnedByAPIServer()
|
||||
throws InterruptedException {
|
||||
Thread.sleep((serviceOccurrence + 1) * serverListRefreshInterval);
|
||||
}
|
||||
|
||||
public static Endpoints newEndpoint(String name, String namespace, DefaultMockServer mockServer) {
|
||||
public static Endpoints newEndpoint(String name, String namespace,
|
||||
DefaultMockServer mockServer) {
|
||||
// @formatter:off
|
||||
return new EndpointsBuilder()
|
||||
.withNewMetadata()
|
||||
.withName(name)
|
||||
.withNamespace(namespace)
|
||||
.endMetadata()
|
||||
.addNewSubset()
|
||||
.addNewAddress().withIp(mockServer.getHostName()).endAddress()
|
||||
.addNewPort("http",mockServer.getPort(),"http")
|
||||
.endSubset()
|
||||
.build();
|
||||
.withNewMetadata()
|
||||
.withName(name)
|
||||
.withNamespace(namespace)
|
||||
.endMetadata()
|
||||
.addNewSubset()
|
||||
.addNewAddress()
|
||||
.withIp(mockServer.getHostName())
|
||||
.endAddress()
|
||||
.addNewPort("http", mockServer.getPort(), "http")
|
||||
.endSubset()
|
||||
.build();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
* Copyright 2013-2018 the original author or 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
|
||||
* 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,
|
||||
@@ -28,6 +28,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -39,12 +40,11 @@ import org.springframework.web.client.RestTemplate;
|
||||
* @author Charles Moulliard
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = TestApplication.class,
|
||||
properties = {
|
||||
"spring.application.name=testapp",
|
||||
"spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true",
|
||||
"spring.cloud.kubernetes.config.namespace=testns"})
|
||||
@SpringBootTest(classes = TestApplication.class, properties = {
|
||||
"spring.application.name=testapp",
|
||||
"spring.cloud.kubernetes.client.namespace=testns",
|
||||
"spring.cloud.kubernetes.client.trustCerts=true",
|
||||
"spring.cloud.kubernetes.config.namespace=testns" })
|
||||
@EnableAutoConfiguration
|
||||
@EnableDiscoveryClient
|
||||
public class RibbonTest {
|
||||
@@ -67,36 +67,43 @@ public class RibbonTest {
|
||||
public static void setUpBefore() throws Exception {
|
||||
mockClient = server.getClient();
|
||||
|
||||
//Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
|
||||
// Configure the kubernetes master url to point to the mock server
|
||||
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
|
||||
mockClient.getConfiguration().getMasterUrl());
|
||||
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
|
||||
"false");
|
||||
|
||||
//Configured
|
||||
server.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp").andReturn(200, new EndpointsBuilder()
|
||||
.withNewMetadata()
|
||||
.withName("testapp-a")
|
||||
.endMetadata()
|
||||
.addNewSubset()
|
||||
.addNewAddress().withIp(mockEndpointA.getMockServer().getHostName()).endAddress()
|
||||
.addNewPort("http", mockEndpointA.getMockServer().getPort(), "http")
|
||||
.endSubset()
|
||||
.addNewSubset()
|
||||
.addNewAddress().withIp(mockEndpointB.getMockServer().getHostName()).endAddress()
|
||||
.addNewPort("http", mockEndpointB.getMockServer().getPort(), "http")
|
||||
.endSubset()
|
||||
.build()).always();
|
||||
// Configured
|
||||
server.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp")
|
||||
.andReturn(200,
|
||||
new EndpointsBuilder().withNewMetadata().withName("testapp-a")
|
||||
.endMetadata().addNewSubset().addNewAddress()
|
||||
.withIp(mockEndpointA.getMockServer().getHostName())
|
||||
.endAddress()
|
||||
.addNewPort("http",
|
||||
mockEndpointA.getMockServer().getPort(), "http")
|
||||
.endSubset().addNewSubset().addNewAddress()
|
||||
.withIp(mockEndpointB.getMockServer().getHostName())
|
||||
.endAddress()
|
||||
.addNewPort("http",
|
||||
mockEndpointB.getMockServer().getPort(), "http")
|
||||
.endSubset().build())
|
||||
.always();
|
||||
|
||||
mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A").always();
|
||||
mockEndpointB.expect().get().withPath("/greeting").andReturn(200, "Hello from B").always();
|
||||
mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A")
|
||||
.always();
|
||||
mockEndpointB.expect().get().withPath("/greeting").andReturn(200, "Hello from B")
|
||||
.always();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
List<String> greetings = new ArrayList<>();
|
||||
for (int i = 0; i < 2 ; i++) {
|
||||
greetings.add(restTemplate.getForObject("http://testapp/greeting", String.class));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
greetings.add(
|
||||
restTemplate.getForObject("http://testapp/greeting", String.class));
|
||||
}
|
||||
greetings.contains("Hello from A");
|
||||
greetings.contains("Hello from B");
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or 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.ribbon;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
~ Copyright 2013-2018 the original author or 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
|
||||
Reference in New Issue
Block a user