Support for multiple profiles in profile placeholders
In a file-based repository up to now we only support single profiles in a placeholder. This change adds full support for multiple profiles in the native profile and slightly limited support for git backends (only the first profile to match an actual repository will be used to locate the physical repository, but all profiles will be applied to the search inside that repository).
This commit is contained in:
@@ -87,17 +87,24 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
public Locations getLocations(String application, String profile, String label) {
|
||||
for (PatternMatchingJGitEnvironmentRepository repository : this.repos.values()) {
|
||||
if (repository.matches(application, profile, label)) {
|
||||
JGitEnvironmentRepository candidate = getRepository(repository,
|
||||
application, profile, label);
|
||||
Environment source = candidate.findOne(application, profile, label);
|
||||
if (source != null) {
|
||||
return repository.getLocations(application, profile, label);
|
||||
for (JGitEnvironmentRepository candidate : getRepositories(repository,
|
||||
application, profile, label)) {
|
||||
try {
|
||||
Environment source = candidate.findOne(application, profile,
|
||||
label);
|
||||
if (source != null) {
|
||||
return candidate.getLocations(application, profile, label);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JGitEnvironmentRepository candidate = getRepository(this,
|
||||
application, profile, label);
|
||||
if (candidate==this) {
|
||||
JGitEnvironmentRepository candidate = getRepository(this, application, profile,
|
||||
label);
|
||||
if (candidate == this) {
|
||||
return super.getLocations(application, profile, label);
|
||||
}
|
||||
return candidate.getLocations(application, profile, label);
|
||||
@@ -107,35 +114,56 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
public Environment findOne(String application, String profile, String label) {
|
||||
for (PatternMatchingJGitEnvironmentRepository repository : this.repos.values()) {
|
||||
if (repository.matches(application, profile, label)) {
|
||||
JGitEnvironmentRepository candidate = getRepository(repository,
|
||||
application, profile, label);
|
||||
Environment source = candidate.findOne(application, profile, label);
|
||||
if (source != null) {
|
||||
return source;
|
||||
for (JGitEnvironmentRepository candidate : getRepositories(repository,
|
||||
application, profile, label)) {
|
||||
try {
|
||||
Environment source = candidate.findOne(application, profile,
|
||||
label);
|
||||
if (source != null) {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.logger.info(
|
||||
"Cannot load configuration from " + candidate.getUri());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JGitEnvironmentRepository candidate = getRepository(this,
|
||||
application, profile, label);
|
||||
if (candidate==this) {
|
||||
JGitEnvironmentRepository candidate = getRepository(this, application, profile,
|
||||
label);
|
||||
if (candidate == this) {
|
||||
return super.findOne(application, profile, label);
|
||||
}
|
||||
return candidate.findOne(application, profile, label);
|
||||
}
|
||||
|
||||
private List<JGitEnvironmentRepository> getRepositories(
|
||||
JGitEnvironmentRepository repository, String application, String profile,
|
||||
String label) {
|
||||
List<JGitEnvironmentRepository> list = new ArrayList<>();
|
||||
String[] profiles = profile == null ? new String[] { null }
|
||||
: StringUtils.commaDelimitedListToStringArray(profile);
|
||||
for (int i = profiles.length; i-- > 0;) {
|
||||
list.add(getRepository(repository, application, profiles[i], label));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private JGitEnvironmentRepository getRepository(JGitEnvironmentRepository repository,
|
||||
String application, String profile, String label) {
|
||||
if (!repository.getUri().contains("{")) {
|
||||
return repository;
|
||||
}
|
||||
String key = repository.getUri();
|
||||
if (application!=null) {
|
||||
if (application != null) {
|
||||
key = key.replace("{application}", application);
|
||||
}
|
||||
if (profile!=null) {
|
||||
if (profile != null) {
|
||||
key = key.replace("{profile}", profile);
|
||||
}
|
||||
if (label!=null) {
|
||||
if (label != null) {
|
||||
key = key.replace("{label}", label);
|
||||
}
|
||||
if (!this.repos.containsKey(key)) {
|
||||
@@ -173,10 +201,12 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
if (this.pattern == null || this.pattern.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PatternMatchUtils.simpleMatch(this.pattern,
|
||||
application + "/" + profile)) {
|
||||
return true;
|
||||
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
|
||||
for (int i = profiles.length; i-- > 0;) {
|
||||
if (PatternMatchUtils.simpleMatch(this.pattern,
|
||||
application + "/" + profiles[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,21 +122,27 @@ public class NativeEnvironmentRepository
|
||||
}
|
||||
List<String> output = new ArrayList<String>();
|
||||
for (String location : locations) {
|
||||
String value = location;
|
||||
if (application != null) {
|
||||
value = value.replace("{application}", application);
|
||||
}
|
||||
String[] profiles = new String[] { profile };
|
||||
if (profile != null) {
|
||||
value = value.replace("{profile}", profile);
|
||||
profiles = StringUtils.commaDelimitedListToStringArray(profile);
|
||||
}
|
||||
if (label != null) {
|
||||
value = value.replace("{label}", label);
|
||||
}
|
||||
if (!value.endsWith("/")) {
|
||||
value = value + "/";
|
||||
}
|
||||
if (isDirectory(value)) {
|
||||
output.add(value);
|
||||
for (String prof : profiles) {
|
||||
String value = location;
|
||||
if (application != null) {
|
||||
value = value.replace("{application}", application);
|
||||
}
|
||||
if (prof != null) {
|
||||
value = value.replace("{profile}", prof);
|
||||
}
|
||||
if (label != null) {
|
||||
value = value.replace("{label}", label);
|
||||
}
|
||||
if (!value.endsWith("/")) {
|
||||
value = value + "/";
|
||||
}
|
||||
if (isDirectory(value)) {
|
||||
output.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String location : locations) {
|
||||
@@ -175,9 +181,10 @@ public class NativeEnvironmentRepository
|
||||
.cleanPath(new File(normal.substring("file:".length()))
|
||||
.getAbsolutePath());
|
||||
}
|
||||
String profile = result.getProfiles() == null ? null : StringUtils.arrayToCommaDelimitedString(result.getProfiles());
|
||||
for (String pattern : getLocations(result.getName(), profile, result.getLabel())
|
||||
.getLocations()) {
|
||||
String profile = result.getProfiles() == null ? null
|
||||
: StringUtils.arrayToCommaDelimitedString(result.getProfiles());
|
||||
for (String pattern : getLocations(result.getName(), profile,
|
||||
result.getLabel()).getLocations()) {
|
||||
if (!pattern.contains(":")) {
|
||||
pattern = "file:" + pattern;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,11 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.PatternMatchingJGitEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.SearchPathLocator.Locations;
|
||||
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
@@ -33,7 +35,7 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class MultipleJGitEnvironmentUriTemplateRepositoryTests {
|
||||
public class MultipleJGitEnvironmentApplicationPlaceholderRepositoryTests {
|
||||
|
||||
private StandardEnvironment environment = new StandardEnvironment();
|
||||
private MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(
|
||||
@@ -76,6 +78,17 @@ public class MultipleJGitEnvironmentUriTemplateRepositoryTests {
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingRepo() {
|
||||
Environment environment = this.repository.findOne("missing-config-repo",
|
||||
"staging", "master");
|
||||
assertEquals("Wrong property sources: " + environment, 1,
|
||||
environment.getPropertySources().size());
|
||||
assertEquals(this.repository.getUri() + "/application.yml",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mappingRepo() {
|
||||
Environment environment = this.repository.findOne("test1-config-repo", "staging",
|
||||
@@ -100,6 +113,16 @@ public class MultipleJGitEnvironmentUriTemplateRepositoryTests {
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("not supported yet (placeholders in search paths)")
|
||||
public void profilesInSearchPaths() {
|
||||
this.repository.setSearchPaths("{profile}");
|
||||
Locations locations = this.repository.getLocations("foo", "dev,one,two",
|
||||
"master");
|
||||
assertEquals(3, locations.getLocations().length);
|
||||
assertEquals("classpath:/test/dev/", locations.getLocations()[0]);
|
||||
}
|
||||
|
||||
private void assertVersion(Environment environment) {
|
||||
String version = environment.getVersion();
|
||||
assertNotNull("version was null", version);
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.config.server.environment;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.PatternMatchingJGitEnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.SearchPathLocator.Locations;
|
||||
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class MultipleJGitEnvironmentProfilePlaceholderRepositoryTests {
|
||||
|
||||
private StandardEnvironment environment = new StandardEnvironment();
|
||||
private MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(
|
||||
this.environment);
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
String defaultUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");
|
||||
this.repository.setUri(defaultUri);
|
||||
this.repository.setRepos(createRepositories());
|
||||
}
|
||||
|
||||
private Map<String, PatternMatchingJGitEnvironmentRepository> createRepositories()
|
||||
throws Exception {
|
||||
String test1Uri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo");
|
||||
ConfigServerTestUtils.prepareLocalRepo("test2-config-repo");
|
||||
|
||||
Map<String, PatternMatchingJGitEnvironmentRepository> repos = new HashMap<>();
|
||||
repos.put("templates", createRepository("test", "*-config-repo",
|
||||
test1Uri.replace("test1-config-repo", "{profile}")));
|
||||
return repos;
|
||||
}
|
||||
|
||||
private PatternMatchingJGitEnvironmentRepository createRepository(String name,
|
||||
String pattern, String uri) {
|
||||
PatternMatchingJGitEnvironmentRepository repo = new PatternMatchingJGitEnvironmentRepository();
|
||||
repo.setEnvironment(this.environment);
|
||||
repo.setName(name);
|
||||
repo.setPattern(new String[] { pattern });
|
||||
repo.setUri(uri);
|
||||
return repo;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRepo() {
|
||||
Environment environment = this.repository.findOne("bar", "staging", "master");
|
||||
assertEquals(2, environment.getPropertySources().size());
|
||||
assertEquals(this.repository.getUri() + "/bar.properties",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mappingRepo() {
|
||||
Environment environment = this.repository.findOne("application",
|
||||
"test1-config-repo", "master");
|
||||
assertEquals(1, environment.getPropertySources().size());
|
||||
assertEquals(
|
||||
getUri("*").replace("{profile}", "test1-config-repo")
|
||||
+ "/application.yml",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void otherMappingRepo() {
|
||||
Environment environment = this.repository.findOne("application",
|
||||
"test2-config-repo", "master");
|
||||
assertEquals(1, environment.getPropertySources().size());
|
||||
assertEquals(
|
||||
getUri("*").replace("{profile}", "test2-config-repo")
|
||||
+ "/application.properties",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
assertVersion(environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locationsTwoProfiles() throws Exception {
|
||||
Locations locations = this.repository.getLocations("application",
|
||||
"test1-config-repo,test2-config-repo", "master");
|
||||
assertEquals(1, locations.getLocations().length);
|
||||
assertEquals(
|
||||
new File(getUri("*").replace("{profile}", "test2-config-repo")
|
||||
.replace("file:", "")).getCanonicalPath(),
|
||||
new File(locations.getLocations()[0].replace("file:", ""))
|
||||
.getCanonicalPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locationsMissingProfile() throws Exception {
|
||||
Locations locations = this.repository.getLocations("application",
|
||||
"not-there,another-not-there", "master");
|
||||
assertEquals(1, locations.getLocations().length);
|
||||
assertEquals(
|
||||
new File(this.repository.getUri().replace("file:", ""))
|
||||
.getCanonicalPath(),
|
||||
new File(locations.getLocations()[0].replace("file:", ""))
|
||||
.getCanonicalPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoMappingRepos() {
|
||||
Environment environment = this.repository.findOne("application",
|
||||
"test1-config-repo,test2-config-repo,missing-config-repo", "master");
|
||||
assertEquals(1, environment.getPropertySources().size());
|
||||
assertEquals(
|
||||
getUri("*").replace("{profile}", "test2-config-repo")
|
||||
+ "/application.properties",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
assertVersion(environment);
|
||||
assertArrayEquals(environment.getProfiles(), new String[] { "test1-config-repo",
|
||||
"test2-config-repo", "missing-config-repo" });
|
||||
}
|
||||
|
||||
private void assertVersion(Environment environment) {
|
||||
String version = environment.getVersion();
|
||||
assertNotNull("version was null", version);
|
||||
assertTrue("version length was wrong",
|
||||
version.length() >= 40 && version.length() <= 64);
|
||||
}
|
||||
|
||||
private String getUri(String pattern) {
|
||||
String uri = null;
|
||||
|
||||
Map<String, PatternMatchingJGitEnvironmentRepository> repoMappings = this.repository
|
||||
.getRepos();
|
||||
|
||||
for (PatternMatchingJGitEnvironmentRepository repo : repoMappings.values()) {
|
||||
String[] mappingPattern = repo.getPattern();
|
||||
if (mappingPattern != null && mappingPattern.length != 0) {
|
||||
uri = repo.getUri();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,15 @@ public class NativeEnvironmentRepositoryTests {
|
||||
environment.getPropertySources().get(0).getSource().get("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void placeholdersProfiles() {
|
||||
this.repository.setSearchLocations("classpath:/test/{profile}/");
|
||||
Environment environment = this.repository.findOne("foo", "dev,mysql", "master");
|
||||
assertEquals(2, environment.getPropertySources().size());
|
||||
assertEquals("mysql",
|
||||
environment.getPropertySources().get(0).getSource().get("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void placeholdersApplicationAndProfile() {
|
||||
this.repository.setSearchLocations("classpath:/test/{profile}/{application}/");
|
||||
@@ -127,6 +136,14 @@ public class NativeEnvironmentRepositoryTests {
|
||||
assertEquals("classpath:/test/foo/", locations.getLocations()[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locationProfilesApplication() {
|
||||
this.repository.setSearchLocations("classpath:/test/{profile}");
|
||||
Locations locations = this.repository.getLocations("foo", "dev,one,two", "master");
|
||||
assertEquals(3, locations.getLocations().length);
|
||||
assertEquals("classpath:/test/dev/", locations.getLocations()[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void placeholdersNoTrailingSlash() {
|
||||
this.repository.setSearchLocations("classpath:/test/{label}");
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
foo:mysql
|
||||
Reference in New Issue
Block a user