Instead of using Map everywhere it's neater to use a strongly typed

object. This reuses JGitEnvironmentRepository, since it shares
most of the same properties. The format of the repos config
changes - now it is a Map not a List and the key is used as a "name"
to provide a default pattern and a location in the basedir.

Example config:

    spring:
      application:
        name: configserver
      cloud:
        config:
          server:
            git:
              uri: https://github.com/spring-cloud-samples/config-repo
              repos:
                iceycake: https://github.com/iceycake/config-repo
                project1:
                  patterns: project1-*,*-project1
                  uri: https://github.com/spring-cloud-samples/config-repo-1
This commit is contained in:
Dave Syer
2015-02-10 15:49:35 +00:00
parent e05e876f8f
commit 897ad1face
7 changed files with 138 additions and 159 deletions

View File

@@ -95,18 +95,21 @@ spring:
git:
uri: https://github.com/spring-cloud-samples/config-repo
repos:
- patterns: *pattern
uri: https://github.com/pattern1/config-repo
- patterns: pattern*,*pattern1*
simple: https://github.com/pattern1/config-repo
special:
pattern: pattern*,*pattern1*
uri: https://github.com/pattern2/config-repo
- patterns: local*
local:
pattern: local*
uri: file:/home/configsvc/config-repo
----
In the above example, if {application} does not match to any of the patterns
under "spring.cloud.config.server.git.repos", it will use the default uri
defined under "spring.cloud.config.server.git.uri". Acceptable pattern
format is "*xxx", "xxx*", or "*xxx*".
In the above example, if {application} does not match to any of the
patterns, it will use the default uri defined under
"spring.cloud.config.server.git.uri". For the "simple" repository, the
pattern is "simple" (i.e. it only matches one application). The
pattern format is a comma-separated list of application names with
wildcards.
==== File System Backend

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.config.server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -1,26 +0,0 @@
package org.springframework.cloud.config.server;
import javax.annotation.PostConstruct;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
*
* @author iceycake
*
*/
@ConfigurationProperties(prefix = "spring.cloud.config.server.git.repos")
public class EnvironmentRepositories {
private String uri;
private String name;
@PostConstruct
public void init() throws Exception {
}
public EnvironmentRepositories() {
super();
}
}

View File

