From c9532406201bf7851457849a34335d8bc7b7ec39 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Thu, 29 Jun 2017 16:15:09 -0600 Subject: [PATCH 1/7] Allow Discovery HealthIndicator description to be disabled. fixes gh-223 --- .../main/asciidoc/spring-cloud-commons.adoc | 4 + .../CommonsClientAutoConfiguration.java | 7 +- .../DiscoveryClientHealthIndicator.java | 12 +- ...coveryClientHealthIndicatorProperties.java | 40 +++++++ .../DiscoveryClientHealthIndicatorTests.java | 109 ++++++++++++++++++ ...iscoveryCompositeHealthIndicatorTests.java | 27 ++--- 6 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 38fdab00..b9921306 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -317,6 +317,10 @@ Commons provides the `@EnableDiscoveryClient` annotation. This looks for impleme By default, implementations of `DiscoveryClient` will auto-register the local Spring Boot server with the remote discovery server. This can be disabled by setting `autoRegister=false` in `@EnableDiscoveryClient`. +==== Health Indicator + +Commons creates a Spring Boot `HealthIndicator` that `DiscoveryClient` implementations can participate in by implementing `DiscoveryHealthIndicator`. To disable the composite `HealthIndicator` set `spring.cloud.discovery.client.composite-indicator.enabled=false`. A generic `HealthIndicator` based on `DiscoveryClient` is auto-configured (`DiscoveryClientHealthIndicator). To disable it, set `spring.cloud.discovery.client.health-indicator.enabled=false`. To disable the description field of the `DiscoveryClientHealthIndicator` set `spring.cloud.discovery.client.health-indicator.include-description=false`, otherwise it can bubble up as the `description` of the rolled up `HealthIndicator`. + === ServiceRegistry Commons now provides a `ServiceRegistry` interface which provides methods like `register(Registration)` and `deregister(Registration)` which allow you to provide custom registered services. `Registration` is a marker interface. diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java index 53abf1e8..b2b346a0 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java @@ -28,10 +28,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 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.client.actuator.FeaturesEndpoint; import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicator; +import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthIndicator; import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; @@ -48,6 +50,7 @@ import org.springframework.context.annotation.Configuration; public class CommonsClientAutoConfiguration { @Configuration + @EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class) @ConditionalOnClass(HealthIndicator.class) @ConditionalOnBean(DiscoveryClient.class) @ConditionalOnProperty(value = "spring.cloud.discovery.enabled", matchIfMissing = true) @@ -55,8 +58,8 @@ public class CommonsClientAutoConfiguration { @Bean @ConditionalOnProperty(value = "spring.cloud.discovery.client.health-indicator.enabled", matchIfMissing = true) public DiscoveryClientHealthIndicator discoveryClientHealthIndicator( - DiscoveryClient discoveryClient) { - return new DiscoveryClientHealthIndicator(discoveryClient); + DiscoveryClient discoveryClient, DiscoveryClientHealthIndicatorProperties properties) { + return new DiscoveryClientHealthIndicator(discoveryClient, properties); } @Bean diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java index 0c0304ef..75ec4a2b 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java @@ -39,10 +39,17 @@ public class DiscoveryClientHealthIndicator implements DiscoveryHealthIndicator, private int order = Ordered.HIGHEST_PRECEDENCE; - private DiscoveryClient discoveryClient; + private final DiscoveryClient discoveryClient; + private final DiscoveryClientHealthIndicatorProperties properties; + @Deprecated public DiscoveryClientHealthIndicator(DiscoveryClient discoveryClient) { + this(discoveryClient, new DiscoveryClientHealthIndicatorProperties()); + } + + public DiscoveryClientHealthIndicator(DiscoveryClient discoveryClient, DiscoveryClientHealthIndicatorProperties properties) { this.discoveryClient = discoveryClient; + this.properties = properties; } @Override @@ -59,7 +66,8 @@ public class DiscoveryClientHealthIndicator implements DiscoveryHealthIndicator, if (this.discoveryInitialized.get()) { try { List services = this.discoveryClient.getServices(); - builder.status(new Status("UP", this.discoveryClient.description())) + String description = (this.properties.isIncludeDescription()) ? this.discoveryClient.description() : ""; + builder.status(new Status("UP", description)) .withDetail("services", services); } catch (Exception e) { diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java new file mode 100644 index 00000000..fed6ddf1 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java @@ -0,0 +1,40 @@ +package org.springframework.cloud.client.discovery.health; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Spencer Gibb + */ +@ConfigurationProperties("spring.cloud.discovery.client.health-indicator") +public class DiscoveryClientHealthIndicatorProperties { + + private boolean enabled = true; + + //TODO: change to false in 2.0.0 + private boolean includeDescription = true; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isIncludeDescription() { + return includeDescription; + } + + public void setIncludeDescription(boolean includeDescription) { + this.includeDescription = includeDescription; + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("DiscoveryClientHealthIndicatorProperties{"); + sb.append("enabled=").append(enabled); + sb.append(", includeDescription=").append(includeDescription); + sb.append('}'); + return sb.toString(); + } +} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java new file mode 100644 index 00000000..5a8113af --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java @@ -0,0 +1,109 @@ +/* + * Copyright 2013-2015 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.client.discovery.health; + +import java.util.Arrays; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthAggregator; +import org.springframework.boot.actuate.health.OrderedHealthAggregator; +import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.client.CommonsClientAutoConfiguration; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * @author Spencer Gibb + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { DiscoveryClientHealthIndicatorTests.Config.class, + CommonsClientAutoConfiguration.class }, properties = "spring.cloud.discovery.client.health-indicator.include-description:false") +public class DiscoveryClientHealthIndicatorTests { + + @Autowired + private DiscoveryCompositeHealthIndicator healthIndicator; + + @Autowired + private DiscoveryClientHealthIndicator clientHealthIndicator; + + @Configuration + @EnableConfigurationProperties + public static class Config { + @Bean + public HealthAggregator healthAggregator() { + return new OrderedHealthAggregator(); + } + + @Bean + public DiscoveryClient discoveryClient() { + DiscoveryClient mock = mock(DiscoveryClient.class); + given(mock.description()).willReturn("TestDiscoveryClient"); + given(mock.getServices()).willReturn(Arrays.asList("TestService1")); + return mock; + } + + @Bean + public DiscoveryHealthIndicator discoveryHealthIndicator() { + return new DiscoveryHealthIndicator() { + @Override + public String getName() { + return "testDiscoveryHealthIndicator"; + } + + @Override + public Health health() { + return new Health.Builder().unknown().build(); + } + }; + } + } + + @Test + public void testHealthIndicatorDescriptionDisabled() { + assertNotNull("healthIndicator was null", this.healthIndicator); + Health health = this.healthIndicator.health(); + assertHealth(health, Status.UNKNOWN); + + clientHealthIndicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); + + health = this.healthIndicator.health(); + Status status = assertHealth(health, Status.UP); + assertEquals("status description was wrong", "", + status.getDescription()); + } + + private Status assertHealth(Health health, Status expected) { + assertNotNull("health was null", health); + Status status = health.getStatus(); + assertNotNull("status was null", status); + assertEquals("status code was wrong", expected.getCode(), status.getCode()); + return status; + } +} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthIndicatorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthIndicatorTests.java index b4e09988..b1eb25df 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthIndicatorTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthIndicatorTests.java @@ -16,42 +16,41 @@ package org.springframework.cloud.client.discovery.health; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - import java.util.Arrays; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthAggregator; import org.springframework.boot.actuate.health.OrderedHealthAggregator; import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.CommonsClientAutoConfiguration; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + /** * @author Spencer Gibb */ @RunWith(SpringRunner.class) -@ContextConfiguration(classes = { DiscoveryCompositeHealthIndicatorTests.Config.class, +@SpringBootTest(classes = { DiscoveryCompositeHealthIndicatorTests.Config.class, CommonsClientAutoConfiguration.class }) public class DiscoveryCompositeHealthIndicatorTests { @Autowired - DiscoveryCompositeHealthIndicator healthIndicator; + private DiscoveryCompositeHealthIndicator healthIndicator; @Autowired - DiscoveryClientHealthIndicator clientHealthIndicator; + private DiscoveryClientHealthIndicator clientHealthIndicator; @Configuration public static class Config { @@ -90,11 +89,11 @@ public class DiscoveryCompositeHealthIndicatorTests { Health health = this.healthIndicator.health(); assertHealth(health, Status.UNKNOWN); - clientHealthIndicator.onApplicationEvent(new InstanceRegisteredEvent(this, null)); + clientHealthIndicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); health = this.healthIndicator.health(); Status status = assertHealth(health, Status.UP); - assertEquals("status desciption was wrong", "TestDiscoveryClient", + assertEquals("status description was wrong", "TestDiscoveryClient", status.getDescription()); } @@ -105,9 +104,5 @@ public class DiscoveryCompositeHealthIndicatorTests { assertEquals("status code was wrong", expected.getCode(), status.getCode()); return status; } - - public static void main(String[] args) { - SpringApplication.run(new Object[]{Config.class,CommonsClientAutoConfiguration.class}, new String[] {"--debug", "--spring.main.webEnvironment=false"}); - } } From ca06452be0d1809bf9785349515d08055a2c2dd2 Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Fri, 30 Jun 2017 16:09:44 -0700 Subject: [PATCH 2/7] GH-140: Support for Composite Discovery client (#198) Add support for Composite Discovery client * Test that the default discovery client is present * Return a local Service instance from Composite Discovery Client fixes gh-140 --- .../composite/CompositeDiscoveryClient.java | 73 +++++++++++ ...ositeDiscoveryClientAutoConfiguration.java | 28 +++++ ...impleDiscoveryClientAutoConfiguration.java | 16 ++- .../main/resources/META-INF/spring.factories | 1 + ...DiscoveryClientAutoConfigurationTests.java | 79 ++++++++++++ .../CompositeDiscoveryClientTests.java | 116 ++++++++++++++++++ ...ryClientAutoConfigurationDefaultTests.java | 16 ++- ...DiscoveryClientPropertiesMappingTests.java | 3 +- ...DiscoveryClientOverridesDefaultsTests.java | 70 ----------- 9 files changed, 312 insertions(+), 90 deletions(-) create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java create mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java create mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java new file mode 100644 index 00000000..c3735f19 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java @@ -0,0 +1,73 @@ +package org.springframework.cloud.client.discovery.composite; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; + +/** + * A {@link DiscoveryClient} composed of other Discovery Client's and will delegate the + * calls to each of them in order + * + * @author Biju Kunjummen + */ +public class CompositeDiscoveryClient implements DiscoveryClient { + + private final List discoveryClients; + + public CompositeDiscoveryClient(List discoveryClients) { + this.discoveryClients = discoveryClients; + } + + @Override + public String description() { + return "Composite Discovery Client"; + } + + @Override + public ServiceInstance getLocalServiceInstance() { + if (this.discoveryClients != null) { + for (DiscoveryClient discoveryClient : discoveryClients) { + ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance(); + if (serviceInstance != null) { + return serviceInstance; + } + } + } + return null; + } + + @Override + public List getInstances(String serviceId) { + if (this.discoveryClients != null) { + for (DiscoveryClient discoveryClient : discoveryClients) { + List instances = discoveryClient.getInstances(serviceId); + if (instances != null && instances.size() > 0) { + return instances; + } + } + } + return Collections.emptyList(); + } + + @Override + public List getServices() { + LinkedHashSet services = new LinkedHashSet<>(); + if (this.discoveryClients != null) { + for (DiscoveryClient discoveryClient : discoveryClients) { + List serviceForClient = discoveryClient.getServices(); + if (serviceForClient != null) { + services.addAll(serviceForClient); + } + } + } + return new ArrayList<>(services); + } + + List getDiscoveryClients() { + return discoveryClients; + } +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java new file mode 100644 index 00000000..b71d28da --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java @@ -0,0 +1,28 @@ +package org.springframework.cloud.client.discovery.composite; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import java.util.List; + +/** + * Auto-configuration for Composite Discovery Client. + * + * @author Biju Kunjummen + */ + +@Configuration +@AutoConfigureBefore(SimpleDiscoveryClientAutoConfiguration.class) +public class CompositeDiscoveryClientAutoConfiguration { + + @Bean + @Primary + public CompositeDiscoveryClient compositeDiscoveryClient(List discoveryClients) { + return new CompositeDiscoveryClient(discoveryClients); + } + +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java index 797f632b..ef7b1ad7 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java @@ -1,23 +1,23 @@ package org.springframework.cloud.client.discovery.simple; -import java.net.URI; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; import org.springframework.cloud.commons.util.InetUtils; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.util.ClassUtils; +import java.net.URI; + /** * Spring Boot Auto-Configuration for Simple Properties based Discovery Client * @@ -25,8 +25,6 @@ import org.springframework.util.ClassUtils; */ @Configuration -@ConditionalOnMissingBean(DiscoveryClient.class) -@EnableConfigurationProperties @AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class) public class SimpleDiscoveryClientAutoConfiguration { @@ -54,9 +52,9 @@ public class SimpleDiscoveryClientAutoConfiguration { } @Bean - public DiscoveryClient simpleDiscoveryClient( - SimpleDiscoveryProperties simpleDiscoveryProperties) { - return new SimpleDiscoveryClient(simpleDiscoveryProperties); + @Order(Ordered.LOWEST_PRECEDENCE) + public DiscoveryClient simpleDiscoveryClient() { + return new SimpleDiscoveryClient(simpleDiscoveryProperties()); } private int findPort() { diff --git a/spring-cloud-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-commons/src/main/resources/META-INF/spring.factories index 4e17ff9a..874eb1fc 100644 --- a/spring-cloud-commons/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-commons/src/main/resources/META-INF/spring.factories @@ -7,6 +7,7 @@ org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\ org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\ org.springframework.cloud.commons.util.UtilAutoConfiguration,\ +org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\ org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java new file mode 100644 index 00000000..f7572297 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java @@ -0,0 +1,79 @@ +package org.springframework.cloud.client.discovery.composite; + +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; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Composite Discovery Client should be the one found by default. + * + * @author Biju Kunjummen + */ + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CompositeDiscoveryClientAutoConfigurationTests { + + @Autowired + private DiscoveryClient discoveryClient; + + @Test + public void compositeDiscoveryClientShouldBeTheDefault() { + assertThat(discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); + CompositeDiscoveryClient compositeDiscoveryClient = (CompositeDiscoveryClient) discoveryClient; + assertThat(compositeDiscoveryClient.getDiscoveryClients()).hasSize(2); + assertThat(compositeDiscoveryClient.getDiscoveryClients().get(0).description()) + .isEqualTo("A custom discovery client"); + } + + @Test + public void simpleDiscoveryClientShouldBeHaveTheLowestPrecedence() { + CompositeDiscoveryClient compositeDiscoveryClient = (CompositeDiscoveryClient) discoveryClient; + assertThat(compositeDiscoveryClient.getDiscoveryClients().get(0).description()) + .isEqualTo("A custom discovery client"); + assertThat(compositeDiscoveryClient.getDiscoveryClients().get(1)) + .isInstanceOf(SimpleDiscoveryClient.class); + } + + @EnableAutoConfiguration + @Configuration + public static class Config { + + @Bean + public DiscoveryClient customDiscoveryClient1() { + return new DiscoveryClient() { + @Override + public String description() { + return "A custom discovery client"; + } + + @Override + public ServiceInstance getLocalServiceInstance() { + return null; + } + + @Override + public List getInstances(String serviceId) { + return null; + } + + @Override + public List getServices() { + return null; + } + }; + } + } +} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java new file mode 100644 index 00000000..bb5a9f24 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java @@ -0,0 +1,116 @@ +package org.springframework.cloud.client.discovery.composite; + +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; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.test.context.junit4.SpringRunner; + +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for behavior of Composite Discovery Client + * + * @author Biju Kunjummen + */ + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { + "spring.application.name=service0", + "spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s1-1:8080", + "spring.cloud.discovery.client.simple.instances.service1[1].uri=https://s1-2:8443", + "spring.cloud.discovery.client.simple.instances.service2[0].uri=https://s2-1:8080", + "spring.cloud.discovery.client.simple.instances.service2[1].uri=https://s2-2:443" }) +public class CompositeDiscoveryClientTests { + + @Autowired + private DiscoveryClient discoveryClient; + + @Test + public void getInstancesByServiceIdShouldDelegateCall() { + assertThat(this.discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); + + assertThat(this.discoveryClient.getInstances("service1")).hasSize(2); + + ServiceInstance s1 = this.discoveryClient.getInstances("service1").get(0); + assertThat(s1.getHost()).isEqualTo("s1-1"); + assertThat(s1.getPort()).isEqualTo(8080); + assertThat(s1.getUri()).isEqualTo(URI.create("http://s1-1:8080")); + assertThat(s1.isSecure()).isEqualTo(false); + } + + @Test + public void getServicesShouldAggregateAllServiceNames() { + assertThat(this.discoveryClient.getServices()).containsOnlyOnce("service1", "service2", "custom"); + } + + @Test + public void getDescriptionShouldBeComposite() { + assertThat(this.discoveryClient.description()).isEqualTo("Composite Discovery Client"); + } + + @Test + public void getInstancesShouldRespectOrder() { + assertThat(this.discoveryClient.getInstances("custom")).hasSize(1); + assertThat(this.discoveryClient.getInstances("custom")).hasSize(1); + } + + @Test + public void getInstancesByUnknownServiceIdShouldReturnAnEmptyList() { + assertThat(this.discoveryClient.getInstances("unknown")).hasSize(0); + } + + + @Test + public void localServiceInstanceShouldReturnTheFirstMatch() { + assertThat(this.discoveryClient.getLocalServiceInstance().getServiceId()).isEqualTo("service0"); + } + + @EnableAutoConfiguration + @Configuration + public static class Config { + + @Bean + @Order(1) + public DiscoveryClient customDiscoveryClient() { + return new DiscoveryClient() { + @Override + public String description() { + return "A custom discovery client"; + } + + @Override + public ServiceInstance getLocalServiceInstance() { + return null; + } + + @Override + public List getInstances(String serviceId) { + if (serviceId.equals("custom")) { + ServiceInstance s1 = new DefaultServiceInstance("custom", "host", + 123, false); + return Arrays.asList(s1); + } + return Collections.emptyList(); + } + + @Override + public List getServices() { + return Arrays.asList("custom"); + } + }; + } + } +} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java index b62e7aca..bb6732ec 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java @@ -3,36 +3,34 @@ package org.springframework.cloud.client.discovery.simple; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * DiscoveryClient implementation defaults to {@link SimpleDiscoveryClient} + * DiscoveryClient implementation defaults to {@link CompositeDiscoveryClient} + * * @author Biju Kunjummen */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = DiscoveryClientAutoConfigurationDefaultTests.App.class) +@SpringBootTest(classes = DiscoveryClientAutoConfigurationDefaultTests.Config.class) public class DiscoveryClientAutoConfigurationDefaultTests { @Autowired - DiscoveryClient discoveryClient; + private DiscoveryClient discoveryClient; @Test public void simpleDiscoveryClientShouldBeTheDefault() { - assertThat(discoveryClient).isInstanceOf(SimpleDiscoveryClient.class); + assertThat(discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); } @EnableAutoConfiguration @Configuration - public static class App { - public static void main(String[] args) { - SpringApplication.run(App.class, args); - } + public static class Config { } } diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java index b1095976..56435d5a 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java @@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; @@ -32,7 +31,7 @@ public class SimpleDiscoveryClientPropertiesMappingTests { private SimpleDiscoveryProperties props; @Autowired - private DiscoveryClient discoveryClient; + private SimpleDiscoveryClient discoveryClient; @Test public void propsShouldGetCleanlyMapped() { diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java deleted file mode 100644 index 04672f17..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.springframework.cloud.client.discovery.simple; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = UserDefinedDiscoveryClientOverridesDefaultsTests.App.class) -public class UserDefinedDiscoveryClientOverridesDefaultsTests { - - @Autowired - DiscoveryClient discoveryClient; - - @Test - public void testDiscoveryClientIsNotNoop() { - assertThat(discoveryClient).isNotInstanceOf(SimpleDiscoveryClient.class); - - assertThat(discoveryClient.description()) - .isEqualTo("user defined discovery client"); - } - - @EnableAutoConfiguration - @Configuration - public static class App { - - @Bean - public DiscoveryClient discoveryClient() { - return new DiscoveryClient() { - @Override - public String description() { - return "user defined discovery client"; - } - - @Override - public ServiceInstance getLocalServiceInstance() { - return null; - } - - @Override - public List getInstances(String serviceId) { - return null; - } - - @Override - public List getServices() { - return null; - } - }; - } - - public static void main(String[] args) { - SpringApplication.run(App.class, args); - } - } -} From 2b6ad4a118d3ab7f800f0b32243e76e91405ff98 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 30 Jun 2017 17:19:48 -0600 Subject: [PATCH 3/7] bump to version 1.3.0 --- docs/pom.xml | 2 +- pom.xml | 2 +- spring-cloud-commons-dependencies/pom.xml | 2 +- spring-cloud-commons/pom.xml | 2 +- spring-cloud-context/pom.xml | 2 +- spring-cloud-starter/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 8884557e..d374b05a 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT pom Spring Cloud Commons Docs diff --git a/pom.xml b/pom.xml index b0f3d5e1..cb241b2d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.springframework.cloud spring-cloud-commons-parent - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT pom Spring Cloud Commons Parent Spring Cloud Commons Parent diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml index d02ee3ca..d5e0a5a9 100644 --- a/spring-cloud-commons-dependencies/pom.xml +++ b/spring-cloud-commons-dependencies/pom.xml @@ -9,7 +9,7 @@ spring-cloud-commons-dependencies - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT pom spring-cloud-commons-dependencies Spring Cloud Commons Dependencies diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml index 7b120d36..93c07f14 100644 --- a/spring-cloud-commons/pom.xml +++ b/spring-cloud-commons/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT .. spring-cloud-commons diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml index aad2dc1c..d394d0a1 100644 --- a/spring-cloud-context/pom.xml +++ b/spring-cloud-context/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT .. spring-cloud-context diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml index ad11a0f1..2d10fc41 100644 --- a/spring-cloud-starter/pom.xml +++ b/spring-cloud-starter/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT spring-cloud-starter spring-cloud-starter From 2e81db24cf255620a1057074d72cf3964faf7eef Mon Sep 17 00:00:00 2001 From: Fabio Matos Date: Sat, 1 Jul 2017 01:38:03 +0200 Subject: [PATCH 4/7] Disables endpoint creation (#208) Fixes gh-117 --- ...LifecycleMvcEndpointAutoConfiguration.java | 14 +- .../RefreshEndpointAutoConfiguration.java | 37 ++-- .../context/restart/RestartEndpoint.java | 4 +- .../LifecycleMvcAutoConfigurationTests.java | 205 ++++++++++++------ ...efreshAutoConfigurationClassPathTests.java | 5 +- .../RefreshAutoConfigurationTests.java | 3 +- 6 files changed, 170 insertions(+), 98 deletions(-) diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java index 39af35d4..456b465e 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java @@ -15,7 +15,7 @@ */ package org.springframework.cloud.autoconfigure; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -42,19 +42,14 @@ import org.springframework.context.annotation.Configuration; * */ @Configuration -@ConditionalOnClass(EnvironmentEndpoint.class) @ConditionalOnWebApplication -@ConditionalOnBean(RestartEndpoint.class) @AutoConfigureAfter({ WebMvcAutoConfiguration.class, RefreshEndpointAutoConfiguration.class }) public class LifecycleMvcEndpointAutoConfiguration { - @Autowired - private RestartEndpoint restartEndpoint; - @Bean @ConditionalOnBean(EnvironmentEndpoint.class) - @ConditionalOnProperty(value = "endpoints.env.post.enabled", matchIfMissing = true) + @ConditionalOnEnabledEndpoint(value = "env.post") public EnvironmentManagerMvcEndpoint environmentManagerEndpoint( EnvironmentEndpoint delegate, EnvironmentManager environment) { return new EnvironmentManagerMvcEndpoint(delegate, environment); @@ -67,8 +62,9 @@ public class LifecycleMvcEndpointAutoConfiguration { } @Bean - public RestartMvcEndpoint restartMvcEndpoint() { - return new RestartMvcEndpoint(this.restartEndpoint); + @ConditionalOnBean(RestartEndpoint.class) + public RestartMvcEndpoint restartMvcEndpoint(RestartEndpoint restartEndpoint) { + return new RestartMvcEndpoint(restartEndpoint); } @Bean diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java index 38fb06ce..1614e968 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java @@ -19,6 +19,7 @@ package org.springframework.cloud.autoconfigure; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -26,7 +27,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration; import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; import org.springframework.cloud.context.refresh.ContextRefresher; @@ -57,6 +57,7 @@ public class RefreshEndpointAutoConfiguration { } @ConditionalOnClass(IntegrationMBeanExporter.class) + @ConditionalOnEnabledEndpoint(value = "restart", enabledByDefault = false) protected static class RestartEndpointWithIntegration { @Autowired(required = false) @@ -75,30 +76,38 @@ public class RefreshEndpointAutoConfiguration { } @ConditionalOnMissingClass("org.springframework.integration.monitor.IntegrationMBeanExporter") + @ConditionalOnEnabledEndpoint(value = "restart", enabledByDefault = false) protected static class RestartEndpointWithoutIntegration { @Bean @ConditionalOnMissingBean - public RestartEndpoint restartEndpoint() { + public RestartEndpoint restartEndpointWithoutIntegration() { return new RestartEndpoint(); } + } - @Bean - @ConfigurationProperties("endpoints.pause") - public RestartEndpoint.PauseEndpoint pauseEndpoint(RestartEndpoint restartEndpoint) { - return restartEndpoint.getPauseEndpoint(); - } + @ConditionalOnEnabledEndpoint(value = "restart", enabledByDefault = false) + protected static class PauseResumeEndpoints { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnEnabledEndpoint("pause") + public RestartEndpoint.PauseEndpoint pauseEndpoint(RestartEndpoint restartEndpoint) { + return restartEndpoint.getPauseEndpoint(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnEnabledEndpoint("resume") + public RestartEndpoint.ResumeEndpoint resumeEndpoint(RestartEndpoint restartEndpoint) { + return restartEndpoint.getResumeEndpoint(); + } - @Bean - @ConfigurationProperties("endpoints.resume") - public RestartEndpoint.ResumeEndpoint resumeEndpoint( - RestartEndpoint restartEndpoint) { - return restartEndpoint.getResumeEndpoint(); } @Configuration - @ConditionalOnProperty(value = "endpoints.refresh.enabled", matchIfMissing = true) + @ConditionalOnEnabledEndpoint("refresh") @ConditionalOnBean(PropertySourceBootstrapConfiguration.class) protected static class RefreshEndpointConfiguration { @@ -110,4 +119,4 @@ public class RefreshEndpointAutoConfiguration { } } -} \ No newline at end of file +} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java index 70bb0616..4454c788 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java @@ -114,7 +114,7 @@ public class RestartEndpoint extends AbstractEndpoint return new ResumeEndpoint(); } - @ConfigurationProperties("endpoints") + @ConfigurationProperties("endpoints.pause") public class PauseEndpoint extends AbstractEndpoint { public PauseEndpoint() { @@ -131,7 +131,7 @@ public class RestartEndpoint extends AbstractEndpoint } } - @ConfigurationProperties("endpoints") + @ConfigurationProperties("endpoints.resume") public class ResumeEndpoint extends AbstractEndpoint { public ResumeEndpoint() { diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java index e69183a5..270512f4 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java @@ -1,88 +1,157 @@ package org.springframework.cloud.autoconfigure; +import org.assertj.core.util.Lists; +import org.junit.Test; +import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.ResponseEntity; + +import java.util.List; + import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; -import org.junit.Test; - -import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - /** * @author Spencer Gibb */ public class LifecycleMvcAutoConfigurationTests { - @Test - public void postEnvMvcEndpointDisabled() { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, - "server.port=0", "endpoints.env.post.enabled=false")) { - assertThat(context - .getBeanNamesForType(EnvironmentManagerMvcEndpoint.class).length, - is(equalTo(0))); - } - } + // postEnvMvcEndpoint + @Test + public void postEnvMvcEndpointDisabled() { + beanNotCreated("environmentManagerEndpoint", + "endpoints.env.post.enabled=false"); + } - @Test - public void pauseMvcEndpointDisabled() { - endpointDisabled("endpoints.pause.enabled", "pauseMvcEndpoint"); - } + @Test + public void postEnvMvcEndpointGloballyDisabled() { + beanNotCreated("environmentManagerEndpoint", + "endpoints.enabled=false"); + } - @Test - public void resumeMvcEndpointDisabled() { - endpointDisabled("endpoints.resume.enabled", "resumeMvcEndpoint"); - } + @Test + public void postEnvMvcEndpointEnabled() { + beanCreated("environmentManagerEndpoint", + "endpoints.env.post.enabled=true"); + } - @Test - public void restartMvcEndpointDisabled() { - endpointDisabled("endpoints.restart.enabled", "restartMvcEndpoint"); - } - - @Test - public void pauseMvcEndpointGloballyDisabled() { - endpointDisabled("endpoints.enabled", "pauseMvcEndpoint"); - } - - @Test - public void resumeMvcEndpointGloballyDisabled() { - endpointDisabled("endpoints.enabled", "resumeMvcEndpoint"); - } - - @Test - public void restartMvcEndpointGloballyDisabled() { - endpointDisabled("endpoints.enabled", "restartMvcEndpoint"); - } + // restartMvcEndpoint + @Test + public void restartMvcEndpointDisabled() { + beanNotCreated("restartMvcEndpoint", + "endpoints.restart.enabled=false"); + } - private void endpointDisabled(String enabledProp, String beanName) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, - "server.port=0", enabledProp + "=false")) { - EndpointMvcAdapter endpoint = context.getBean(beanName, - EndpointMvcAdapter.class); - Object result = endpoint.invoke(); - assertThat("result is wrong type", result, - is(instanceOf(ResponseEntity.class))); - ResponseEntity response = (ResponseEntity) result; - assertThat("response code was wrong", response.getStatusCode(), - equalTo(HttpStatus.NOT_FOUND)); - } - } + @Test + public void restartMvcEndpointGloballyDisabled() { + beanNotCreated("restartMvcEndpoint", + "endpoints.enabled=false"); + } - private static ConfigurableApplicationContext getApplicationContext( - Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).properties(properties).run(); - } + @Test + public void restartMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("restartMvcEndpoint", + "endpoints.restart.enabled=true"); + } - @Configuration - @EnableAutoConfiguration - static class Config { + // pauseMvcEndpoint + @Test + public void pauseMvcEndpointDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.pause.enabled=false"); + } - } + @Test + public void pauseMvcEndpointRestartDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.restart.enabled=false", + "endpoints.pause.enabled=true"); + } + + @Test + public void pauseMvcEndpointGloballyDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.enabled=false"); + } + + @Test + public void pauseMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("pauseMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.pause.enabled=true"); + } + + // resumeMvcEndpoint + @Test + public void resumeMvcEndpointDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.resume.enabled=false"); + } + + @Test + public void resumeMvcEndpointRestartDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.restart.enabled=false", + "endpoints.resume.enabled=true"); + } + + @Test + public void resumeMvcEndpointGloballyDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.enabled=false"); + } + + @Test + public void resumeMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("resumeMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.resume.enabled=true"); + } + + private void beanNotCreated(String beanName, String... contextProperties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { + assertThat("bean was created", context.containsBeanDefinition(beanName), equalTo(false)); + } + } + + private void beanCreated(String beanName, String... contextProperties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { + assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); + } + } + + private void beanCreatedAndEndpointEnabled(String beanName, String... properties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, properties)) { + assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); + + EndpointMvcAdapter endpoint = context.getBean(beanName, EndpointMvcAdapter.class); + Object result = endpoint.invoke(); + + assertThat("result is wrong type", result, + is(not(instanceOf(ResponseEntity.class)))); + } + } + + private static ConfigurableApplicationContext getApplicationContext( + Class configuration, String... properties) { + + List defaultProperties = Lists.newArrayList(properties); + defaultProperties.add("server.port=0"); + defaultProperties.add("spring.jmx.default-domain=${random.uuid}"); + + return new SpringApplicationBuilder(configuration).properties(defaultProperties.toArray(new String[]{})).run(); + } + + @Configuration + @EnableAutoConfiguration + static class Config { + + } } diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java index a6b190cb..36092206 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java @@ -24,14 +24,13 @@ public class RefreshAutoConfigurationClassPathTests { try (ConfigurableApplicationContext context = getApplicationContext( Config.class)) { assertFalse(context.getBeansOfType(RefreshEventListener.class).isEmpty()); - assertFalse(context.containsBean("refeshEndpoint")); + assertFalse(context.containsBean("refreshEndpoint")); } } private static ConfigurableApplicationContext getApplicationContext( Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).web(false) - .properties(properties).run(); + return new SpringApplicationBuilder(configuration).web(false).properties(properties).run(); } @Configuration diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java index b4f1fc16..3ecfeb66 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java @@ -33,8 +33,7 @@ public class RefreshAutoConfigurationTests { private static ConfigurableApplicationContext getApplicationContext( Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).web(false) - .properties(properties).run(); + return new SpringApplicationBuilder(configuration).web(false).properties(properties).run(); } @Configuration From 2baa775f656541c3fe24cf47fa637cd3d2444d21 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 30 Jun 2017 17:45:27 -0600 Subject: [PATCH 5/7] Make getDiscoveryClients() public --- .../client/discovery/composite/CompositeDiscoveryClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java index c3735f19..ff7cf2de 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java @@ -67,7 +67,7 @@ public class CompositeDiscoveryClient implements DiscoveryClient { return new ArrayList<>(services); } - List getDiscoveryClients() { + public List getDiscoveryClients() { return discoveryClients; } } From c75673110b65f5a508272e3a3eb3e2941dad246d Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 30 Jun 2017 17:47:08 -0600 Subject: [PATCH 6/7] formatting --- .../LifecycleMvcAutoConfigurationTests.java | 218 +++++++++--------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java index 270512f4..98feb248 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java @@ -22,136 +22,136 @@ import static org.junit.Assert.assertThat; */ public class LifecycleMvcAutoConfigurationTests { - // postEnvMvcEndpoint - @Test - public void postEnvMvcEndpointDisabled() { - beanNotCreated("environmentManagerEndpoint", - "endpoints.env.post.enabled=false"); - } + // postEnvMvcEndpoint + @Test + public void postEnvMvcEndpointDisabled() { + beanNotCreated("environmentManagerEndpoint", + "endpoints.env.post.enabled=false"); + } - @Test - public void postEnvMvcEndpointGloballyDisabled() { - beanNotCreated("environmentManagerEndpoint", - "endpoints.enabled=false"); - } + @Test + public void postEnvMvcEndpointGloballyDisabled() { + beanNotCreated("environmentManagerEndpoint", + "endpoints.enabled=false"); + } - @Test - public void postEnvMvcEndpointEnabled() { - beanCreated("environmentManagerEndpoint", - "endpoints.env.post.enabled=true"); - } + @Test + public void postEnvMvcEndpointEnabled() { + beanCreated("environmentManagerEndpoint", + "endpoints.env.post.enabled=true"); + } - // restartMvcEndpoint - @Test - public void restartMvcEndpointDisabled() { - beanNotCreated("restartMvcEndpoint", - "endpoints.restart.enabled=false"); - } + // restartMvcEndpoint + @Test + public void restartMvcEndpointDisabled() { + beanNotCreated("restartMvcEndpoint", + "endpoints.restart.enabled=false"); + } - @Test - public void restartMvcEndpointGloballyDisabled() { - beanNotCreated("restartMvcEndpoint", - "endpoints.enabled=false"); - } + @Test + public void restartMvcEndpointGloballyDisabled() { + beanNotCreated("restartMvcEndpoint", + "endpoints.enabled=false"); + } - @Test - public void restartMvcEndpointEnabled() { - beanCreatedAndEndpointEnabled("restartMvcEndpoint", - "endpoints.restart.enabled=true"); - } + @Test + public void restartMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("restartMvcEndpoint", + "endpoints.restart.enabled=true"); + } - // pauseMvcEndpoint - @Test - public void pauseMvcEndpointDisabled() { - beanNotCreated("pauseMvcEndpoint", - "endpoints.pause.enabled=false"); - } + // pauseMvcEndpoint + @Test + public void pauseMvcEndpointDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.pause.enabled=false"); + } - @Test - public void pauseMvcEndpointRestartDisabled() { - beanNotCreated("pauseMvcEndpoint", - "endpoints.restart.enabled=false", - "endpoints.pause.enabled=true"); - } + @Test + public void pauseMvcEndpointRestartDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.restart.enabled=false", + "endpoints.pause.enabled=true"); + } - @Test - public void pauseMvcEndpointGloballyDisabled() { - beanNotCreated("pauseMvcEndpoint", - "endpoints.enabled=false"); - } + @Test + public void pauseMvcEndpointGloballyDisabled() { + beanNotCreated("pauseMvcEndpoint", + "endpoints.enabled=false"); + } - @Test - public void pauseMvcEndpointEnabled() { - beanCreatedAndEndpointEnabled("pauseMvcEndpoint", - "endpoints.restart.enabled=true", - "endpoints.pause.enabled=true"); - } + @Test + public void pauseMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("pauseMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.pause.enabled=true"); + } - // resumeMvcEndpoint - @Test - public void resumeMvcEndpointDisabled() { - beanNotCreated("resumeMvcEndpoint", - "endpoints.restart.enabled=true", - "endpoints.resume.enabled=false"); - } + // resumeMvcEndpoint + @Test + public void resumeMvcEndpointDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.resume.enabled=false"); + } - @Test - public void resumeMvcEndpointRestartDisabled() { - beanNotCreated("resumeMvcEndpoint", - "endpoints.restart.enabled=false", - "endpoints.resume.enabled=true"); - } + @Test + public void resumeMvcEndpointRestartDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.restart.enabled=false", + "endpoints.resume.enabled=true"); + } - @Test - public void resumeMvcEndpointGloballyDisabled() { - beanNotCreated("resumeMvcEndpoint", - "endpoints.enabled=false"); - } + @Test + public void resumeMvcEndpointGloballyDisabled() { + beanNotCreated("resumeMvcEndpoint", + "endpoints.enabled=false"); + } - @Test - public void resumeMvcEndpointEnabled() { - beanCreatedAndEndpointEnabled("resumeMvcEndpoint", - "endpoints.restart.enabled=true", - "endpoints.resume.enabled=true"); - } + @Test + public void resumeMvcEndpointEnabled() { + beanCreatedAndEndpointEnabled("resumeMvcEndpoint", + "endpoints.restart.enabled=true", + "endpoints.resume.enabled=true"); + } - private void beanNotCreated(String beanName, String... contextProperties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { - assertThat("bean was created", context.containsBeanDefinition(beanName), equalTo(false)); - } - } + private void beanNotCreated(String beanName, String... contextProperties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { + assertThat("bean was created", context.containsBeanDefinition(beanName), equalTo(false)); + } + } - private void beanCreated(String beanName, String... contextProperties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { - assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); - } - } + private void beanCreated(String beanName, String... contextProperties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { + assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); + } + } - private void beanCreatedAndEndpointEnabled(String beanName, String... properties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, properties)) { - assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); + private void beanCreatedAndEndpointEnabled(String beanName, String... properties) { + try (ConfigurableApplicationContext context = getApplicationContext(Config.class, properties)) { + assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true)); - EndpointMvcAdapter endpoint = context.getBean(beanName, EndpointMvcAdapter.class); - Object result = endpoint.invoke(); + EndpointMvcAdapter endpoint = context.getBean(beanName, EndpointMvcAdapter.class); + Object result = endpoint.invoke(); - assertThat("result is wrong type", result, - is(not(instanceOf(ResponseEntity.class)))); - } - } + assertThat("result is wrong type", result, + is(not(instanceOf(ResponseEntity.class)))); + } + } - private static ConfigurableApplicationContext getApplicationContext( - Class configuration, String... properties) { + private static ConfigurableApplicationContext getApplicationContext( + Class configuration, String... properties) { - List defaultProperties = Lists.newArrayList(properties); - defaultProperties.add("server.port=0"); - defaultProperties.add("spring.jmx.default-domain=${random.uuid}"); + List defaultProperties = Lists.newArrayList(properties); + defaultProperties.add("server.port=0"); + defaultProperties.add("spring.jmx.default-domain=${random.uuid}"); - return new SpringApplicationBuilder(configuration).properties(defaultProperties.toArray(new String[]{})).run(); - } + return new SpringApplicationBuilder(configuration).properties(defaultProperties.toArray(new String[]{})).run(); + } - @Configuration - @EnableAutoConfiguration - static class Config { + @Configuration + @EnableAutoConfiguration + static class Config { - } + } } From 2aa6c3932257983ef9d7791f6ceef0c4b9e17bf2 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 30 Jun 2017 20:19:35 -0600 Subject: [PATCH 7/7] Reinstate @ConditionalOnClass(EnvironmentEndpoint.class) --- .../autoconfigure/LifecycleMvcEndpointAutoConfiguration.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java index 456b465e..ba2ce2e2 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java @@ -42,6 +42,7 @@ import org.springframework.context.annotation.Configuration; * */ @Configuration +@ConditionalOnClass(EnvironmentEndpoint.class) @ConditionalOnWebApplication @AutoConfigureAfter({ WebMvcAutoConfiguration.class, RefreshEndpointAutoConfiguration.class })