From 1e3a7c05cdbe2c0b0f5c2b5096200b03499eb348 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 29 Jul 2019 14:29:27 +0200 Subject: [PATCH 1/2] Added symbolic link of index.adoc --- docs/src/main/asciidoc/index.adoc | 1 + 1 file changed, 1 insertion(+) create mode 120000 docs/src/main/asciidoc/index.adoc diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 00000000..a296f031 --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-config.adoc \ No newline at end of file From 25689a8b963b1640b7b794743d30de89da2d4cd2 Mon Sep 17 00:00:00 2001 From: Tim Ysewyn Date: Fri, 2 Aug 2019 19:17:46 +0200 Subject: [PATCH 2/2] Support context refresh of config server. (#1433) Whenever the `spring.cloud.config.server.overrides` property was changed (either through the env actuator endpoint or remote bootstrap configuration) this was not reflected when retrieving the application's configuration. fixes gh-1295 --- .../config/ConfigServerMvcConfiguration.java | 7 +- .../ResourceRepositoryConfiguration.java | 4 +- ...BootstrapConfigServerIntegrationTests.java | 6 +- ...freshableConfigServerIntegrationTests.java | 142 ++++++++++++++++++ .../src/test/resources/enable-bootstrap.yml | 2 + .../encrypt-repo/enable-bootstrap.yml | 6 + .../resources/encrypt-repo/git/COMMIT_EDITMSG | 2 +- .../src/test/resources/encrypt-repo/git/index | Bin 225 -> 313 bytes .../test/resources/encrypt-repo/git/logs/HEAD | 1 + .../encrypt-repo/git/logs/refs/heads/master | 1 + .../63/e43ddbda928b903e56f601409552bbfb7fdd99 | Bin 0 -> 72 bytes .../ba/97b023d1d0faa44cc337479d6a8ac1ebcdb00d | Bin 0 -> 140 bytes .../fd/07d827993aaf6ed7ef1b979767ee9277d1d409 | Bin 0 -> 830 bytes .../encrypt-repo/git/refs/heads/master | 2 +- 14 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/RefreshableConfigServerIntegrationTests.java create mode 100644 spring-cloud-config-server/src/test/resources/encrypt-repo/enable-bootstrap.yml create mode 100644 spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/63/e43ddbda928b903e56f601409552bbfb7fdd99 create mode 100644 spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ba/97b023d1d0faa44cc337479d6a8ac1ebcdb00d create mode 100644 spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/fd/07d827993aaf6ed7ef1b979767ee9277d1d409 diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java index aaf4b170..fb91c0d2 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java @@ -27,19 +27,21 @@ import org.springframework.cloud.config.server.environment.EnvironmentEncryptorE import org.springframework.cloud.config.server.environment.EnvironmentRepository; import org.springframework.cloud.config.server.resource.ResourceController; import org.springframework.cloud.config.server.resource.ResourceRepository; +import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author Dave Syer * @author Roy Clarkson + * @author Tim Ysewyn */ @Configuration @ConditionalOnWebApplication -public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter { +public class ConfigServerMvcConfiguration implements WebMvcConfigurer { @Autowired(required = false) private EnvironmentEncryptor environmentEncryptor; @@ -55,6 +57,7 @@ public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter { } @Bean + @RefreshScope public EnvironmentController environmentController( EnvironmentRepository envRepository, ConfigServerProperties server) { EnvironmentController controller = new EnvironmentController( diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ResourceRepositoryConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ResourceRepositoryConfiguration.java index 21da4c7c..dcdf966b 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ResourceRepositoryConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ResourceRepositoryConfiguration.java @@ -18,7 +18,6 @@ package org.springframework.cloud.config.server.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.config.server.environment.SearchPathLocator; import org.springframework.cloud.config.server.resource.GenericResourceRepository; import org.springframework.cloud.config.server.resource.ResourceRepository; @@ -27,10 +26,9 @@ import org.springframework.context.annotation.Configuration; /** * @author Dave Syer - * + * @author Tim Ysewyn */ @Configuration -@EnableConfigurationProperties(ConfigServerProperties.class) @ConditionalOnMissingBean(ResourceRepository.class) public class ResourceRepositoryConfiguration { diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java index dc396952..6568ef45 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java @@ -63,8 +63,10 @@ public class BootstrapConfigServerIntegrationTests { public void contextLoads() { Environment environment = new TestRestTemplate().getForObject( "http://localhost:" + this.port + "/foo/development/", Environment.class); - assertThat(environment.getPropertySources().isEmpty()).isFalse(); - assertThat(environment.getPropertySources().get(0).getSource().get("info.foo")) + assertThat(environment.getPropertySources()).hasSize(2); + assertThat(environment.getPropertySources().get(0).getSource().get("bar")) + .isEqualTo("foo"); + assertThat(environment.getPropertySources().get(1).getSource().get("info.foo")) .isEqualTo("bar"); } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/RefreshableConfigServerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/RefreshableConfigServerIntegrationTests.java new file mode 100644 index 00000000..ebc59d8d --- /dev/null +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/RefreshableConfigServerIntegrationTests.java @@ -0,0 +1,142 @@ +/* + * Copyright 2013-2019 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 + * + * https://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.config.server; + +import java.io.IOException; + +import org.eclipse.jgit.junit.MockSystemReader; +import org.eclipse.jgit.util.SystemReader; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.config.environment.Environment; +import org.springframework.cloud.config.server.RefreshableConfigServerIntegrationTests.TestConfiguration; +import org.springframework.cloud.config.server.environment.EnvironmentRepository; +import org.springframework.cloud.config.server.resource.ResourceRepository; +import org.springframework.cloud.config.server.test.ConfigServerTestUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.BDDMockito.given; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestConfiguration.class, properties = { + "spring.cloud.config.enabled=true", + "management.endpoints.web.exposure.include=env, refresh" }, webEnvironment = WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@DirtiesContext +public class RefreshableConfigServerIntegrationTests { + + private static String localRepo = null; + + @LocalServerPort + private int port; + + @BeforeClass + public static void init() throws IOException { + // mock Git configuration to make tests independent of local Git configuration + SystemReader.setInstance(new MockSystemReader()); + + localRepo = ConfigServerTestUtils.prepareLocalRepo(); + } + + @AfterClass + public static void after() throws IOException { + ConfigServerTestUtils.deleteLocalRepo(localRepo); + } + + /* + * We're emulating an application "foo" which is running with the "development" profile + * and is asking for its properties using the REST endpoint. We're also calling the + * /env & /refresh actuator endpoints to change the + * `spring.cloud.config.server.overrides.foo` property. Since we see that we only get + * the overridden "foo" property after the context refresh we are sure that the + * properties have been set and the EnvironmentController bean has successfully been + * recreated with the new overrides. + */ + @Test + public void refreshOverrides() { + Environment environment = new TestRestTemplate().getForObject( + "http://localhost:" + this.port + "/foo/development/", Environment.class); + assertThat(environment.getPropertySources()).isEmpty(); + + String actuatorEndpoint = "http://localhost:" + this.port + "/actuator"; + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", "application/json"); + HttpEntity request = new HttpEntity<>( + "{\"name\": \"spring.cloud.config.server.overrides.foo\", \"value\": \"bar\"}", + headers); + ResponseEntity response = new TestRestTemplate() + .postForEntity(actuatorEndpoint + "/env", request, Void.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + + response = new TestRestTemplate().postForEntity(actuatorEndpoint + "/refresh", + null, Void.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + + environment = new TestRestTemplate().getForObject( + "http://localhost:" + this.port + "/foo/development/", Environment.class); + assertThat(environment.getPropertySources()).isNotEmpty(); + assertThat(environment.getPropertySources().get(0).getSource().get("foo")) + .isEqualTo("bar"); + } + + @Configuration + @EnableAutoConfiguration + @EnableConfigServer + protected static class TestConfiguration { + + @Bean + public EnvironmentRepository environmentRepository() { + EnvironmentRepository repository = Mockito.mock(EnvironmentRepository.class); + Environment environment = new Environment("", ""); + given(repository.findOne(isA(String.class), isA(String.class), + nullable(String.class))).willReturn(environment); + return repository; + } + + @Bean + public ResourceRepository resourceRepository() { + ResourceRepository repository = Mockito.mock(ResourceRepository.class); + given(repository.findOne(isA(String.class), isA(String.class), + nullable(String.class), isA(String.class))) + .willReturn(new ByteArrayResource("".getBytes())); + return repository; + } + + } + +} diff --git a/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml b/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml index fab99da1..6fcb23ff 100644 --- a/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml +++ b/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml @@ -1,4 +1,6 @@ spring: + application: + name: enable-bootstrap cloud: config: server: diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/enable-bootstrap.yml b/spring-cloud-config-server/src/test/resources/encrypt-repo/enable-bootstrap.yml new file mode 100644 index 00000000..63e43ddb --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/enable-bootstrap.yml @@ -0,0 +1,6 @@ +spring: + cloud: + config: + server: + overrides: + bar: foo diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG index c8fcd951..8f9fc884 100644 --- a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG @@ -1 +1 @@ -Updated +Added server overrides diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/index b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/index index 41937d55f5b1baab536006ce31a4bfa337eb455a..f6761ccd6bf87b9001408f0d23287ab555e1d49e 100644 GIT binary patch delta 239 zcmaFJxRc4i#WTp6fq{Vuh?!#@oMtn+-k2V%Gwqd3l(P{d0|N^~{3}NWhQ=if42)la zYD6X)=%|3z*)2~7tBcvJ4^`)YqOL)w9<0uM=FeCMenZU{4Hu#6?2*+0%?wO_Vtf16 zr0xlJVc!@XrUvc)U4M5bgGg##Vp2}3Zc=`JNpVS0Vu4;|ZVpg25QGG|x&kRl24e*S xu3ghNC||trYl+WcbN9JfT?b#E-N2jNDW?84iSOa}h}7+2OJ_{}*fs5+833@oP%!`i delta 150 zcmdnV^pMfO#WTp6fq{VugkvH?cIwwIdJCf&7@3(FTR5y37#f!_FfhLW;fV%1Dj<2m zV$*0C4N=FYilVMT$226!)fH&2B!iKH0askiGG;T$m8)1)mT+u5cBjr}el)wZ*LT-z UYRi1D%an*;>S)^Uw(7)B08y_ls{jB1 diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD index dc9c2ab0..3e9d8789 100644 --- a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD @@ -6,3 +6,4 @@ 7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer 1498491043 +0100 checkout: moving from raw to master 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer 1498491468 +0100 commit: Add encrypted property ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc bd414a6cc8653d7e282df0a257babc6283b83596 Marcin Grzejszczak 1549357702 +0100 commit: Updated +bd414a6cc8653d7e282df0a257babc6283b83596 fd07d827993aaf6ed7ef1b979767ee9277d1d409 Tim Ysewyn 1564492480 +0200 commit: Added server overrides diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master index 5412791a..7ca96c00 100644 --- a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master @@ -1,3 +1,4 @@ 0000000000000000000000000000000000000000 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer 1406860776 -0700 branch: Created from 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer 1498491468 +0100 commit: Add encrypted property ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc bd414a6cc8653d7e282df0a257babc6283b83596 Marcin Grzejszczak 1549357702 +0100 commit: Updated +bd414a6cc8653d7e282df0a257babc6283b83596 fd07d827993aaf6ed7ef1b979767ee9277d1d409 Tim Ysewyn 1564492480 +0200 commit: Added server overrides diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/63/e43ddbda928b903e56f601409552bbfb7fdd99 b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/63/e43ddbda928b903e56f601409552bbfb7fdd99 new file mode 100644 index 0000000000000000000000000000000000000000..245ed5d6ffa5c314e7abc0defe21516c7f7f684a GIT binary patch literal 72 zcmV-O0Jr~m0ZYosPg1ZjWGF5u%FIi*;!;pZ&dD!L0WpBg{JgYGupo$6oLW?tS_F{+ e@$-SaqRf=kVuX-_LQ-Opl|ov6J{JI0$QPu;IUzX! literal 0 HcmV?d00001 diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ba/97b023d1d0faa44cc337479d6a8ac1ebcdb00d b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ba/97b023d1d0faa44cc337479d6a8ac1ebcdb00d new file mode 100644 index 0000000000000000000000000000000000000000..9d0456727c20de07ca86a56dd8e0fcc58ee78460 GIT binary patch literal 140 zcmV;70CWF%0V^p=O;s>7HfAt1FfcPQQAjK($jMAjEXmBz)2qzQVUV?Xyk?$PY52>y znLKJP16%^$cq!yKArWP}-v$-GL@n1u_o}NR;fj) zbW0_b?$s&!$Dnvm0qF@+-6~vOyP*zY?UX(e6CGpJO zRX2jXWGOb|ivsZ+QwkN0=(2_x%?Wvy7d(xa95I~86WKIg`!@)i2RIMavUcG2as4^` z`E2HX%J%jNRoVMy?=EA zd^c{hkVw|1)S`DgE1C6=XE!m|^xJqn)G3+eOcQ!z!e!gIYll_vDM!IfX65ybE z@@4jpi0s)guyr3VG|mTc3vXv5``neWLNN;bF)<17EM?7g z4%v>KWp?W5E_|6L+o|;UQU(F@kf)6!! z4u+F(e0R6Eu1qe67OGZ9_%RuD3JN20ISFGcw9zdVhGXh|efab@aaiZtp|T*l+NEP@ zx3Y;TaB^E%ty2ZA6gyb!i+t!m6GBI0e*Z|bR+&@=3p!TMGPU8WmSTqde2`f`)_+UWi=3g I0kFke9;w=y82|tP literal 0 HcmV?d00001 diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master index 51053139..65ee9fbb 100644 --- a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master @@ -1 +1 @@ -bd414a6cc8653d7e282df0a257babc6283b83596 +fd07d827993aaf6ed7ef1b979767ee9277d1d409