@@ -43,7 +43,6 @@ import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.FileUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.config.Environment;
import org.springframework.cloud.config.PropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
@@ -54,10 +53,11 @@ import org.springframework.util.StringUtils;
import com.jcraft.jsch.Session;
/**
* An {@link EnvironmentRepository} backed by a single git repository.
*
* @author Dave Syer
*
*/
@ConfigurationProperties("spring.cloud.config.server.git")
public class JGitEnvironmentRepository implements EnvironmentRepository, InitializingBean {
private static Log logger = LogFactory.getLog(JGitEnvironmentRepository.class);
@@ -147,6 +147,14 @@ public class JGitEnvironmentRepository implements EnvironmentRepository, Initial
this.password = password;
}
protected ConfigurableEnvironment getEnvironment() {
return environment;
}
protected void setEnvironment(ConfigurableEnvironment environment) {
this.environment = environment;
}
@Override
public Environment findOne(String application, String profile, String label) {
initialize();

View File

@@ -16,132 +16,120 @@
package org.springframework.cloud.config.server;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.config.Environment;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
/**
* {@link EnvironmentRepository} that based on one or more git repositories. Can be
* configured just like a single {@link JGitEnvironmentRepository}, for the "default"
* properties, and then additional repositories can be registered by name. The simplest
* form of the registration is just a map from name to uri (plus credentials if needed),
* where each app has its own git repository. As well as a name you can provide a pattern
* that matches on the application name (or even a list of patterns). Each sub-repository
* additionally can have its own search paths (subdirectories inside the top level of the
* repository).
*
* @author Andy Chan (iceycake)
* @author Dave Syer
*
*/
@ConfigurationProperties("spring.cloud.config.server.git")
public class MultipleJGitEnvironmentRepository implements EnvironmentRepository,
InitializingBean {
public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository {
private static final String REPO_PATTERNS = "patterns";
private static final String REPO_URI = "uri";
private static final String REPO_USERNAME = "username";
private static final String REPO_PASSWORD = "password";
private static final String REPO_SEARCHPATHS = "searchPaths";
private Map<String, PatternMatchingJGitEnvironmentRepository> repos = new LinkedHashMap<String, PatternMatchingJGitEnvironmentRepository>();
private String uri;
private String username;
private String password;
private String[] searchPaths = new String[0];
private List<Map<String, Object>> repos = new ArrayList<Map<String, Object>>();
private Map<String, JGitEnvironmentRepository> repoCache = new LinkedHashMap<String, JGitEnvironmentRepository>();
private JGitEnvironmentRepository defaultRepo;
private ConfigurableEnvironment environment;
public MultipleJGitEnvironmentRepository(ConfigurableEnvironment environment) {
super(environment);
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.state(uri != null,
"You need to configure a uri for the default git repository");
}
public MultipleJGitEnvironmentRepository(ConfigurableEnvironment environment) {
this.environment = environment;
}
public void setSearchPaths(String... searchPaths) {
this.searchPaths = searchPaths;
}
public void setUri(String uri) {
while (uri.endsWith("/")) {
uri = uri.substring(0, uri.length() - 1);
super.afterPropertiesSet();
for (String name : repos.keySet()) {
PatternMatchingJGitEnvironmentRepository repo = repos.get(name);
repo.setEnvironment(getEnvironment());
if (!StringUtils.hasText(repo.getName())) {
repo.setName(name);
}
if (repo.getPattern() == null || repo.getPattern().length == 0) {
repo.setPattern(new String[] { name });
}
repo.afterPropertiesSet();
}
this.uri = uri;
}
public String getUri() {
return uri;
public void setRepos(Map<String, PatternMatchingJGitEnvironmentRepository> repos) {
this.repos.putAll(repos);
}
public void setRepos(List<Map<String, Object>> repos) {
this.repos.addAll(repos);
}
public List<Map<String, Object>> getRepos() {
public Map<String, PatternMatchingJGitEnvironmentRepository> getRepos() {
return this.repos;
}
@Override
public Environment findOne(String application, String profile, String label) {
if (this.defaultRepo == null) {
defaultRepo = createJGitEnvironmentRepository(this.uri, this.username,
this.password, this.searchPaths);
for (PatternMatchingJGitEnvironmentRepository repository : repos.values()) {
Environment source = repository.findOne(application, profile, label);
if (source != null) {
return source;
}
}
return super.findOne(application, profile, label);
}
public static class PatternMatchingJGitEnvironmentRepository extends
JGitEnvironmentRepository {
private String[] pattern;
private String name;
public PatternMatchingJGitEnvironmentRepository() {
super(null);
}
public PatternMatchingJGitEnvironmentRepository(String uri) {
this();
setUri(uri);
}
JGitEnvironmentRepository repo = this.defaultRepo;
@Override
public Environment findOne(String application, String profile, String label) {
for (Map<String, Object> repoKeyValue : repos) {
String repoPatternsList = (String)repoKeyValue.get(REPO_PATTERNS);
if (repoPatternsList == null || repoPatternsList.isEmpty()) {
continue;
}
String[] repoPatterns = repoPatternsList.split(",");
String repoUri = (String)repoKeyValue.get(REPO_URI);
Assert.state(repoUri != null,
"You need to configure a uri for the '" + repoPatternsList + "' git repository");
String repoUsername = (String)repoKeyValue.get(REPO_USERNAME);
String repoPassword = (String)repoKeyValue.get(REPO_PASSWORD);
String[] repoSearchPaths = new String[0];
LinkedHashMap<String, String> searchPathsList = (LinkedHashMap<String, String>)repoKeyValue.get(REPO_SEARCHPATHS);
if (searchPathsList != null) {
repoSearchPaths = searchPathsList.values().toArray(new String[searchPathsList.values().size()]);
if (pattern == null || pattern.length == 0) {
return null;
}
if (PatternMatchUtils.simpleMatch(repoPatterns, application)) {
repo = repoCache.get(repoPatternsList);
if (repo == null) {
repo = createJGitEnvironmentRepository(repoUri, repoUsername,
repoPassword, repoSearchPaths);
synchronized (repoCache) {
repoCache.put(repoPatternsList, repo);
}
}
break;
if (PatternMatchUtils.simpleMatch(pattern, application)) {
return super.findOne(application, profile, label);
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getPattern() {
return pattern;
}
public void setPattern(String[] pattern) {
this.pattern = pattern;
}
return repo.findOne(application, profile, label);
}
private JGitEnvironmentRepository createJGitEnvironmentRepository(String uri,
String username, String password, String[] searchPaths) {
JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment);
repo.setUri(uri);
repo.setUsername(username);
repo.setPassword(password);
repo.setSearchPaths(searchPaths);
return repo;
}
}

View File

@@ -20,9 +20,7 @@ import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.util.FileUtils;
@@ -78,18 +76,27 @@ public class MultipleJGitEnvironmentRepositoryIntegrationTests {
String test1RepoUri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo");
Map<String, Object> repoMapping = new LinkedHashMap<String, Object>();
repoMapping.put("patterns", "*test1*");
repoMapping.put("uri", test1RepoUri);
List<Map<String, Object>> repoMappings = new ArrayList<Map<String, Object>>();
repoMappings.add(repoMapping);
Map<String, Object> reposProperties = new LinkedHashMap<String, Object>();
reposProperties.put("spring.cloud.config.server.git.repos", repoMappings);
repoMapping.put("spring.cloud.config.server.git.repos[test1].pattern", "*test1*");
repoMapping.put("spring.cloud.config.server.git.repos[test1].uri", test1RepoUri);
context = new SpringApplicationBuilder(TestConfiguration.class).web(false)
.properties("spring.cloud.config.server.git.uri:" + defaultRepoUri)
.properties(reposProperties).run();
.properties(repoMapping).run();
EnvironmentRepository repository = context.getBean(EnvironmentRepository.class);
repository.findOne("test1-svc", "staging", "master");
Environment environment = repository.findOne("test1-svc", "staging", "master");
assertEquals(2, environment.getPropertySources().size());
}
@Test
public void mappingRepoWithJustUri() throws IOException {
String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");
String test1RepoUri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo");
Map<String, Object> repoMapping = new LinkedHashMap<String, Object>();
repoMapping.put("spring.cloud.config.server.git.repos.test1-svc", test1RepoUri);
context = new SpringApplicationBuilder(TestConfiguration.class).web(false)
.properties("spring.cloud.config.server.git.uri:" + defaultRepoUri)
.properties(repoMapping).run();
EnvironmentRepository repository = context.getBean(EnvironmentRepository.class);
repository.findOne("test1-svc", "staging", "master");
Environment environment = repository.findOne("test1-svc", "staging", "master");

View File

@@ -18,14 +18,13 @@ package org.springframework.cloud.config.server;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.config.Environment;
import org.springframework.cloud.config.server.MultipleJGitEnvironmentRepository.PatternMatchingJGitEnvironmentRepository;
import org.springframework.core.env.StandardEnvironment;
/**
@@ -43,24 +42,25 @@ public class MultipleJGitEnvironmentRepositoryTests {
String defaultUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");
repository.setUri(defaultUri);
repository.setRepos(createRepositoryMappings());
repository.setRepos(createRepositories());
}
private List<Map<String, Object>> createRepositoryMappings() throws Exception {
private Map<String, PatternMatchingJGitEnvironmentRepository> createRepositories() throws Exception {
String test1Uri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo");
List<Map<String, Object>> mappings = new ArrayList<Map<String, Object>>();
mappings.add(createRepositoryMapping("*test1*", test1Uri));
Map<String, PatternMatchingJGitEnvironmentRepository> repos = new HashMap<String, PatternMatchingJGitEnvironmentRepository>();
repos.put("test1", createRepository("test1", "*test1*", test1Uri));
return mappings;
return repos;
}
private Map<String, Object> createRepositoryMapping(String pattern, String uri) {
Map<String, Object> repoMapping = new LinkedHashMap<String, Object>();
repoMapping.put("patterns", pattern);
repoMapping.put("uri", uri);
return repoMapping;
private PatternMatchingJGitEnvironmentRepository createRepository(String name, String pattern, String uri) {
PatternMatchingJGitEnvironmentRepository repo = new PatternMatchingJGitEnvironmentRepository();
repo.setEnvironment(environment);
repo.setName(name);
repo.setPattern(new String[] {pattern});
repo.setUri(uri);
return repo;
}
@Test
@@ -112,19 +112,19 @@ public class MultipleJGitEnvironmentRepositoryTests {
public void mappingRepo() {
Environment environment = repository.findOne("test1-svc", "staging", "master");
assertEquals(2, environment.getPropertySources().size());
assertEquals(getUri("*test1*") + "test1-svc.properties", environment
assertEquals(getUri("*test1*") + "/test1-svc.properties", environment
.getPropertySources().get(0).getName());
}
private String getUri(String pattern) {
String uri = null;
List<Map<String, Object>> repoMappings = repository.getRepos();
Map<String, PatternMatchingJGitEnvironmentRepository> repoMappings = repository.getRepos();
for (Map<String, Object> mapping : repoMappings) {
String mappingPattern = (String)mapping.get("patterns");
if (mappingPattern != null) {
uri = (String)mapping.get("uri");
for (PatternMatchingJGitEnvironmentRepository repo : repoMappings.values()) {
String[] mappingPattern = repo.getPattern();
if (mappingPattern != null && mappingPattern.length!=0) {
uri = repo.getUri();
break;
}
}