Add GIT repository support
Default to a scratch repository on github:
$ curl localhost:8888/foo/development
{"name":"development","label":"master","propertySources":[
{"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
{"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
]}
This commit is contained in:
@@ -59,6 +59,9 @@ public class BootstrapApplicationListener implements
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
Environment environment = event.getEnvironment();
|
||||
if (!environment.getProperty("spring.platform.bootstrap.enabled", Boolean.class, true)) {
|
||||
return;
|
||||
}
|
||||
if (environment instanceof ConfigurableEnvironment) {
|
||||
ConfigurableEnvironment configurable = (ConfigurableEnvironment) environment;
|
||||
// don't listen to events in a bootstrap context
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -37,6 +38,7 @@ public class Application {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Profile("native")
|
||||
protected static class NativeRepositoryConfiguration {
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
@@ -46,4 +48,13 @@ public class Application {
|
||||
return new NativeEnvironmentRepository(environment);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Profile("!native")
|
||||
protected static class GitRepositoryConfiguration {
|
||||
@Bean
|
||||
public JGitEnvironmentRepository repository() {
|
||||
return new JGitEnvironmentRepository();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.platform.config.server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
import org.springframework.platform.bootstrap.config.PropertySource;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JGitEnvironmentRepository implements EnvironmentRepository {
|
||||
|
||||
public static final String DEFAULT_URI = "https://github.com/scratches/config-repo";
|
||||
|
||||
private File basedir;
|
||||
|
||||
private String uri = DEFAULT_URI;
|
||||
|
||||
public JGitEnvironmentRepository() {
|
||||
try {
|
||||
basedir = Files.createTempDirectory("config-repo-").toFile();
|
||||
basedir.deleteOnExit();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Cannot create temp dir", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
while (uri.endsWith("/")) {
|
||||
uri = uri.substring(0, uri.length() - 1);
|
||||
}
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String name, String label) {
|
||||
try {
|
||||
Git git;
|
||||
if (new File(basedir, ".git").exists()) {
|
||||
git = Git.open(basedir);
|
||||
} else {
|
||||
git = Git.cloneRepository().setURI(uri).setDirectory(basedir).call();
|
||||
}
|
||||
Environment result;
|
||||
synchronized (this) {
|
||||
SpringApplicationEnvironmentRepository environment = new SpringApplicationEnvironmentRepository();
|
||||
git.checkout().setName(label).call();
|
||||
String search = git.getRepository().getDirectory().getParent();
|
||||
environment.setSearchLocations(search);
|
||||
result = clean(environment.findOne(application, name, label));
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot clone repository", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Environment clean(Environment value) {
|
||||
Environment result = new Environment(value.getName(), value.getLabel());
|
||||
for (PropertySource source : value.getPropertySources()) {
|
||||
String name = source.getName().replace(basedir.toURI().toString(), "");
|
||||
name = name.replace("applicationConfig: [", "");
|
||||
name = uri + "/"
|
||||
+ name.substring(0, name.contains("]") ? name.lastIndexOf("]") : name.length());
|
||||
result.add(new PropertySource(name, source.getSource()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.platform.config.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -27,8 +28,10 @@ import org.springframework.platform.bootstrap.config.Environment;
|
||||
import org.springframework.platform.bootstrap.config.PropertySource;
|
||||
import org.springframework.web.context.support.StandardServletEnvironment;
|
||||
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link EnvironmentRepository} that just reflects an existing
|
||||
* Spring Environment.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@@ -46,14 +49,14 @@ public class NativeEnvironmentRepository implements EnvironmentRepository {
|
||||
public NativeEnvironmentRepository(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String env, String label) {
|
||||
Environment result = new Environment(env, label);
|
||||
for (org.springframework.core.env.PropertySource<?> source : environment.getPropertySources()) {
|
||||
String name = source.getName();
|
||||
if (!standardSources .contains(name) && source instanceof MapPropertySource) {
|
||||
result.add(new PropertySource(name, (Map<?,?>)source.getSource()));
|
||||
if (!standardSources.contains(name) && source instanceof MapPropertySource) {
|
||||
result.add(new PropertySource(name, (Map<?, ?>) source.getSource()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.platform.config.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of {@link EnvironmentRepository} that uses a SpringApplication
|
||||
* and configuration files located through the normal protocols. The resulting Environment
|
||||
* is composed of property sources located using the application name as the config file
|
||||
* stem (spring.config.name) and the environment name as a Spring profile.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SpringApplicationEnvironmentRepository implements EnvironmentRepository {
|
||||
|
||||
private String[] locations;
|
||||
|
||||
@Override
|
||||
public Environment findOne(String config, String profile, String label) {
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
builder.profiles(profile.split(",")).web(false).showBanner(false);
|
||||
String[] args = getArgs(config);
|
||||
ConfigurableApplicationContext context = builder.run(args);
|
||||
try {
|
||||
return new NativeEnvironmentRepository(context.getEnvironment()).findOne(
|
||||
config, profile, label);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getArgs(String config) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("--spring.config.name=" + config);
|
||||
list.add("--spring.platform.bootstrap.enabled=false");
|
||||
if (locations != null) {
|
||||
list.add("--spring.config.location="
|
||||
+ StringUtils.arrayToCommaDelimitedString(locations));
|
||||
}
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public void setSearchLocations(String... locations) {
|
||||
this.locations = locations;
|
||||
for (int i = 0; i < locations.length; i++) {
|
||||
String location = locations[i];
|
||||
if (!location.endsWith(".properties") && !location.endsWith(".yml")
|
||||
&& !location.endsWith(".yaml") && !location.endsWith("/")) {
|
||||
location = location + "/";
|
||||
}
|
||||
locations[i] = location;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,30 @@
|
||||
package org.springframework.platform.config.server;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@IntegrationTest("server.port:0")
|
||||
@WebAppConfiguration
|
||||
public class ApplicationTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
Environment environment = new TestRestTemplate().getForObject("http://localhost:" + port + "/foo/development/", Environment.class);
|
||||
assertFalse(environment.getPropertySources().isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.platform.config.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JGitEnvironmentRepositoryTests {
|
||||
|
||||
private JGitEnvironmentRepository repository = new JGitEnvironmentRepository();
|
||||
|
||||
@Test
|
||||
public void vanilla() {
|
||||
repository.findOne("bar", "staging", "master");
|
||||
Environment environment = repository.findOne("bar", "staging", "master");
|
||||
assertEquals(1, environment.getPropertySources().size());
|
||||
assertEquals(JGitEnvironmentRepository.DEFAULT_URI + "/bar.properties",
|
||||
environment.getPropertySources().get(0).getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.platform.config.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.platform.bootstrap.config.Environment;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SpringApplicationEnvironmentRepositoryTests {
|
||||
|
||||
private SpringApplicationEnvironmentRepository repository = new SpringApplicationEnvironmentRepository();
|
||||
|
||||
@Test
|
||||
public void vanilla() {
|
||||
Environment environment = repository.findOne("foo", "development", "master");
|
||||
assertEquals(2, environment.getPropertySources().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixed() {
|
||||
repository.setSearchLocations("classpath:/test");
|
||||
Environment environment = repository.findOne("foo", "development", "master");
|
||||
assertEquals(3, environment.getPropertySources().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixedWithFile() {
|
||||
repository.setSearchLocations("file:./src/test/resources/test");
|
||||
Environment environment = repository.findOne("foo", "development", "master");
|
||||
assertEquals(3, environment.getPropertySources().size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
bar: spam
|
||||
@@ -0,0 +1 @@
|
||||
foo: bar
|
||||
@@ -0,0 +1 @@
|
||||
foo: test_bar
|
||||
Reference in New Issue
Block a user