Take into account secure port settings when looking for config server
When the config server is located via discovery (spring.cloud.config.discovery.enabled=true) the discovery process should attempt to establish whether the config server prefers to be accessed securely (e.g. it registered with Eureka as nonSecurePortEnabled=false). This change ensures that this happens. Fixes gh-450
This commit is contained in:
@@ -16,9 +16,12 @@
|
||||
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
|
||||
@@ -39,8 +42,8 @@ import com.netflix.discovery.DiscoveryManager;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config server via
|
||||
* discovery.
|
||||
* Bootstrap configuration for a config client that wants to lookup the config
|
||||
* server via discovery.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -50,23 +53,25 @@ import lombok.extern.apachecommons.CommonsLog;
|
||||
@EnableDiscoveryClient
|
||||
@Import(EurekaClientAutoConfiguration.class)
|
||||
@CommonsLog
|
||||
public class DiscoveryClientConfigServiceBootstrapConfiguration implements
|
||||
SmartApplicationListener {
|
||||
public class DiscoveryClientConfigServiceBootstrapConfiguration implements SmartApplicationListener {
|
||||
|
||||
private HeartbeatMonitor monitor = new HeartbeatMonitor();
|
||||
|
||||
@Autowired
|
||||
private ConfigClientProperties config;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.client.discovery.DiscoveryClient client;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent && ((ContextRefreshedEvent) event).getApplicationContext()==context) {
|
||||
if (event instanceof ContextRefreshedEvent
|
||||
&& ((ContextRefreshedEvent) event).getApplicationContext() == context) {
|
||||
refresh();
|
||||
}
|
||||
else if (event instanceof HeartbeatEvent) {
|
||||
} else if (event instanceof HeartbeatEvent) {
|
||||
if (this.monitor.update(((HeartbeatEvent) event).getValue())) {
|
||||
refresh();
|
||||
}
|
||||
@@ -92,12 +97,9 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
|
||||
private void refresh() {
|
||||
try {
|
||||
log.info("Locating configserver via discovery");
|
||||
InstanceInfo server = DiscoveryManager
|
||||
.getInstance()
|
||||
.getDiscoveryClient()
|
||||
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(),
|
||||
false);
|
||||
String url = server.getHomePageUrl();
|
||||
InstanceInfo server = DiscoveryManager.getInstance().getDiscoveryClient()
|
||||
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(), false);
|
||||
String url = getHomePage(server);
|
||||
if (server.getMetadata().containsKey("password")) {
|
||||
String user = server.getMetadata().get("user");
|
||||
user = user == null ? "user" : user;
|
||||
@@ -113,10 +115,17 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
|
||||
url = url + path;
|
||||
}
|
||||
this.config.setUri(url);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
log.warn("Could not locate configserver via discovery", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String getHomePage(InstanceInfo server) {
|
||||
List<ServiceInstance> instances = client.getInstances(this.config.getDiscovery().getServiceId());
|
||||
if (instances==null || instances.isEmpty()) {
|
||||
return server.getHomePageUrl();
|
||||
}
|
||||
return instances.get(0).getUri().toString() + "/";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,8 +110,8 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
// assume if unsecure is enabled, that is the default
|
||||
if (this.instance.isPortEnabled(UNSECURE) || !this.instance.isPortEnabled(SECURE)) {
|
||||
// assume if secure is enabled, that is the default
|
||||
if (!this.instance.isPortEnabled(SECURE)) {
|
||||
return this.instance.getPort();
|
||||
}
|
||||
return this.instance.getSecurePort();
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.config.client.ConfigClientProperties;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -61,20 +62,18 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.willReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(
|
||||
1,
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceAutoConfiguration.class).length);
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceAutoConfiguration.class).length);
|
||||
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
Mockito.verify(this.client).shutdown();
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getRawUri());
|
||||
assertEquals("bar", ApplicationInfoManager.getInstance().getInfo().getMetadata()
|
||||
.get("foo"));
|
||||
assertEquals("bar",
|
||||
ApplicationInfoManager.getInstance().getInfo().getMetadata().get("foo"));
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
@@ -89,7 +88,9 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
|
||||
parent.refresh();
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.setParent(parent);
|
||||
this.context.register(DiscoveryClientConfigServiceAutoConfiguration.class);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceAutoConfiguration.class,
|
||||
EurekaClientAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
DiscoveryManager.getInstance().setDiscoveryClient(this.client);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,15 @@ import org.springframework.cloud.config.client.ConfigClientProperties;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.InstanceInfo.PortType;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.DiscoveryManager;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -55,32 +58,45 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class);
|
||||
assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(
|
||||
0,
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
assertEquals(0, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.willReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(
|
||||
1,
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getRawUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureWhenRequested() throws Exception {
|
||||
info = InstanceInfo.Builder.newBuilder().setAppName("app").setHostName("foo")
|
||||
.setHomePageUrl("/", null).enablePort(PortType.SECURE, true).setSecurePort(443).build();
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.willReturn(this.info);
|
||||
given(this.client.getInstancesByVipAddress("CONFIGSERVER", false))
|
||||
.willReturn(Arrays.asList(info));
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("https://foo:443/", locator.getRawUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsPasssword() throws Exception {
|
||||
this.info.getMetadata().put("password", "bar");
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.willReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
@@ -92,8 +108,8 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
@Test
|
||||
public void setsPath() throws Exception {
|
||||
this.info.getMetadata().put("configPath", "/bar");
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.willReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
@@ -103,8 +119,8 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
private void setup(String... env) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
"mockDiscoveryClient", this.client);
|
||||
this.context.getDefaultListableBeanFactory()
|
||||
.registerSingleton("mockDiscoveryClient", this.client);
|
||||
DiscoveryManager.getInstance().setDiscoveryClient(this.client);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class,
|
||||
|
||||
Reference in New Issue
Block a user