Allows users to provide composite environments. Fixes #495.
This commit is contained in:
@@ -556,6 +556,58 @@ $ vault write secret/application foo=bar baz=bam
|
||||
All applications using the config server will have the properties
|
||||
`foo` and `baz` available to them.
|
||||
|
||||
==== Composite Environment Repositories
|
||||
|
||||
In some scenarios you may wish to pull configuration data from multiple
|
||||
environment repositories. To do this just enable
|
||||
multiple profiles in your config server's application properties or YAML file.
|
||||
If, for example, you want to pull configuration data from a Git repository
|
||||
as well as a SVN repository you would set the following properties for your
|
||||
configuration server.
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
profiles:
|
||||
active: git, svn
|
||||
cloud:
|
||||
config:
|
||||
server:
|
||||
svn:
|
||||
uri: file:///path/to/svn/repo
|
||||
order: 2
|
||||
git:
|
||||
uri: file:///path/to/git/repo
|
||||
order: 1
|
||||
----
|
||||
|
||||
In addition to each repo specifying a URI, you can also specify an `order` property.
|
||||
The `order` property allows you to specify the priority order for all your repositories.
|
||||
The lower the numerical value of the `order` property the higher priority it will have.
|
||||
The priority order of a repository will help resolve any potential conflicts between
|
||||
repositories that contain values for the same properties.
|
||||
|
||||
NOTE: Any type of failure when retrieving values from an environment repositoy
|
||||
will result in a failure for the entire composite environment.
|
||||
|
||||
NOTE: When using a composite environment it is important that all repos contain
|
||||
the same label(s). If you have an environment similar to the one above and you request
|
||||
configuration data with the label `master` but the SVN
|
||||
repo does not contain a branch called `master` the entire request will fail.
|
||||
|
||||
===== Custom Composite Environment Repositories
|
||||
|
||||
It is also possible to provide your own `EnvironmentRepository` bean
|
||||
to be included as part of a composite environment in addition to
|
||||
using one of the environment repositories from Spring Cloud. To do this your bean
|
||||
must implement `OrderedEnvironmentRepository`. For convenience sake, there is
|
||||
an abstract implementation of this interface you can extend called
|
||||
`AbstractOrderedEnvironmentRepository`. If you extend `AbstractOrderedEnvironmentRepository`
|
||||
your environment repository will have the lowest possible precedence by default.
|
||||
If you would like to change this, make sure you call the `setOrder` method
|
||||
to set the precedence or override the `getOrder` method to return the order
|
||||
value you would like your environment repository to have.
|
||||
|
||||
==== Property Overrides
|
||||
|
||||
The Config Server has an "overrides" feature that allows the operator
|
||||
|
||||
@@ -76,6 +76,10 @@ public class Environment {
|
||||
this.propertySources.add(propertySource);
|
||||
}
|
||||
|
||||
public void add(List<PropertySource> propertySources) {
|
||||
this.propertySources.addAll(propertySources);
|
||||
}
|
||||
|
||||
public void addFirst(PropertySource propertySource) {
|
||||
this.propertySources.add(0, propertySource);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.OrderedEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.SearchPathCompositeEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.SearchPathLocator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnBean(OrderedEnvironmentRepository.class)
|
||||
public class CompositeConfiguration {
|
||||
|
||||
private List<OrderedEnvironmentRepository> environmentRepos = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnBean(SearchPathLocator.class)
|
||||
public SearchPathCompositeEnvironmentRepository compositeEnvironmentRepository() {
|
||||
return new SearchPathCompositeEnvironmentRepository(environmentRepos);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean(SearchPathLocator.class)
|
||||
public CompositeEnvironmentRepository compositeEnvironmentRepository2() {
|
||||
return new CompositeEnvironmentRepository(environmentRepos);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private void setEnvironmentRepos(List<OrderedEnvironmentRepository> repos) {
|
||||
this.environmentRepos = repos;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import org.springframework.context.annotation.Import;
|
||||
@Configuration
|
||||
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
|
||||
@EnableConfigurationProperties(ConfigServerProperties.class)
|
||||
@Import({ EnvironmentRepositoryConfiguration.class, ResourceRepositoryConfiguration.class,
|
||||
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class,
|
||||
ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class })
|
||||
public class ConfigServerAutoConfiguration {
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.config.server.environment.ConsulEnvironmentWatch;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentWatch;
|
||||
@@ -36,10 +35,10 @@ import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Ryan Baxter
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(EnvironmentRepository.class)
|
||||
public class EnvironmentRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -56,15 +55,14 @@ public class EnvironmentRepositoryConfiguration {
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Bean
|
||||
public NativeEnvironmentRepository environmentRepository() {
|
||||
public NativeEnvironmentRepository nativeEnvironmentRepository() {
|
||||
return new NativeEnvironmentRepository(this.environment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(EnvironmentRepository.class)
|
||||
protected static class GitRepositoryConfiguration {
|
||||
protected static class DefaultRepositoryConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
@@ -73,7 +71,7 @@ public class EnvironmentRepositoryConfiguration {
|
||||
private ConfigServerProperties server;
|
||||
|
||||
@Bean
|
||||
public MultipleJGitEnvironmentRepository environmentRepository() {
|
||||
public MultipleJGitEnvironmentRepository defaultEnvironmentRepository() {
|
||||
MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(this.environment);
|
||||
if (this.server.getDefaultLabel()!=null) {
|
||||
repository.setDefaultLabel(this.server.getDefaultLabel());
|
||||
@@ -82,6 +80,10 @@ public class EnvironmentRepositoryConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Profile("git")
|
||||
protected static class GitRepositoryConfiguration extends DefaultRepositoryConfiguration {}
|
||||
|
||||
@Configuration
|
||||
@Profile("subversion")
|
||||
protected static class SvnRepositoryConfiguration {
|
||||
@@ -92,7 +94,7 @@ public class EnvironmentRepositoryConfiguration {
|
||||
private ConfigServerProperties server;
|
||||
|
||||
@Bean
|
||||
public SvnKitEnvironmentRepository environmentRepository() {
|
||||
public SvnKitEnvironmentRepository svnKitEnvironmentRepository() {
|
||||
SvnKitEnvironmentRepository repository = new SvnKitEnvironmentRepository(this.environment);
|
||||
if (this.server.getDefaultLabel()!=null) {
|
||||
repository.setDefaultLabel(this.server.getDefaultLabel());
|
||||
@@ -105,7 +107,7 @@ public class EnvironmentRepositoryConfiguration {
|
||||
@Profile("vault")
|
||||
protected static class VaultConfiguration {
|
||||
@Bean
|
||||
public EnvironmentRepository environmentRepository(HttpServletRequest request, EnvironmentWatch watch) {
|
||||
public VaultEnvironmentRepository valutEnvironmentRepository(HttpServletRequest request, EnvironmentWatch watch) {
|
||||
return new VaultEnvironmentRepository(request, watch, new RestTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.environment;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class AbstractOrderedEnvironmentRepository implements OrderedEnvironmentRepository {
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.config.server.environment;
|
||||
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.support.AbstractScmAccessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
/**
|
||||
@@ -25,9 +26,10 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractScmEnvironmentRepository extends AbstractScmAccessor
|
||||
implements EnvironmentRepository, SearchPathLocator {
|
||||
implements OrderedEnvironmentRepository, SearchPathLocator {
|
||||
|
||||
private EnvironmentCleaner cleaner = new EnvironmentCleaner();
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
public AbstractScmEnvironmentRepository(ConfigurableEnvironment environment) {
|
||||
super(environment);
|
||||
@@ -46,4 +48,12 @@ public abstract class AbstractScmEnvironmentRepository extends AbstractScmAccess
|
||||
getUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.environment;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.core.OrderComparator;
|
||||
|
||||
/**
|
||||
* An {@link EnvironmentRepository} composed of multiple ordered {@link OrderedEnvironmentRepository}s.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class CompositeEnvironmentRepository implements EnvironmentRepository {
|
||||
|
||||
protected List<OrderedEnvironmentRepository> environmentRepositories;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CompositeEnvironmentRepository}.
|
||||
* @param environmentRepositories The list of {@link OrderedEnvironmentRepository}s to create the composite from.
|
||||
*/
|
||||
public CompositeEnvironmentRepository(List<OrderedEnvironmentRepository> environmentRepositories) {
|
||||
//Sort the environment repositories by the priority
|
||||
Collections.sort(environmentRepositories, OrderComparator.INSTANCE);
|
||||
this.environmentRepositories = environmentRepositories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String profile, String label) {
|
||||
Environment env = new Environment(application, new String[]{profile}, label, null, null);
|
||||
for(EnvironmentRepository repo : environmentRepositories) {
|
||||
env.add(repo.findOne(application, profile, label).getPropertySources());
|
||||
}
|
||||
return env;
|
||||
}
|
||||
}
|
||||
@@ -293,4 +293,8 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(int order) {
|
||||
super.setOrder(order);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Roy Clarkson
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.config.server.native")
|
||||
public class NativeEnvironmentRepository
|
||||
implements EnvironmentRepository, SearchPathLocator {
|
||||
public class NativeEnvironmentRepository extends AbstractOrderedEnvironmentRepository
|
||||
implements SearchPathLocator {
|
||||
|
||||
private static Log logger = LogFactory.getLog(NativeEnvironmentRepository.class);
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.environment;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* A prioritized {@link EnvironmentRepository}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface OrderedEnvironmentRepository extends EnvironmentRepository, Ordered {
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.environment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link CompositeEnvironmentRepository} which implements {@link SearchPathLocator}.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class SearchPathCompositeEnvironmentRepository extends CompositeEnvironmentRepository implements SearchPathLocator {
|
||||
|
||||
/**
|
||||
* Creates a new {@link SearchPathCompositeEnvironmentRepository}.
|
||||
* @param environmentRepositories The {@link OrderedEnvironmentRepository}s to create this composite from.
|
||||
*/
|
||||
public SearchPathCompositeEnvironmentRepository(List<OrderedEnvironmentRepository> environmentRepositories) {
|
||||
super(environmentRepositories);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locations getLocations(String application, String profile, String label) {
|
||||
List<String> locations = new ArrayList<>();
|
||||
for(EnvironmentRepository repo : this.environmentRepositories) {
|
||||
if(repo instanceof SearchPathLocator) {
|
||||
locations.addAll(Arrays.asList(((SearchPathLocator) repo).getLocations(application, profile, label).getLocations()));
|
||||
}
|
||||
}
|
||||
return new Locations(application, profile, label, null, locations.toArray(new String[locations.size()]));
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,10 @@ public class SvnKitEnvironmentRepository extends AbstractScmEnvironmentRepositor
|
||||
this.defaultLabel = defaultLabel;
|
||||
}
|
||||
|
||||
public SvnKitEnvironmentRepository(ConfigurableEnvironment environment) {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Locations getLocations(String application, String profile,
|
||||
String label) {
|
||||
@@ -168,10 +172,6 @@ public class SvnKitEnvironmentRepository extends AbstractScmEnvironmentRepositor
|
||||
|
||||
}
|
||||
|
||||
public SvnKitEnvironmentRepository(ConfigurableEnvironment environment) {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getWorkingDirectory() {
|
||||
return this.getBasedir();
|
||||
@@ -193,4 +193,9 @@ public class SvnKitEnvironmentRepository extends AbstractScmEnvironmentRepositor
|
||||
return svnPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(int order) {
|
||||
super.setOrder(order);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import static org.springframework.cloud.config.client.ConfigClientProperties.TOK
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.config.server.vault")
|
||||
public class VaultEnvironmentRepository implements EnvironmentRepository {
|
||||
public class VaultEnvironmentRepository extends AbstractOrderedEnvironmentRepository {
|
||||
|
||||
public static final String VAULT_TOKEN = "X-Vault-Token";
|
||||
|
||||
@@ -190,6 +190,11 @@ public class VaultEnvironmentRepository implements EnvironmentRepository {
|
||||
this.profileSeparator = profileSeparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(int order) {
|
||||
super.setOrder(order);
|
||||
}
|
||||
|
||||
static class VaultResponse {
|
||||
private String auth;
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ConfigServerApplication.class,
|
||||
properties = { "spring.config.name:compositeconfigserver",
|
||||
"spring.cloud.config.server.svn.uri:file:///./target/repos/svn-config-repo",
|
||||
"spring.cloud.config.server.svn.order:2",
|
||||
"spring.cloud.config.server.git.uri:file:./target/repos/config-repo",
|
||||
"spring.cloud.config.server.git.order:1"},
|
||||
webEnvironment = RANDOM_PORT)
|
||||
@ActiveProfiles({ "test", "git", "subversion" })
|
||||
public class CompositeConfigServerIntegrationTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception {
|
||||
ConfigServerTestUtils.prepareLocalRepo();
|
||||
ConfigServerTestUtils.prepareLocalSvnRepo("src/test/resources/svn-config-repo",
|
||||
"target/repos/svn-config-repo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
Environment environment = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/", Environment.class);
|
||||
assertEquals(3, environment.getPropertySources().size());
|
||||
assertEquals("overrides", environment.getPropertySources().get(0).getName());
|
||||
assertTrue(environment.getPropertySources().get(1).getName().contains("config-repo") &&
|
||||
!environment.getPropertySources().get(1).getName().contains("svn-config-repo"));
|
||||
assertTrue(environment.getPropertySources().get(2).getName().contains("svn-config-repo"));
|
||||
assertEquals("{spring.cloud.config.enabled=true}", environment
|
||||
.getPropertySources().get(0).getSource().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourseEndpointsWork() {
|
||||
//This request will get the file from the Git Repo
|
||||
String text = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/composite/bar.properties", String.class);
|
||||
|
||||
String expected = "foo: bar";
|
||||
assertEquals("invalid content", expected, text);
|
||||
|
||||
//This request will get the file from the SVN Repo
|
||||
text = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/composite/bar.properties", String.class);
|
||||
assertEquals("invalid content", expected, text);
|
||||
}
|
||||
}
|
||||
@@ -49,10 +49,4 @@ public class NativeConfigServerIntegrationTests {
|
||||
+ port + "/bad/default/", String.class);
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(ConfigServerApplication.class).profiles("native").properties(
|
||||
"spring.config.name=configserver").run(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.environment.PropertySource;
|
||||
import org.springframework.cloud.config.server.EnableConfigServer;
|
||||
import org.springframework.cloud.config.server.environment.AbstractOrderedEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.OrderedEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomCompositeEnvironmentRepositoryTests.TestApplication.class, properties = {
|
||||
"spring.config.name:compositeconfigserver", "spring.cloud.config.server.git.uri:file:./target/repos/config-repo",
|
||||
"spring.cloud.config.server.git.order:1" }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@ActiveProfiles({"test", "git"})
|
||||
@DirtiesContext
|
||||
public class CustomCompositeEnvironmentRepositoryTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception {
|
||||
ConfigServerTestUtils.prepareLocalRepo();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
Environment environment = new TestRestTemplate().getForObject(
|
||||
"http://localhost:" + port + "/foo/development/", Environment.class);
|
||||
List<PropertySource> propertySources = environment.getPropertySources();
|
||||
assertEquals(3, propertySources.size());
|
||||
assertEquals("overrides", propertySources.get(0).getName());
|
||||
assertTrue(propertySources.get(1).getName().contains("config-repo"));
|
||||
assertEquals("p", propertySources.get(2).getName());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableConfigServer
|
||||
protected static class TestApplication {
|
||||
|
||||
@Bean
|
||||
public OrderedEnvironmentRepository environmentRepository() {
|
||||
return new AbstractOrderedEnvironmentRepository() {
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String profile,
|
||||
String label) {
|
||||
Environment e = new Environment("test", new String[0], "label", "version",
|
||||
"state");
|
||||
PropertySource p = new PropertySource("p", new HashMap<>());
|
||||
e.add(p);
|
||||
return e;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(CustomEnvironmentRepositoryTests.TestApplication.class,
|
||||
args);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2013-2016 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.config.server.environment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.environment.PropertySource;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class CompositeEnvironmentRepositoryTests {
|
||||
|
||||
private class TestOrderedEnvironmentRepository extends AbstractOrderedEnvironmentRepository implements SearchPathLocator {
|
||||
|
||||
private Environment env;
|
||||
private Locations locations;
|
||||
|
||||
public TestOrderedEnvironmentRepository(int order, Environment env, Locations locations) {
|
||||
setOrder(order);
|
||||
this.env = env;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String profile, String label) {
|
||||
return env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locations getLocations(String application, String profile, String label) {
|
||||
return locations;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrder() {
|
||||
PropertySource p1 = mock(PropertySource.class);
|
||||
doReturn("p1").when(p1).getName();
|
||||
PropertySource p2 = mock(PropertySource.class);
|
||||
doReturn("p2").when(p2).getName();
|
||||
PropertySource p3 = mock(PropertySource.class);
|
||||
doReturn("p3").when(p3).getName();
|
||||
PropertySource p4 = mock(PropertySource.class);
|
||||
doReturn("p4").when(p4).getName();
|
||||
PropertySource p5 = mock(PropertySource.class);
|
||||
doReturn("p5").when(p5).getName();
|
||||
String sLoc1 = "loc1";
|
||||
String sLoc2 = "loc2";
|
||||
String sLoc3 = "loc3";
|
||||
String sLoc4 = "loc4";
|
||||
String sLoc5 = "loc5";
|
||||
Environment e1 = new Environment("app", "dev");
|
||||
e1.add(p1);
|
||||
e1.add(p5);
|
||||
Environment e2 = new Environment("app", "dev");
|
||||
e2.add(p2);
|
||||
Environment e3 = new Environment("app", "dev");
|
||||
e3.add(p3);
|
||||
e3.add(p4);
|
||||
SearchPathLocator.Locations loc1 = new SearchPathLocator.Locations("app", "dev", "label", "version", new String[]{sLoc1});
|
||||
SearchPathLocator.Locations loc2 = new SearchPathLocator.Locations("app", "dev", "label", "version", new String[]{sLoc5, sLoc4});
|
||||
SearchPathLocator.Locations loc3 = new SearchPathLocator.Locations("app", "dev", "label", "version", new String[]{sLoc3, sLoc2});
|
||||
List<OrderedEnvironmentRepository> repos = new ArrayList<OrderedEnvironmentRepository>();
|
||||
repos.add(new TestOrderedEnvironmentRepository(3, e1, loc1));
|
||||
repos.add(new TestOrderedEnvironmentRepository(2, e3, loc2));
|
||||
repos.add(new TestOrderedEnvironmentRepository(1, e2, loc3));
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(repos);
|
||||
Environment compositeEnv = compositeRepo.findOne("foo", "bar", "world");
|
||||
List<PropertySource> propertySources = compositeEnv.getPropertySources();
|
||||
assertEquals(5, propertySources.size());
|
||||
assertEquals("p2", propertySources.get(0).getName());
|
||||
assertEquals("p3", propertySources.get(1).getName());
|
||||
assertEquals("p4", propertySources.get(2).getName());
|
||||
assertEquals("p1", propertySources.get(3).getName());
|
||||
assertEquals("p5", propertySources.get(4).getName());
|
||||
|
||||
SearchPathLocator.Locations locations = compositeRepo.getLocations("app", "dev", "label");
|
||||
String[] locationStrings = locations.getLocations();
|
||||
assertEquals(5, locationStrings.length);
|
||||
assertEquals(sLoc3, locationStrings[0]);
|
||||
assertEquals(sLoc2, locationStrings[1]);
|
||||
assertEquals(sLoc5, locationStrings[2]);
|
||||
assertEquals(sLoc4, locationStrings[3]);
|
||||
assertEquals(sLoc1, locationStrings[4]);
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class JGitEnvironmentRepositoryIntegrationTests {
|
||||
.run("--spring.cloud.config.server.git.uri=" + uri,
|
||||
"--spring.cloud.config.server.git.cloneOnStart=true");
|
||||
EnvironmentRepository repository = this.context
|
||||
.getBean(EnvironmentRepository.class);
|
||||
.getBean(JGitEnvironmentRepository.class);
|
||||
assertTrue(((JGitEnvironmentRepository) repository).isCloneOnStart());
|
||||
Environment environment = repository.findOne("bar", "staging", "master");
|
||||
assertEquals(2, environment.getPropertySources().size());
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
spring:
|
||||
cloud:
|
||||
config:
|
||||
server:
|
||||
overrides:
|
||||
spring:
|
||||
cloud:
|
||||
config:
|
||||
enabled: true
|
||||
Binary file not shown.
@@ -1 +1,5 @@
|
||||
0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Dave Syer <dsyer@gopivotal.com> 1406860717 -0700
|
||||
7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Ryan Baxter <rbaxter@pivotal.io> 1481905383 -0500 checkout: moving from raw to master
|
||||
9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905407 -0500 checkout: moving from master to raw
|
||||
7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905544 -0500 checkout: moving from raw to composite
|
||||
7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905552 -0500 checkout: moving from composite to raw
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905474 -0500 branch: Created from raw
|
||||
@@ -0,0 +1 @@
|
||||
7df4a26d5437d9d4090cd5809967f870444cde8f
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
2
|
||||
3
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
K 10
|
||||
svn:author
|
||||
V 11
|
||||
ryanjbaxter
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2016-12-16T16:51:59.468533Z
|
||||
K 7
|
||||
svn:log
|
||||
V 23
|
||||
adding composite branch
|
||||
END
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
id: 0.0.t2-4
|
||||
type: dir
|
||||
pred: 0.0.r2/1211
|
||||
count: 3
|
||||
text: 2 1126 72 0 a8927d430ec09518c534d157c6e49580
|
||||
cpath: /
|
||||
copyroot: 0 /
|
||||
is-fresh-txn-root: y
|
||||
|
||||
Reference in New Issue
Block a user