diff --git a/pom.xml b/pom.xml index 0172ce15..e6d819a0 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,11 @@ spring-cloud-config-client 1.0.0.BUILD-SNAPSHOT + + org.springframework.cloud + spring-cloud-config-server + 1.0.0.BUILD-SNAPSHOT + org.springframework.cloud spring-cloud-netflix-core diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml index 0bca3bba..1f932025 100644 --- a/spring-cloud-netflix-core/pom.xml +++ b/spring-cloud-netflix-core/pom.xml @@ -29,6 +29,11 @@ spring-cloud-config-client true + + org.springframework.cloud + spring-cloud-config-server + true + com.netflix.archaius archaius-core diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java index aabce15b..7034aa2d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java @@ -35,6 +35,9 @@ import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.DiscoveryClient; /** + * Bootstrap configuration for a config client that wants to lookup the config server via + * discovery. + * * @author Dave Syer * */ @@ -49,7 +52,7 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements @Autowired private DiscoveryClient client; - + @Autowired private ConfigClientProperties config; @@ -62,8 +65,8 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements log.info("Environment is not ConfigurableEnvironment so cannot look up configserver"); return; } - InstanceInfo server = client.getNextServerFromEureka(config.getDiscovery().getServiceId(), - false); + InstanceInfo server = client.getNextServerFromEureka(config.getDiscovery() + .getServiceId(), false); String url = server.getHomePageUrl(); if (server.getMetadata().containsKey("password")) { String user = server.getMetadata().get("user"); @@ -72,6 +75,13 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements String password = server.getMetadata().get("password"); config.setPassword(password); } + if (server.getMetadata().containsKey("configPath")) { + String path = server.getMetadata().get("configPath"); + if (url.endsWith("/") && path.startsWith("/")) { + url = url.substring(0, url.length()-1); + } + url = url + path; + } config.setUri(url); } catch (Exception e) { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java new file mode 100644 index 00000000..f5e26ba2 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2014 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.netflix.config; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.config.server.ConfigServerProperties; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import com.netflix.discovery.DiscoveryClient; + +/** + * Extra configuration for config server if it happens to be a Eureka instance. + * @author Dave Syer + * + */ +@Configuration +@EnableConfigurationProperties +@ConditionalOnClass({EurekaInstanceConfigBean.class, DiscoveryClient.class, ConfigServerProperties.class}) +public class EurekaClientConfigServerAutoConfiguration { + + @Autowired(required=false) + private EurekaInstanceConfigBean instance; + + @Autowired(required=false) + private ConfigServerProperties server; + + @PostConstruct + public void init() { + if (instance==null || server==null) { + return; + } + String prefix = server.getPrefix(); + if (StringUtils.hasText(prefix)) { + instance.getMetadataMap().put("configPath", prefix); + } + } + +} diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories index 4133727c..ea0512e6 100644 --- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories @@ -1,5 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration,\ +org.springframework.cloud.netflix.config.EurekaClientConfigServerAutoConfiguration,\ org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\ org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\ diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java index e1cb2b50..42af96b9 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java @@ -83,6 +83,16 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests { assertEquals("user", locator.getUsername()); } + @Test + public void setsPath() throws Exception { + info.getMetadata().put("configPath", "/bar"); + Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn( + info); + setup("spring.cloud.config.discovery.enabled=true"); + ConfigClientProperties locator = context.getBean(ConfigClientProperties.class); + assertEquals("http://foo:7001/bar", locator.getUri()); + } + private void setup(String... env) { context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(context, env); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java new file mode 100644 index 00000000..018cb4db --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2014 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.netflix.config; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.config.server.ConfigServerProperties; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import com.netflix.appinfo.EurekaInstanceConfig; + +/** + * @author Dave Syer + * + */ +public class EurekaClientConfigServerAutoConfigurationTests { + + private ConfigurableApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + } + + @Test + public void offByDefault() throws Exception { + context = new AnnotationConfigApplicationContext( + EurekaClientConfigServerAutoConfiguration.class); + assertEquals(0, + context.getBeanNamesForType(EurekaInstanceConfigBean.class).length); + } + + @Test + public void onWhenRequested() throws Exception { + setup("spring.cloud.config.server.prefix=/config"); + assertEquals(1, context.getBeanNamesForType(EurekaInstanceConfig.class).length); + EurekaInstanceConfig instance = context.getBean(EurekaInstanceConfig.class); + assertEquals("/config", instance.getMetadataMap().get("configPath")); + } + + private void setup(String... env) { + context = new SpringApplicationBuilder( + PropertyPlaceholderAutoConfiguration.class, + EurekaClientConfigServerAutoConfiguration.class, + ConfigServerProperties.class, EurekaInstanceConfigBean.class).web(false) + .properties(env).run(); + } + +}