From 897ad1face61321cd36776163fb3963a7993d98e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Feb 2015 15:49:35 +0000 Subject: [PATCH] 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 --- .../main/asciidoc/spring-cloud-config.adoc | 19 +- .../server/ConfigServerMvcConfiguration.java | 1 - .../server/EnvironmentRepositories.java | 26 --- .../server/JGitEnvironmentRepository.java | 12 +- .../MultipleJGitEnvironmentRepository.java | 168 ++++++++---------- ...EnvironmentRepositoryIntegrationTests.java | 31 ++-- ...ultipleJGitEnvironmentRepositoryTests.java | 40 ++--- 7 files changed, 138 insertions(+), 159 deletions(-) delete mode 100644 spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositories.java diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index badb822a..dc80aea6 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -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 diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerMvcConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerMvcConfiguration.java index e479aad6..8f5db3d5 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerMvcConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerMvcConfiguration.java @@ -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; diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositories.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositories.java deleted file mode 100644 index b73fe4a6..00000000 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositories.java +++ /dev/null @@ -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(); - } -} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java index 170964fd..bea29da7 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java @@ -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(); diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepository.java index 2a0bfed2..f60d22ac 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepository.java @@ -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 repos = new LinkedHashMap(); - private String uri; - private String username; - private String password; - private String[] searchPaths = new String[0]; - - private List> repos = new ArrayList>(); - private Map repoCache = new LinkedHashMap(); - 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 repos) { + this.repos.putAll(repos); } - public void setRepos(List> repos) { - this.repos.addAll(repos); - } - - public List> getRepos() { + public Map 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 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 searchPathsList = (LinkedHashMap)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; - } } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryIntegrationTests.java index 474924ea..bd4c62a8 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryIntegrationTests.java @@ -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 repoMapping = new LinkedHashMap(); - repoMapping.put("patterns", "*test1*"); - repoMapping.put("uri", test1RepoUri); - - List> repoMappings = new ArrayList>(); - repoMappings.add(repoMapping); - - Map reposProperties = new LinkedHashMap(); - 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 repoMapping = new LinkedHashMap(); + 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"); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryTests.java index 9179425b..278ed602 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/MultipleJGitEnvironmentRepositoryTests.java @@ -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> createRepositoryMappings() throws Exception { + private Map createRepositories() throws Exception { String test1Uri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo"); - List> mappings = new ArrayList>(); - mappings.add(createRepositoryMapping("*test1*", test1Uri)); + Map repos = new HashMap(); + repos.put("test1", createRepository("test1", "*test1*", test1Uri)); - return mappings; + return repos; } - private Map createRepositoryMapping(String pattern, String uri) { - Map repoMapping = new LinkedHashMap(); - 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> repoMappings = repository.getRepos(); + Map repoMappings = repository.getRepos(); - for (Map 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; } }