diff --git a/docs/pom.xml b/docs/pom.xml index be074579..557d6a03 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -14,7 +14,7 @@ spring-cloud-config ${basedir}/.. - 1.1.x + 1.3.x diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index d2bd9dd7..2f3ef071 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -479,8 +479,9 @@ on the search path, so properties files are loaded from each search location *and* a subdirectory with the same name as the label (the labelled properties take precedence in the Spring Environment). Thus the default behaviour with no placeholders is the same as adding a -search location ending with `/{label}/. For example `file:/tmp/config` -is the same as `file:/tmp/config,file:/tmp/config/{label}` +search location ending with `/{label}/`. For example `file:/tmp/config` +is the same as `file:/tmp/config,file:/tmp/config/{label}`. This behavior can be +disabled by setting `spring.cloud.config.server.native.addLabelLocations=false`. ==== Vault Backend @@ -1308,23 +1309,13 @@ the client. Typically this involves passing special `Authorization` headers to authenticate requests to the server. To provide a custom `RestTemplate` follow the steps below. -1. Set `spring.cloud.config.enabled=false` to disable the existing config server -property source. - -2. Create a new configuration bean with an implementation of `PropertySourceLocator`. +1. Create a new configuration bean with an implementation of `PropertySourceLocator`. .CustomConfigServiceBootstrapConfiguration.java [source,java] ---- @Configuration public class CustomConfigServiceBootstrapConfiguration { - @Bean - public ConfigClientProperties configClientProperties() { - ConfigClientProperties client = new ConfigClientProperties(this.environment); - client.setEnabled(false); - return client; - } - @Bean public ConfigServicePropertySourceLocator configServicePropertySourceLocator() { ConfigClientProperties clientProperties = configClientProperties(); @@ -1335,10 +1326,10 @@ public class CustomConfigServiceBootstrapConfiguration { } ---- -3. In `resources/META-INF` create a file called +2. In `resources/META-INF` create a file called `spring.factories` and specify your custom configuration. -.spring.factorties +.spring.factories [source,properties] ---- org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration diff --git a/mvnw.cmd b/mvnw.cmd index fc830243..b0dc0e7e 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,145 +1,145 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -set MAVEN_CMD_LINE_ARGS=%* - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java index 909d4070..7b60a21c 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 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. @@ -34,6 +34,7 @@ import org.springframework.retry.interceptor.RetryOperationsInterceptor; /** * @author Dave Syer + * @author Tristan Hanson * */ @Configuration @@ -50,6 +51,7 @@ public class ConfigServiceBootstrapConfiguration { } @Bean + @ConditionalOnMissingBean(ConfigServicePropertySourceLocator.class) @ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true) public ConfigServicePropertySourceLocator configServicePropertySource(ConfigClientProperties properties) { ConfigServicePropertySourceLocator locator = new ConfigServicePropertySourceLocator( diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfigurationTest.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfigurationTest.java new file mode 100644 index 00000000..fa9edb7b --- /dev/null +++ b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfigurationTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013-2017 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.client; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.client.RestTemplate; + +import java.lang.reflect.Field; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Tristan Hanson + * + */ +public class ConfigServiceBootstrapConfigurationTest { + + private AnnotationConfigApplicationContext context; + + @Before + public void setUp() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + } + + @After + public void tearDown() throws Exception { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void overrideConfigServicePropertySourceLocatorWhenBeanIsProvided() { + EnvironmentTestUtils.addEnvironment(this.context, "spring.cloud.config.enabled=true"); + this.context.register(ConfigServicePropertySourceLocatorOverrideConfig.class); + this.context.register(ConfigServiceBootstrapConfiguration.class); + this.context.refresh(); + + ConfigServicePropertySourceLocator locator = this.context.getBean(ConfigServicePropertySourceLocator.class); + + Field restTemplateField = ReflectionUtils.findField(ConfigServicePropertySourceLocator.class, "restTemplate"); + restTemplateField.setAccessible(true); + + RestTemplate restTemplate = (RestTemplate) ReflectionUtils.getField(restTemplateField, locator); + + assertThat(restTemplate).isNotNull(); + } + + @Configuration + protected static class ConfigServicePropertySourceLocatorOverrideConfig { + + @Autowired + private Environment environment; + + @Bean + public ConfigServicePropertySourceLocator locator() { + ConfigServicePropertySourceLocator locator = new ConfigServicePropertySourceLocator(new ConfigClientProperties(environment)); + locator.setRestTemplate(new RestTemplate()); + return locator; + } + + } + +} \ No newline at end of file diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java index 326cb108..bc5c1d32 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java @@ -15,17 +15,24 @@ */ package org.springframework.cloud.config.server.bootstrap; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.config.client.ConfigClientProperties; import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.config.server.config.EncryptionAutoConfiguration; import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration; +import org.springframework.cloud.config.server.encryption.LocatorTextEncryptor; import org.springframework.cloud.config.server.environment.EnvironmentRepository; import org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.security.crypto.encrypt.TextEncryptor; import org.springframework.util.StringUtils; /** @@ -39,9 +46,28 @@ import org.springframework.util.StringUtils; * @author Roy Clarkson */ @Configuration -public class ConfigServerBootstrapConfiguration { +@ConditionalOnProperty("spring.cloud.config.server.bootstrap") +@AutoConfigureBefore(EncryptionAutoConfiguration.class) +public class ConfigServerBootstrapConfiguration implements BeanPostProcessor { + + @Autowired + private BeanFactory beanFactory; + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof TextEncryptor && !(bean instanceof LocatorTextEncryptor)) { + return new LocatorTextEncryptor(beanFactory); + } + return bean; + } - @ConditionalOnProperty("spring.cloud.config.server.bootstrap") @EnableConfigurationProperties(ConfigServerProperties.class) @Import(EnvironmentRepositoryConfiguration.class) protected static class LocalPropertySourceLocatorConfiguration { diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java index 4733911e..d66fe444 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.cloud.config.server.config; import javax.servlet.http.HttpServletRequest; +import org.eclipse.jgit.api.TransportConfigCallback; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -83,10 +84,14 @@ class DefaultRepositoryConfiguration { @Autowired private ConfigServerProperties server; + @Autowired(required = false) + private TransportConfigCallback transportConfigCallback; + @Bean public MultipleJGitEnvironmentRepository defaultEnvironmentRepository() { MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository( this.environment); + repository.setTransportConfigCallback(this.transportConfigCallback); if (this.server.getDefaultLabel() != null) { repository.setDefaultLabel(this.server.getDefaultLabel()); } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/LocatorTextEncryptor.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/LocatorTextEncryptor.java new file mode 100644 index 00000000..6c4b5497 --- /dev/null +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/LocatorTextEncryptor.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-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.encryption; + +import java.util.Map; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.security.crypto.encrypt.TextEncryptor; + +/** + * @author Dave Syer + * + */ +public class LocatorTextEncryptor implements TextEncryptor { + + private EnvironmentPrefixHelper helper = new EnvironmentPrefixHelper(); + + private TextEncryptorLocator locator; + + private BeanFactory beanFactory; + + public LocatorTextEncryptor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public String encrypt(String text) { + Map keys = helper.getEncryptorKeys("configserver", "default", + text); + return getLocator().locate(keys).encrypt(helper.stripPrefix(text)); + } + + private TextEncryptorLocator getLocator() { + if (locator == null) { + locator = beanFactory.getBean(TextEncryptorLocator.class); + } + return locator; + } + + @Override + public String decrypt(String encryptedText) { + Map keys = helper.getEncryptorKeys("configserver", "default", + encryptedText); + return getLocator().locate(keys).decrypt(helper.stripPrefix(encryptedText)); + } + +} \ No newline at end of file diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepository.java index 77d2f44f..f58509f2 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepository.java @@ -41,8 +41,15 @@ public class CompositeEnvironmentRepository implements EnvironmentRepository { @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.addAll(repo.findOne(application, profile, label).getPropertySources()); + if(environmentRepositories.size() == 1) { + Environment envRepo = environmentRepositories.get(0).findOne(application, profile, label); + env.addAll(envRepo.getPropertySources()); + env.setVersion(envRepo.getVersion()); + env.setState(envRepo.getState()); + } else { + for (EnvironmentRepository repo : environmentRepositories) { + env.addAll(repo.findOne(application, profile, label).getPropertySources()); + } } return env; } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java index b5f6e53d..f5d20db1 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java @@ -42,6 +42,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.yaml.snakeyaml.DumperOptions.FlowStyle; import org.yaml.snakeyaml.Yaml; @@ -223,7 +224,7 @@ public class EnvironmentController { return rootMap; } - @ExceptionHandler(NoSuchLabelException.class) + @ExceptionHandler(RepositoryException.class) public void noSuchLabel(HttpServletResponse response) throws IOException { response.sendError(HttpStatus.NOT_FOUND.value()); } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java index 45b460b2..c28370de 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java @@ -36,8 +36,10 @@ import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.api.Status; import org.eclipse.jgit.api.StatusCommand; import org.eclipse.jgit.api.TransportCommand; +import org.eclipse.jgit.api.TransportConfigCallback; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.RefNotFoundException; +import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.FetchResult; @@ -74,31 +76,36 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository private static final String FILE_URI_PREFIX = "file:"; /** - * Timeout (in seconds) for obtaining HTTP or SSH connection (if applicable). Default - * 5 seconds. + * Timeout (in seconds) for obtaining HTTP or SSH connection (if + * applicable). Default 5 seconds. */ private int timeout = 5; private boolean initialized; /** - * Flag to indicate that the repository should be cloned on startup (not on demand). - * Generally leads to slower startup but faster first query. + * Flag to indicate that the repository should be cloned on startup (not on + * demand). Generally leads to slower startup but faster first query. */ private boolean cloneOnStart = false; private JGitEnvironmentRepository.JGitFactory gitFactory = new JGitEnvironmentRepository.JGitFactory(); private String defaultLabel = DEFAULT_LABEL; - + /** * The credentials provider to use to connect to the Git repository. */ private CredentialsProvider gitCredentialsProvider; /** - * Flag to indicate that the repository should force pull. If true discard any local - * changes and take from remote repository. + * Transport configuration callback for JGit commands. + */ + private TransportConfigCallback transportConfigCallback; + + /** + * Flag to indicate that the repository should force pull. If true discard + * any local changes and take from remote repository. */ private boolean forcePull; @@ -122,6 +129,14 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository this.timeout = timeout; } + public TransportConfigCallback getTransportConfigCallback() { + return transportConfigCallback; + } + + public void setTransportConfigCallback(TransportConfigCallback transportConfigCallback) { + this.transportConfigCallback = transportConfigCallback; + } + public JGitFactory getGitFactory() { return this.gitFactory; } @@ -147,8 +162,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } @Override - public synchronized Locations getLocations(String application, String profile, - String label) { + public synchronized Locations getLocations(String application, String profile, String label) { if (label == null) { label = this.defaultLabel; } @@ -159,8 +173,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository @Override public void afterPropertiesSet() throws Exception { - Assert.state(getUri() != null, - "You need to configure a uri for the git repository"); + Assert.state(getUri() != null, "You need to configure a uri for the git repository"); initialize(); if (this.cloneOnStart) { initClonedRepository(); @@ -177,41 +190,37 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository git = createGitClient(); if (shouldPull(git)) { fetch(git, label); - //checkout after fetch so we can get any new branches, tags, ect. + // checkout after fetch so we can get any new branches, tags, + // ect. checkout(git, label); - if(isBranch(git, label)) { - //merge results from fetch + if (isBranch(git, label)) { + // merge results from fetch merge(git, label); if (!isClean(git)) { - logger.warn("The local repository is dirty. Resetting it to origin/" - + label + "."); + logger.warn("The local repository is dirty. Resetting it to origin/" + label + "."); resetHard(git, label, "refs/remotes/origin/" + label); } } - } - else{ - //nothing to update so just checkout + } else { + // nothing to update so just checkout checkout(git, label); } - //always return what is currently HEAD as the version - return git.getRepository().getRef("HEAD").getObjectId().getName(); - } - catch (RefNotFoundException e) { + // always return what is currently HEAD as the version + return git.getRepository().findRef("HEAD").getObjectId().getName(); + } catch (RefNotFoundException e) { throw new NoSuchLabelException("No such label: " + label, e); - } - catch (GitAPIException e) { - throw new IllegalStateException("Cannot clone or checkout repository", e); - } - catch (Exception e) { + } catch (NoRemoteRepositoryException e) { + throw new NoSuchRepositoryException("No such repository: " + getUri(), e); + } catch (GitAPIException e) { + throw new NoSuchRepositoryException("Cannot clone or checkout repository: " + getUri(), e); + } catch (Exception e) { throw new IllegalStateException("Cannot load environment", e); - } - finally { + } finally { try { if (git != null) { git.close(); } - } - catch (Exception e) { + } catch (Exception e) { this.logger.warn("Could not close git repository", e); } } @@ -219,6 +228,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository /** * Clones the remote repository and then opens a connection to it. + * * @throws GitAPIException * @throws IOException */ @@ -241,41 +251,35 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository CheckoutCommand checkout = git.checkout(); if (shouldTrack(git, label)) { trackBranch(git, checkout, label); - } - else { + } else { // works for tags and local branches checkout.setName(label); } return checkout.call(); } - - public /*public for testing*/ boolean shouldPull(Git git) throws GitAPIException { + protected boolean shouldPull(Git git) throws GitAPIException { boolean shouldPull; Status gitStatus = git.status().call(); boolean isWorkingTreeClean = gitStatus.isClean(); - String originUrl = git.getRepository().getConfig().getString("remote", "origin", - "url"); + String originUrl = git.getRepository().getConfig().getString("remote", "origin", "url"); if (this.forcePull && !isWorkingTreeClean) { shouldPull = true; logDirty(gitStatus); - } - else { + } else { shouldPull = isWorkingTreeClean && originUrl != null; } if (!isWorkingTreeClean && !this.forcePull) { - this.logger.info("Cannot pull from remote " + originUrl - + ", the working tree is not clean."); + this.logger.info("Cannot pull from remote " + originUrl + ", the working tree is not clean."); } return shouldPull; } @SuppressWarnings("unchecked") private void logDirty(Status status) { - Set dirties = dirties(status.getAdded(), status.getChanged(), - status.getRemoved(), status.getMissing(), status.getModified(), - status.getConflicting(), status.getUntracked()); + Set dirties = dirties(status.getAdded(), status.getChanged(), status.getRemoved(), status.getMissing(), + status.getModified(), status.getConflicting(), status.getUntracked()); this.logger.warn(String.format("Dirty files found: %s", dirties)); } @@ -292,24 +296,22 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository return isBranch(git, label) && !isLocalBranch(git, label); } - private FetchResult fetch(Git git, String label) { + protected FetchResult fetch(Git git, String label) { FetchCommand fetch = git.fetch(); fetch.setRemote("origin"); fetch.setTagOpt(TagOpt.FETCH_TAGS); - setTimeout(fetch); + configureCommand(fetch); try { - setCredentialsProvider(fetch); FetchResult result = fetch.call(); - if(result.getTrackingRefUpdates() != null && result.getTrackingRefUpdates().size() > 0) { + if (result.getTrackingRefUpdates() != null && result.getTrackingRefUpdates().size() > 0) { logger.info("Fetched for remote " + label + " and found " + result.getTrackingRefUpdates().size() - + " updates"); + + " updates"); } return result; - } - catch (Exception ex) { - String message = "Could not fetch remote for " + label + " remote: " + git - .getRepository().getConfig().getString("remote", "origin", "url"); + } catch (Exception ex) { + String message = "Could not fetch remote for " + label + " remote: " + + git.getRepository().getConfig().getString("remote", "origin", "url"); warn(message, ex); return null; } @@ -318,16 +320,15 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository private MergeResult merge(Git git, String label) { try { MergeCommand merge = git.merge(); - merge.include(git.getRepository().getRef("origin/" + label)); + merge.include(git.getRepository().findRef("origin/" + label)); MergeResult result = merge.call(); - if(!result.getMergeStatus().isSuccessful()) { + if (!result.getMergeStatus().isSuccessful()) { this.logger.warn("Merged from remote " + label + " with result " + result.getMergeStatus()); } return result; - } - catch (Exception ex) { - String message = "Could not merge remote for " + label + " remote: " + git - .getRepository().getConfig().getString("remote", "origin", "url"); + } catch (Exception ex) { + String message = "Could not merge remote for " + label + " remote: " + + git.getRepository().getConfig().getString("remote", "origin", "url"); warn(message, ex); return null; } @@ -339,31 +340,38 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository reset.setMode(ResetType.HARD); try { Ref resetRef = reset.call(); - if(resetRef != null) { + if (resetRef != null) { this.logger.info("Reset label " + label + " to version " + resetRef.getObjectId()); } return resetRef; - } - catch (Exception ex) { - String message = "Could not reset to remote for " + label + " (current ref=" - + ref + "), remote: " + git.getRepository().getConfig() - .getString("remote", "origin", "url"); + } catch (Exception ex) { + String message = "Could not reset to remote for " + label + " (current ref=" + ref + "), remote: " + + git.getRepository().getConfig().getString("remote", "origin", "url"); warn(message, ex); return null; } } private Git createGitClient() throws IOException, GitAPIException { - if (new File(getBasedir(), ".git").exists()) { - return openGitRepository(); + File lock = new File(getWorkingDirectory(), ".git/index.lock"); + if (lock.exists()) { + // The only way this can happen is if another JVM (e.g. one that + // crashed earlier) created the lock. We can attempt to recover by + // wiping the slate clean. + logger.info("Deleting stale JGit lock file at " + lock); + lock.delete(); } - else { + if (new File(getWorkingDirectory(), ".git").exists()) { + return openGitRepository(); + } else { return copyRepository(); } } - // Synchronize here so that multiple requests don't all try and delete the base dir - // together (this is a once only operation, so it only holds things up on the first + // Synchronize here so that multiple requests don't all try and delete the + // base dir + // together (this is a once only operation, so it only holds things up on + // the first // request). private synchronized Git copyRepository() throws IOException, GitAPIException { deleteBaseDirIfExists(); @@ -371,8 +379,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository Assert.state(getBasedir().exists(), "Could not create basedir: " + getBasedir()); if (getUri().startsWith(FILE_URI_PREFIX)) { return copyFromLocalRepository(); - } - else { + } else { return cloneToBasedir(); } } @@ -394,14 +401,12 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } private Git cloneToBasedir() throws GitAPIException { - CloneCommand clone = this.gitFactory.getCloneCommandByCloneRepository() - .setURI(getUri()).setDirectory(getBasedir()); - setTimeout(clone); - setCredentialsProvider(clone); + CloneCommand clone = this.gitFactory.getCloneCommandByCloneRepository().setURI(getUri()) + .setDirectory(getBasedir()); + configureCommand(clone); try { return clone.call(); - } - catch (GitAPIException e) { + } catch (GitAPIException e) { deleteBaseDirIfExists(); throw e; } @@ -411,8 +416,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository if (getBasedir().exists()) { try { FileUtils.delete(getBasedir(), FileUtils.RECURSIVE); - } - catch (IOException e) { + } catch (IOException e) { throw new IllegalStateException("Failed to initialize base directory", e); } } @@ -430,28 +434,38 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } } - private void setCredentialsProvider(TransportCommand cmd) { - if (gitCredentialsProvider != null) { - cmd.setCredentialsProvider(gitCredentialsProvider); - } else if (hasText(getUsername())) { - cmd.setCredentialsProvider( - new UsernamePasswordCredentialsProvider(getUsername(), getPassword())); - } else if (hasText(getPassphrase())) { - cmd.setCredentialsProvider( - new PassphraseCredentialsProvider(getPassphrase())); + private void configureCommand(TransportCommand command) { + command.setTimeout(this.timeout); + if (this.transportConfigCallback != null) { + command.setTransportConfigCallback(this.transportConfigCallback); + } + CredentialsProvider credentialsProvider = getCredentialsProvider(); + if (credentialsProvider != null) { + command.setCredentialsProvider(credentialsProvider); } } - private void setTimeout(TransportCommand pull) { - pull.setTimeout(this.timeout); + private CredentialsProvider getCredentialsProvider() { + if (this.gitCredentialsProvider != null) { + return this.gitCredentialsProvider; + } + + if (hasText(getUsername()) && hasText(getPassword())) { + return new UsernamePasswordCredentialsProvider(getUsername(), getPassword()); + } + + if (hasText(getPassphrase())) { + return new PassphraseCredentialsProvider(getPassphrase()); + } + + return null; } private boolean isClean(Git git) { StatusCommand status = git.status(); try { return status.call().isClean(); - } - catch (Exception e) { + } catch (Exception e) { String message = "Could not execute status command on local repository. Cause: (" + e.getClass().getSimpleName() + ") " + e.getMessage(); warn(message, e); @@ -460,8 +474,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } private void trackBranch(Git git, CheckoutCommand checkout, String label) { - checkout.setCreateBranch(true).setName(label) - .setUpstreamMode(SetupUpstreamMode.TRACK) + checkout.setCreateBranch(true).setName(label).setUpstreamMode(SetupUpstreamMode.TRACK) .setStartPoint("origin/" + label); } @@ -473,8 +486,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository return containsBranch(git, label, null); } - private boolean containsBranch(Git git, String label, ListMode listMode) - throws GitAPIException { + private boolean containsBranch(Git git, String label, ListMode listMode) throws GitAPIException { ListBranchCommand command = git.branchList(); if (listMode != null) { command.setListMode(listMode); @@ -497,7 +509,8 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository /** * Wraps the static method calls to {@link org.eclipse.jgit.api.Git} and - * {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit testing. + * {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit + * testing. */ static class JGitFactory { @@ -520,7 +533,8 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } /** - * @param gitCredentialsProvider the gitCredentialsProvider to set + * @param gitCredentialsProvider + * the gitCredentialsProvider to set */ public void setGitCredentialsProvider(CredentialsProvider gitCredentialsProvider) { this.gitCredentialsProvider = gitCredentialsProvider; diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java index eb0eb377..1f19c64d 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java @@ -63,7 +63,7 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository @Override public void afterPropertiesSet() throws Exception { GitCredentialsProviderFactory credentialFactory = new GitCredentialsProviderFactory(); - super.setGitCredentialsProvider(credentialFactory.createFor(getUri(), + super.setGitCredentialsProvider(credentialFactory.createFor(getUri(), getUsername(), getPassword(), getPassphrase())); super.afterPropertiesSet(); for (String name : this.repos.keySet()) { @@ -75,6 +75,9 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository if (repo.getPattern() == null || repo.getPattern().length == 0) { repo.setPattern(new String[] { name }); } + if (repo.getTransportConfigCallback() == null) { + repo.setTransportConfigCallback(getTransportConfigCallback()); + } if (getTimeout() != 0 && repo.getTimeout() == 0) { repo.setTimeout(getTimeout()); } @@ -88,10 +91,20 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository if (passphrase == null) { passphrase = getPassphrase(); } - repo.setGitCredentialsProvider(credentialFactory.createFor(repo.getUri(), - user, pass, passphrase)); + repo.setGitCredentialsProvider( + credentialFactory.createFor(repo.getUri(), user, pass, passphrase)); repo.afterPropertiesSet(); } + if (!getBasedir().exists() && + !getBasedir().mkdirs()) { + throw new IllegalStateException( + "Basedir does not exist and can not be created: " + getBasedir()); + } + if (!getBasedir().getParentFile().canWrite()) { + throw new IllegalStateException( + "Cannot write parent of basedir (please configure a writable location): " + + getBasedir()); + } } public void setRepos(Map repos) { @@ -119,7 +132,8 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository if (logger.isDebugEnabled()) { this.logger.debug("Cannot retrieve resource locations from " + candidate.getUri() + ", cause: (" - + e.getClass().getSimpleName() + ") " + e.getMessage(), e); + + e.getClass().getSimpleName() + ") " + + e.getMessage(), e); } continue; } @@ -141,7 +155,7 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository for (JGitEnvironmentRepository candidate : getRepositories(repository, application, profile, label)) { try { - if (label==null) { + if (label == null) { label = candidate.getDefaultLabel(); } Environment source = candidate.findOne(application, profile, @@ -152,9 +166,11 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository } catch (Exception e) { if (logger.isDebugEnabled()) { - this.logger.debug("Cannot load configuration from " - + candidate.getUri() + ", cause: (" - + e.getClass().getSimpleName() + ") " + e.getMessage(), e); + this.logger.debug( + "Cannot load configuration from " + candidate.getUri() + + ", cause: (" + e.getClass().getSimpleName() + + ") " + e.getMessage(), + e); } continue; } @@ -163,7 +179,7 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository } JGitEnvironmentRepository candidate = getRepository(this, application, profile, label); - if (label==null) { + if (label == null) { label = candidate.getDefaultLabel(); } if (candidate == this) { @@ -191,7 +207,8 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository } String key = repository.getUri(); - // cover the case where label is in the uri, but no label was sent with the request + // cover the case where label is in the uri, but no label was sent with the + // request if (key.contains("{label}") && label == null) { label = repository.getDefaultLabel(); } @@ -216,7 +233,8 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository File basedir = repository.getBasedir(); BeanUtils.copyProperties(source, repository); repository.setUri(uri); - repository.setBasedir(basedir); + repository.setBasedir( + new File(source.getBasedir().getParentFile(), basedir.getName())); return repository; } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java index 7b254b36..870dc869 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2017 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. @@ -19,12 +19,13 @@ package org.springframework.cloud.config.server.environment; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.boot.Banner.Mode; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; @@ -48,6 +49,7 @@ import org.springframework.util.StringUtils; * * @author Dave Syer * @author Roy Clarkson + * @author Venil Noronha */ @ConfigurationProperties("spring.cloud.config.server.native") public class NativeEnvironmentRepository implements EnvironmentRepository, SearchPathLocator, Ordered { @@ -67,6 +69,11 @@ public class NativeEnvironmentRepository implements EnvironmentRepository, Searc */ private boolean failOnError = false; + /** + * Flag to determine whether label locations should be added. + */ + private boolean addLabelLocations = true; + /** * Version string to be reported for native repository */ @@ -91,6 +98,14 @@ public class NativeEnvironmentRepository implements EnvironmentRepository, Searc return this.failOnError; } + public void setAddLabelLocations(boolean addLabelLocations) { + this.addLabelLocations = addLabelLocations; + } + + public boolean isAddLabelLocations() { + return this.addLabelLocations; + } + public String getDefaultLabel() { return DEFAULT_LABEL; } @@ -128,7 +143,7 @@ public class NativeEnvironmentRepository implements EnvironmentRepository, Searc if (this.searchLocations == null || this.searchLocations.length == 0) { locations = DEFAULT_LOCATIONS; } - List output = new ArrayList(); + Collection output = new LinkedHashSet(); for (String location : locations) { String[] profiles = new String[] { profile }; if (profile != null) { @@ -159,11 +174,13 @@ public class NativeEnvironmentRepository implements EnvironmentRepository, Searc } } } - for (String location : locations) { - if (StringUtils.hasText(label)) { - String labelled = location + label.trim() + "/"; - if (isDirectory(labelled)) { - output.add(labelled); + if (this.addLabelLocations) { + for (String location : locations) { + if (StringUtils.hasText(label)) { + String labelled = location + label.trim() + "/"; + if (isDirectory(labelled)) { + output.add(labelled); + } } } } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NoSuchRepositoryException.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NoSuchRepositoryException.java new file mode 100644 index 00000000..19aad8b3 --- /dev/null +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NoSuchRepositoryException.java @@ -0,0 +1,34 @@ +/* + * Copyright 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; + +/** + * @author Dave Syer + * + */ +@SuppressWarnings("serial") +public class NoSuchRepositoryException extends RepositoryException { + + public NoSuchRepositoryException(String string) { + super(string); + } + + public NoSuchRepositoryException(String string, Exception e) { + super(string, e); + } + +} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AwsCodeCommitCredentialProvider.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AwsCodeCommitCredentialProvider.java index 7425067e..1653d72f 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AwsCodeCommitCredentialProvider.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AwsCodeCommitCredentialProvider.java @@ -19,6 +19,7 @@ package org.springframework.cloud.config.server.support; import static org.springframework.util.StringUtils.hasText; import java.net.URI; +import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; @@ -326,7 +327,8 @@ public class AwsCodeCommitCredentialProvider extends CredentialsProvider { } try { - URI u = new URI(uri.toLowerCase()); + URL url = new URL(uri); + URI u = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); if (u.getScheme().equals("https")) { String host = u.getHost(); if (host.endsWith(".amazonaws.com") && host.startsWith("git-codecommit.")) { diff --git a/spring-cloud-config-server/src/main/resources/META-INF/spring.factories b/spring-cloud-config-server/src/main/resources/META-INF/spring.factories index 94a0bb01..7b893f04 100644 --- a/spring-cloud-config-server/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-config-server/src/main/resources/META-INF/spring.factories @@ -1,6 +1,8 @@ # Bootstrap components org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration +org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration,\ +org.springframework.cloud.config.server.config.EncryptionAutoConfiguration,\ +org.springframework.cloud.config.server.config.SingleEncryptorAutoConfiguration # Application listeners org.springframework.context.ApplicationListener=\ diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java new file mode 100644 index 00000000..4749750f --- /dev/null +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java @@ -0,0 +1,25 @@ +package org.springframework.cloud.config.server; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.cloud.config.server.environment.EnvironmentEncryptorEnvironmentRepositoryTests; +import org.springframework.cloud.config.server.environment.JGitEnvironmentRepositoryIntegrationTests; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepositoryIntegrationTests; +import org.springframework.cloud.config.server.environment.NativeEnvironmentRepositoryTests; +import org.springframework.cloud.config.server.environment.SVNKitEnvironmentRepositoryIntegrationTests; + +/** + * A test suite for probing weird ordering problems in the tests. + * + * @author Dave Syer + */ +@RunWith(Suite.class) +@SuiteClasses({ MultipleJGitEnvironmentRepositoryIntegrationTests.class, + JGitEnvironmentRepositoryIntegrationTests.class, EnvironmentEncryptorEnvironmentRepositoryTests.class, + NativeEnvironmentRepositoryTests.class, SVNKitEnvironmentRepositoryIntegrationTests.class }) +@Ignore +public class AdhocTestSuite { + +} diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java index bd092010..c4a003d1 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertFalse; @RunWith(SpringRunner.class) @SpringBootTest(classes = ConfigServerApplication.class, properties = "spring.cloud.bootstrap.name:enable-bootstrap", webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@ActiveProfiles("test") +@ActiveProfiles({"test", "encrypt"}) public class BootstrapConfigServerIntegrationTests { @LocalServerPort @@ -29,9 +29,12 @@ public class BootstrapConfigServerIntegrationTests { @Value("${info.foo}") private String foo; + @Value("${config.foo}") + private String config; + @BeforeClass public static void init() throws IOException { - ConfigServerTestUtils.prepareLocalRepo(); + ConfigServerTestUtils.prepareLocalRepo("encrypt-repo"); } @Test @@ -46,6 +49,7 @@ public class BootstrapConfigServerIntegrationTests { @Test public void environmentBootstraps() throws Exception { assertEquals("bar", foo); + assertEquals("foo", config); } } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java index 634d1bfd..6eb6018f 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java @@ -48,6 +48,7 @@ public class AwsCodeCommitCredentialsProviderTests { private static final String USER = "test"; private static final String AWS_REPO = "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test"; private static final String BAD_REPO = "https://amazonaws.com/v1/repos/test"; + private static final String CURLY_BRACES_REPO = "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/{application}"; private AwsCodeCommitCredentialProvider provider; @@ -111,6 +112,15 @@ public class AwsCodeCommitCredentialsProviderTests { assertFalse(provider.get(new URIish(BAD_REPO), credentialItems)); } + @Test + public void testUriWithCurlyBracesReturnsTrue() throws UnsupportedCredentialItem, URISyntaxException { + GitCredentialsProviderFactory factory = new GitCredentialsProviderFactory(); + provider = (AwsCodeCommitCredentialProvider) + factory.createFor(CURLY_BRACES_REPO, USER, PASSWORD, null); + CredentialItem[] credentialItems = makeCredentialItems(); + assertTrue(provider.get(new URIish(CURLY_BRACES_REPO), credentialItems)); + } + @Test public void testThrowsUnsupportedCredentialException() throws URISyntaxException { CredentialItem[] goodCredentialItems = makeCredentialItems(); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepositoryTests.java index b1cc7904..138f9f56 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/CompositeEnvironmentRepositoryTests.java @@ -110,4 +110,38 @@ public class CompositeEnvironmentRepositoryTests { assertEquals(sLoc4, locationStrings[3]); assertEquals(sLoc1, locationStrings[4]); } + + @Test + public void testVersion() { + PropertySource p1 = mock(PropertySource.class); + doReturn("p1").when(p1).getName(); + PropertySource p2 = mock(PropertySource.class); + doReturn("p2").when(p2).getName(); + String sLoc1 = "loc1"; + String sLoc2 = "loc2"; + Environment e1 = new Environment("app", "dev"); + e1.add(p1); + e1.setVersion("1"); + e1.setState("state"); + Environment e2 = new Environment("app", "dev"); + e2.add(p2); + e2.setVersion("2"); + e2.setState("state2"); + 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[]{sLoc1, sLoc2}); + List repos = new ArrayList(); + repos.add(new TestOrderedEnvironmentRepository(3, e1, loc1)); + List repos2 = new ArrayList(); + repos2.add(new TestOrderedEnvironmentRepository(3, e1, loc1)); + repos2.add(new TestOrderedEnvironmentRepository(3, e2, loc2)); + SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(repos); + SearchPathCompositeEnvironmentRepository multiCompositeRepo = new SearchPathCompositeEnvironmentRepository(repos2); + Environment env = compositeRepo.findOne("app", "dev", "label"); + assertEquals("1", env.getVersion()); + assertEquals("state", env.getState()); + Environment multiEnv = multiCompositeRepo.findOne("app", "dev", "label"); + assertEquals(null, multiEnv.getVersion()); + assertEquals(null, multiEnv.getState()); + + } } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java index b2981cdf..0943c34d 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java @@ -61,71 +61,83 @@ public class EnvironmentControllerIntegrationTests { @Test public void environmentNoLabel() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/foo/default")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo/default")).andExpect(MockMvcResultMatchers.status().isOk()); Mockito.verify(this.repository).findOne("foo", "default", null); } @Test public void propertiesNoLabel() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/foo-default.properties")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo-default.properties")) + .andExpect(MockMvcResultMatchers.status().isOk()); Mockito.verify(this.repository).findOne("foo", "default", null); } @Test public void propertiesLabel() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", "label")).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-default.properties")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", "label")).thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-default.properties")) + .andExpect(MockMvcResultMatchers.status().isOk()); Mockito.verify(this.repository).findOne("foo", "default", "label"); } @Test public void propertiesLabelWhenApplicationNameContainsHyphen() throws Exception { - Mockito.when(this.repository.findOne("foo-bar", "default", "label")).thenReturn(new Environment("foo-bar", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-bar-default.properties")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo-bar", "default", "label")) + .thenReturn(new Environment("foo-bar", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-bar-default.properties")) + .andExpect(MockMvcResultMatchers.status().isOk()); Mockito.verify(this.repository).findOne("foo-bar", "default", "label"); } @Test public void propertiesLabelWithSlash() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", "label/spam")).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/label(_)spam/foo-default.properties")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", "label/spam")) + .thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/label(_)spam/foo-default.properties")) + .andExpect(MockMvcResultMatchers.status().isOk()); Mockito.verify(this.repository).findOne("foo", "default", "label/spam"); } @Test public void environmentWithLabel() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", "awesome")).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/awesome")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", "awesome")) + .thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/awesome")) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + + @Test + public void environmentWithMissingLabel() throws Exception { + Mockito.when(this.repository.findOne("foo", "default", "missing")) + .thenThrow(new NoSuchLabelException("Planned")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/missing")) + .andExpect(MockMvcResultMatchers.status().isNotFound()); + } + + @Test + public void environmentWithMissingRepo() throws Exception { + Mockito.when(this.repository.findOne("foo", "default", "missing")) + .thenThrow(new NoSuchRepositoryException("Planned")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/missing")) + .andExpect(MockMvcResultMatchers.status().isNotFound()); } @Test public void environmentWithLabelContainingPeriod() throws Exception { - Mockito.when(this.repository.findOne("foo", "default", "1.0.0")).thenReturn( - new Environment("foo", "default")); - this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/1.0.0")).andExpect( - MockMvcResultMatchers.status().isOk()); + Mockito.when(this.repository.findOne("foo", "default", "1.0.0")).thenReturn(new Environment("foo", "default")); + this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/1.0.0")) + .andExpect(MockMvcResultMatchers.status().isOk()); } @Test public void environmentWithLabelContainingSlash() throws Exception { Mockito.when(this.repository.findOne("foo", "default", "feature/puff")) - .thenReturn(new Environment("foo", "default")); + .thenReturn(new Environment("foo", "default")); this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/feature(_)puff")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("\"propertySources\":"))); + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("\"propertySources\":"))); } @Configuration diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryIntegrationTests.java index 61c9dae2..08b4c1fb 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryIntegrationTests.java @@ -16,6 +16,14 @@ package org.springframework.cloud.config.server.environment; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -30,6 +38,7 @@ import java.util.Arrays; import org.eclipse.jgit.api.CheckoutCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ResetCommand.ResetType; +import org.eclipse.jgit.api.TransportConfigCallback; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; @@ -39,7 +48,7 @@ import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; import org.junit.Test; - +import org.mockito.Mockito; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -49,18 +58,12 @@ import org.springframework.cloud.config.server.config.ConfigServerProperties; import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration; import org.springframework.cloud.config.server.test.ConfigServerTestUtils; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.util.ResourceUtils; import org.springframework.util.StreamUtils; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - /** * @author Dave Syer * @author Roy Clarkson @@ -93,8 +96,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.prepareLocalRepo(); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .properties("spring.cloud.config.server.git.uri:" + uri).run(); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "master"); Environment environment = repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -109,12 +111,10 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.copyLocalRepo("config-copy"); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .run("--spring.cloud.config.server.git.uri=" + uri); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "master"); Environment environment = repository.findOne("bar", "staging", "master"); - assertEquals("bar", - environment.getPropertySources().get(0).getSource().get("foo")); + assertEquals("bar", environment.getPropertySources().get(0).getSource().get("foo")); Git git = Git.open(ResourceUtils.getFile(uri).getAbsoluteFile()); git.checkout().setName("master").call(); StreamUtils.copy("foo: foo", Charset.defaultCharset(), @@ -122,15 +122,14 @@ public class JGitEnvironmentRepositoryIntegrationTests { git.add().addFilepattern("bar.properties").call(); git.commit().setMessage("Updated for pull").call(); environment = repository.findOne("bar", "staging", "master"); - assertEquals("foo", - environment.getPropertySources().get(0).getSource().get("foo")); + assertEquals("foo", environment.getPropertySources().get(0).getSource().get("foo")); } /** - * Tests a special use case where the remote repository has been updated with a forced - * push conflicting with the local repo of the Config Server. The Config Server has to - * reset hard on the new reference because a simple pull operation could result in a - * conflicting local repository. + * Tests a special use case where the remote repository has been updated + * with a forced push conflicting with the local repo of the Config Server. + * The Config Server has to reset hard on the new reference because a simple + * pull operation could result in a conflicting local repository. */ @Test public void pullDirtyRepo() throws Exception { @@ -142,23 +141,19 @@ public class JGitEnvironmentRepositoryIntegrationTests { Git git = Git.open(ResourceUtils.getFile(uri).getAbsoluteFile()); StoredConfig config = git.getRepository().getConfig(); - config.setString("remote", "origin", "url", - remote.getDirectory().getAbsolutePath()); - config.setString("remote", "origin", "fetch", - "+refs/heads/*:refs/remotes/origin/*"); + config.setString("remote", "origin", "url", remote.getDirectory().getAbsolutePath()); + config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*"); config.save(); // Pushes the raw branch to remote repository. git.push().call(); - String commitToRevertBeforePull = git.log().setMaxCount(1).call().iterator() - .next().getName(); + String commitToRevertBeforePull = git.log().setMaxCount(1).call().iterator().next().getName(); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .run("--spring.cloud.config.server.git.uri=" + uri); - JGitEnvironmentRepository repository = this.context - .getBean(JGitEnvironmentRepository.class); + JGitEnvironmentRepository repository = this.context.getBean(JGitEnvironmentRepository.class); // Fetches the repository for the first time. SearchPathLocator.Locations locations = repository.getLocations("bar", "test", "raw"); @@ -168,17 +163,14 @@ public class JGitEnvironmentRepositoryIntegrationTests { git.reset().setMode(ResetType.HARD).setRef("master").call(); // Generate a conflicting commit who will be forced on the origin. - Path applicationFilePath = Paths - .get(ResourceUtils.getFile(uri).getAbsoluteFile() + "/application.yml"); + Path applicationFilePath = Paths.get(ResourceUtils.getFile(uri).getAbsoluteFile() + "/application.yml"); - Files.write(applicationFilePath, - Arrays.asList("info:", " foo: bar", "raw: false"), - StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING); + Files.write(applicationFilePath, Arrays.asList("info:", " foo: bar", "raw: false"), StandardCharsets.UTF_8, + StandardOpenOption.TRUNCATE_EXISTING); git.add().addFilepattern(".").call(); git.commit().setMessage("Conflicting commit.").call(); git.push().setForce(true).call(); - String conflictingCommit = git.log().setMaxCount(1).call().iterator() - .next().getName(); + String conflictingCommit = git.log().setMaxCount(1).call().iterator().next().getName(); // Reset to the raw branch. git.reset().setMode(ResetType.HARD).setRef(commitToRevertBeforePull).call(); @@ -187,8 +179,17 @@ public class JGitEnvironmentRepositoryIntegrationTests { locations = repository.getLocations("bar", "test", "raw"); assertEquals(locations.getVersion(), conflictingCommit); - assertTrue("Local repository is not cleaned after retrieving resources.", - git.status().call().isClean()); + assertTrue("Local repository is not cleaned after retrieving resources.", git.status().call().isClean()); + } + + @Test + public void pullMissingRepo() throws Exception { + pull(); + JGitEnvironmentRepository repository = this.context.getBean(JGitEnvironmentRepository.class); + new File(repository.getUri().replaceAll("file:", ""), ".git/index.lock").createNewFile(); + repository.findOne("bar", "staging", "master"); + Environment environment = repository.findOne("bar", "staging", "master"); + assertEquals("foo", environment.getPropertySources().get(0).getSource().get("foo")); } @Test @@ -196,10 +197,8 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) // TODO: why didn't .properties() work for me? - .run("--spring.cloud.config.server.git.uri=" + uri, - "--spring.cloud.config.server.git.searchPaths=sub"); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + .run("--spring.cloud.config.server.git.uri=" + uri, "--spring.cloud.config.server.git.searchPaths=sub"); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "master"); Environment environment = repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -212,8 +211,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { // TODO: why didn't .properties() work for me? .run("--spring.cloud.config.server.git.uri=" + uri, "--spring.cloud.config.server.git.searchPaths={application}"); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("foo,bar", "staging", "master"); Environment environment = repository.findOne("foo,bar", "staging", "master"); assertEquals(3, environment.getPropertySources().size()); @@ -226,8 +224,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { // TODO: why didn't .properties() work for me? .run("--spring.cloud.config.server.git.uri=" + uri, "--spring.cloud.config.server.git.searchPaths={profile}"); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("foo,bar", "staging", "master"); Environment environment = repository.findOne("staging", "foo,bar", "master"); assertEquals(3, environment.getPropertySources().size()); @@ -243,8 +240,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { .getBean(JGitEnvironmentRepository.class); assertThat(repository.getSearchPaths(), Matchers.arrayContaining("{application}")); assertFalse(Arrays.equals(repository.getSearchPaths(), - new JGitEnvironmentRepository(repository.getEnvironment()) - .getSearchPaths())); + new JGitEnvironmentRepository(repository.getEnvironment()).getSearchPaths())); } @Test @@ -252,8 +248,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.prepareLocalRepo(); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .properties("spring.cloud.config.server.git.uri:" + uri).run(); - JGitEnvironmentRepository repository = this.context - .getBean(JGitEnvironmentRepository.class); + JGitEnvironmentRepository repository = this.context.getBean(JGitEnvironmentRepository.class); assertEquals("master", repository.getDefaultLabel()); } @@ -262,8 +257,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.prepareLocalRepo(); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .properties("spring.cloud.config.server.git.uri:" + uri).run(); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "unknownlabel"); } @@ -295,8 +289,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { .getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "master"); Environment environment = repository.findOne("bar", "staging", "master"); - assertEquals("bar", - environment.getPropertySources().get(0).getSource().get("foo")); + assertEquals("bar", environment.getPropertySources().get(0).getSource().get("foo")); Git git = Git.open(ResourceUtils.getFile(uri).getAbsoluteFile()); git.checkout().setName("master").call(); StreamUtils.copy("foo: foo", Charset.defaultCharset(), @@ -304,8 +297,7 @@ public class JGitEnvironmentRepositoryIntegrationTests { git.add().addFilepattern("bar.properties").call(); git.commit().setMessage("Updated for pull").call(); environment = repository.findOne("bar", "staging", "master"); - assertEquals("foo", - environment.getPropertySources().get(0).getSource().get("foo")); + assertEquals("foo", environment.getPropertySources().get(0).getSource().get("foo")); } @Test @@ -313,83 +305,80 @@ public class JGitEnvironmentRepositoryIntegrationTests { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) // TODO: why didn't .properties() work for me? - .run("--spring.cloud.config.server.git.uri=" + uri, - "--spring.cloud.config.server.git.searchPaths=sub", + .run("--spring.cloud.config.server.git.uri=" + uri, "--spring.cloud.config.server.git.searchPaths=sub", "--spring.cloud.config.server.git.cloneOnStart=true"); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "master"); Environment environment = repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); } @Test(expected = NoSuchLabelException.class) - public void findOne_FindInvalidLabel_IllegalStateExceptionThrown() - throws IOException { + public void findOne_FindInvalidLabel_IllegalStateExceptionThrown() throws IOException { String uri = ConfigServerTestUtils.prepareLocalRepo(); this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE) .properties("spring.cloud.config.server.git.uri:" + uri, "--spring.cloud.config.server.git.cloneOnStart=true") .run(); - EnvironmentRepository repository = this.context - .getBean(EnvironmentRepository.class); + EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class); repository.findOne("bar", "staging", "unknownlabel"); } @Test public void testVersionUpdate() throws Exception { - JGitConfigServerTestData testData = JGitConfigServerTestData.prepareClonedGitRepository(TestConfiguration.class); + JGitConfigServerTestData testData = JGitConfigServerTestData + .prepareClonedGitRepository(TestConfiguration.class); - //get our starting versions + // get our starting versions String startingLocalVersion = getCommitID(testData.getClonedGit().getGit(), "master"); String startingRemoteVersion = getCommitID(testData.getServerGit().getGit(), "master"); - //make sure we get the right version out of the gate + // make sure we get the right version out of the gate Environment environment = testData.getRepository().findOne("bar", "staging", "master"); - //make sure the environments version is the same as the remote repo version + // make sure the environments version is the same as the remote repo + // version assertEquals(environment.getVersion(), startingRemoteVersion); - //update the remote repo - FileOutputStream out = new FileOutputStream(new File(testData.getServerGit().getGitWorkingDirectory(), "bar.properties")); + // update the remote repo + FileOutputStream out = new FileOutputStream( + new File(testData.getServerGit().getGitWorkingDirectory(), "bar.properties")); StreamUtils.copy("foo: foo", Charset.defaultCharset(), out); testData.getServerGit().getGit().add().addFilepattern("bar.properties").call(); testData.getServerGit().getGit().commit().setMessage("Updated for pull").call(); - //pull the environment again which should update the local repo from the just updated remote repo + // pull the environment again which should update the local repo from + // the just updated remote repo environment = testData.getRepository().findOne("bar", "staging", "master"); - //do some more check outs to get updated version numbers + // do some more check outs to get updated version numbers String updatedLocalVersion = getCommitID(testData.getClonedGit().getGit(), "master"); String updatedRemoteVersion = getCommitID(testData.getClonedGit().getGit(), "master"); - //make sure our versions have been updated + // make sure our versions have been updated assertEquals(updatedRemoteVersion, updatedLocalVersion); assertNotEquals(updatedRemoteVersion, startingRemoteVersion); assertNotEquals(updatedLocalVersion, startingLocalVersion); - //make sure our environment also reflects the updated version - //this used to have a bug + // make sure our environment also reflects the updated version + // this used to have a bug assertEquals(environment.getVersion(), updatedRemoteVersion); } @Test public void testNewRemoteBranch() throws Exception { - JGitConfigServerTestData testData = JGitConfigServerTestData.prepareClonedGitRepository(TestConfiguration.class); + JGitConfigServerTestData testData = JGitConfigServerTestData + .prepareClonedGitRepository(TestConfiguration.class); Environment environment = testData.getRepository().findOne("bar", "staging", "master"); Object fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); assertEquals(fooProperty, "bar"); - testData.getServerGit().getGit().branchCreate() - .setName("testNewRemoteBranch") - .call(); + testData.getServerGit().getGit().branchCreate().setName("testNewRemoteBranch").call(); - testData.getServerGit().getGit().checkout() - .setName("testNewRemoteBranch") - .call(); + testData.getServerGit().getGit().checkout().setName("testNewRemoteBranch").call(); - //update the remote repo + // update the remote repo FileOutputStream out = new FileOutputStream( new File(testData.getServerGit().getGitWorkingDirectory(), "/bar.properties")); StreamUtils.copy("foo: branchBar", Charset.defaultCharset(), out); @@ -403,7 +392,8 @@ public class JGitEnvironmentRepositoryIntegrationTests { @Test public void testNewRemoteTag() throws Exception { - JGitConfigServerTestData testData = JGitConfigServerTestData.prepareClonedGitRepository(TestConfiguration.class); + JGitConfigServerTestData testData = JGitConfigServerTestData + .prepareClonedGitRepository(TestConfiguration.class); Git serverGit = testData.getServerGit().getGit(); @@ -413,10 +403,10 @@ public class JGitEnvironmentRepositoryIntegrationTests { serverGit.checkout().setName("master").call(); - //create a new tag + // create a new tag serverGit.tag().setName("testTag").setMessage("Testing a tag").call(); - //update the remote repo + // update the remote repo FileOutputStream out = new FileOutputStream( new File(testData.getServerGit().getGitWorkingDirectory(), "/bar.properties")); StreamUtils.copy("foo: testAfterTag", Charset.defaultCharset(), out); @@ -431,50 +421,52 @@ public class JGitEnvironmentRepositoryIntegrationTests { fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); assertEquals(fooProperty, "bar"); - //now move the tag and test again - serverGit.tag().setName("testTag").setForceUpdate(true).setMessage("Testing a moved tag").call(); + // now move the tag and test again + serverGit.tag().setName("testTag").setForceUpdate(true).setMessage("Testing a moved tag").call(); - environment = testData.getRepository().findOne("bar", "staging", "testTag"); - fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); - assertEquals(fooProperty, "testAfterTag"); + environment = testData.getRepository().findOne("bar", "staging", "testTag"); + fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); + assertEquals(fooProperty, "testAfterTag"); } - @Test + @Test public void testNewCommitID() throws Exception { - JGitConfigServerTestData testData = JGitConfigServerTestData.prepareClonedGitRepository(TestConfiguration.class); + JGitConfigServerTestData testData = JGitConfigServerTestData + .prepareClonedGitRepository(TestConfiguration.class); - //get our starting versions + // get our starting versions String startingRemoteVersion = getCommitID(testData.getServerGit().getGit(), "master"); - //make sure we get the right version out of the gate + // make sure we get the right version out of the gate Environment environment = testData.getRepository().findOne("bar", "staging", "master"); assertEquals(environment.getVersion(), startingRemoteVersion); - //update the remote repo - FileOutputStream out = new FileOutputStream(new File(testData.getServerGit().getGitWorkingDirectory(), "bar.properties")); + // update the remote repo + FileOutputStream out = new FileOutputStream( + new File(testData.getServerGit().getGitWorkingDirectory(), "bar.properties")); StreamUtils.copy("foo: barNewCommit", Charset.defaultCharset(), out); testData.getServerGit().getGit().add().addFilepattern("bar.properties").call(); testData.getServerGit().getGit().commit().setMessage("Updated for pull").call(); String updatedRemoteVersion = getCommitID(testData.getServerGit().getGit(), "master"); - //do a normal request and verify we get the new version + // do a normal request and verify we get the new version environment = testData.getRepository().findOne("bar", "staging", "master"); assertEquals(environment.getVersion(), updatedRemoteVersion); Object fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); assertEquals(fooProperty, "barNewCommit"); - //request the prior commit ID and make sure we get it + // request the prior commit ID and make sure we get it environment = testData.getRepository().findOne("bar", "staging", startingRemoteVersion); assertEquals(environment.getVersion(), startingRemoteVersion); fooProperty = ConfigServerTestUtils.getProperty(environment, "bar.properties", "foo"); assertEquals(fooProperty, "bar"); } - @Test(expected = NoSuchLabelException.class) public void testUnknownLabelWithRemote() throws Exception { - JGitConfigServerTestData testData = JGitConfigServerTestData.prepareClonedGitRepository(TestConfiguration.class); + JGitConfigServerTestData testData = JGitConfigServerTestData + .prepareClonedGitRepository(TestConfiguration.class); testData.getRepository().findOne("bar", "staging", "BADLabel"); } @@ -506,11 +498,31 @@ public class JGitEnvironmentRepositoryIntegrationTests { assertEquals(repository.isStrictHostKeyChecking(), strictHostKeyChecking); } + @Test + public void shouldSetTransportConfigCallback() throws IOException { + String uri = ConfigServerTestUtils.prepareLocalRepo(); + this.context = new SpringApplicationBuilder(TestConfigurationWithTransportConfigCallback.class).web(WebApplicationType.NONE) + .properties("spring.cloud.config.server.git.uri:" + uri).run(); + + JGitEnvironmentRepository repository = this.context.getBean(JGitEnvironmentRepository.class); + assertNotNull(repository.getTransportConfigCallback()); + } + @Configuration @EnableConfigurationProperties(ConfigServerProperties.class) - @Import({ PropertyPlaceholderAutoConfiguration.class, - EnvironmentRepositoryConfiguration.class }) + @Import({ PropertyPlaceholderAutoConfiguration.class, EnvironmentRepositoryConfiguration.class }) protected static class TestConfiguration { } + @Configuration + @EnableConfigurationProperties(ConfigServerProperties.class) + @Import({ PropertyPlaceholderAutoConfiguration.class, EnvironmentRepositoryConfiguration.class }) + protected static class TestConfigurationWithTransportConfigCallback { + + @Bean + public TransportConfigCallback transportConfigCallback() { + return Mockito.mock(TransportConfigCallback.class); + } + } + } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java index fa98546a..07fbb577 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java @@ -16,56 +16,6 @@ package org.springframework.cloud.config.server.environment; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.jcraft.jsch.Session; - -import org.apache.commons.logging.Log; -import org.eclipse.jgit.api.CheckoutCommand; -import org.eclipse.jgit.api.CloneCommand; -import org.eclipse.jgit.api.FetchCommand; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.ListBranchCommand; -import org.eclipse.jgit.api.MergeCommand; -import org.eclipse.jgit.api.ResetCommand; -import org.eclipse.jgit.api.Status; -import org.eclipse.jgit.api.StatusCommand; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.api.errors.InvalidRemoteException; -import org.eclipse.jgit.api.errors.NotMergedException; -import org.eclipse.jgit.api.errors.TransportException; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.lib.StoredConfig; -import org.eclipse.jgit.transport.CredentialItem; -import org.eclipse.jgit.transport.CredentialsProvider; -import org.eclipse.jgit.transport.FetchResult; -import org.eclipse.jgit.transport.JschConfigSessionFactory; -import org.eclipse.jgit.transport.OpenSshConfig; -import org.eclipse.jgit.transport.SshSessionFactory; -import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; -import org.eclipse.jgit.util.FS; -import org.eclipse.jgit.util.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; - -import org.springframework.cloud.config.environment.Environment; -import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialProvider; -import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory; -import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider; -import org.springframework.cloud.config.server.test.ConfigServerTestUtils; -import org.springframework.core.env.StandardEnvironment; - import static junit.framework.TestCase.assertTrue; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; @@ -81,6 +31,57 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.eclipse.jgit.api.CheckoutCommand; +import org.eclipse.jgit.api.CloneCommand; +import org.eclipse.jgit.api.FetchCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.ListBranchCommand; +import org.eclipse.jgit.api.MergeCommand; +import org.eclipse.jgit.api.ResetCommand; +import org.eclipse.jgit.api.Status; +import org.eclipse.jgit.api.StatusCommand; +import org.eclipse.jgit.api.TransportConfigCallback; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.NotMergedException; +import org.eclipse.jgit.api.errors.TransportException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.transport.CredentialItem; +import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.FetchResult; +import org.eclipse.jgit.transport.JschConfigSessionFactory; +import org.eclipse.jgit.transport.OpenSshConfig; +import org.eclipse.jgit.transport.SshSessionFactory; +import org.eclipse.jgit.transport.TrackingRefUpdate; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.springframework.cloud.config.environment.Environment; +import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialProvider; +import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory; +import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider; +import org.springframework.cloud.config.server.test.ConfigServerTestUtils; +import org.springframework.core.env.StandardEnvironment; + +import com.jcraft.jsch.Session; + /** * @author Dave Syer * @@ -88,8 +89,7 @@ import static org.mockito.Mockito.when; public class JGitEnvironmentRepositoryTests { private StandardEnvironment environment = new StandardEnvironment(); - private JGitEnvironmentRepository repository = new JGitEnvironmentRepository( - this.environment); + private JGitEnvironmentRepository repository = new JGitEnvironmentRepository(this.environment); private File basedir = new File("target/config"); @@ -110,8 +110,7 @@ public class JGitEnvironmentRepositoryTests { this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", - environment.getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", environment.getPropertySources().get(0).getName()); assertVersion(environment); } @@ -119,7 +118,7 @@ public class JGitEnvironmentRepositoryTests { public void nested() throws IOException { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.repository.setUri(uri); - this.repository.setSearchPaths(new String[] {"sub"}); + this.repository.setSearchPaths(new String[] { "sub" }); this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -132,7 +131,7 @@ public class JGitEnvironmentRepositoryTests { public void placeholderInSearchPath() throws IOException { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.repository.setUri(uri); - this.repository.setSearchPaths(new String[] {"{application}"}); + this.repository.setSearchPaths(new String[] { "{application}" }); this.repository.findOne("sub", "staging", "master"); Environment environment = this.repository.findOne("sub", "staging", "master"); assertEquals(1, environment.getPropertySources().size()); @@ -151,7 +150,7 @@ public class JGitEnvironmentRepositoryTests { public void nestedPattern() throws IOException { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.repository.setUri(uri); - this.repository.setSearchPaths(new String[] {"sub*"}); + this.repository.setSearchPaths(new String[] { "sub*" }); this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -165,8 +164,7 @@ public class JGitEnvironmentRepositoryTests { this.repository.setBasedir(this.basedir); Environment environment = this.repository.findOne("bar", "staging", "raw"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", - environment.getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", environment.getPropertySources().get(0).getName()); assertVersion(environment); } @@ -175,8 +173,7 @@ public class JGitEnvironmentRepositoryTests { this.repository.setBasedir(this.basedir); Environment environment = this.repository.findOne("bar", "staging", "foo"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", environment - .getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", environment.getPropertySources().get(0).getName()); assertVersion(environment); } @@ -186,8 +183,7 @@ public class JGitEnvironmentRepositoryTests { this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", - environment.getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", environment.getPropertySources().get(0).getName()); assertVersion(environment); } @@ -199,8 +195,7 @@ public class JGitEnvironmentRepositoryTests { this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", - environment.getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", environment.getPropertySources().get(0).getName()); assertVersion(environment); } @@ -217,16 +212,14 @@ public class JGitEnvironmentRepositoryTests { } @Test - public void afterPropertiesSet_CloneOnStartTrue_CloneAndFetchCalled() - throws Exception { + public void afterPropertiesSet_CloneOnStartTrue_CloneAndFetchCalled() throws Exception { Git mockGit = mock(Git.class); CloneCommand mockCloneCommand = mock(CloneCommand.class); when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); - JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri("http://somegitserver/somegitrepo"); envRepository.setCloneOnStart(true); @@ -235,16 +228,14 @@ public class JGitEnvironmentRepositoryTests { } @Test - public void afterPropertiesSet_CloneOnStartFalse_CloneAndFetchNotCalled() - throws Exception { + public void afterPropertiesSet_CloneOnStartFalse_CloneAndFetchNotCalled() throws Exception { Git mockGit = mock(Git.class); CloneCommand mockCloneCommand = mock(CloneCommand.class); when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); - JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri("http://somegitserver/somegitrepo"); envRepository.afterPropertiesSet(); @@ -253,16 +244,14 @@ public class JGitEnvironmentRepositoryTests { } @Test - public void afterPropertiesSet_CloneOnStartTrueWithFileURL_CloneAndFetchNotCalled() - throws Exception { + public void afterPropertiesSet_CloneOnStartTrueWithFileURL_CloneAndFetchNotCalled() throws Exception { Git mockGit = mock(Git.class); CloneCommand mockCloneCommand = mock(CloneCommand.class); when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); - JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri("file://somefilesystem/somegitrepo"); envRepository.setCloneOnStart(true); @@ -286,8 +275,7 @@ public class JGitEnvironmentRepositoryTests { when(statusCommand.call()).thenReturn(status); when(status.isClean()).thenReturn(false); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment); repo.setForcePull(true); boolean shouldPull = repo.shouldPull(git); @@ -310,8 +298,7 @@ public class JGitEnvironmentRepositoryTests { when(statusCommand.call()).thenReturn(status); when(status.isClean()).thenReturn(false); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment); boolean shouldPull = repo.shouldPull(git); @@ -333,8 +320,7 @@ public class JGitEnvironmentRepositoryTests { when(statusCommand.call()).thenReturn(status); when(status.isClean()).thenReturn(true); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment); boolean shouldPull = repo.shouldPull(git); @@ -347,11 +333,9 @@ public class JGitEnvironmentRepositoryTests { Git git = mock(Git.class); CloneCommand cloneCommand = mock(CloneCommand.class); MockGitFactory factory = new MockGitFactory(git, cloneCommand); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); this.repository.setGitFactory(factory); - //refresh()->shouldPull + // refresh()->shouldPull StatusCommand statusCommand = mock(StatusCommand.class); Status status = mock(Status.class); when(git.status()).thenReturn(statusCommand); @@ -363,15 +347,21 @@ public class JGitEnvironmentRepositoryTests { when(statusCommand.call()).thenReturn(status); when(status.isClean()).thenReturn(true); - //refresh()->fetch + // refresh()->fetch FetchCommand fetchCommand = mock(FetchCommand.class); when(git.fetch()).thenReturn(fetchCommand); when(fetchCommand.setRemote(anyString())).thenReturn(fetchCommand); - when(fetchCommand.call()).thenThrow(new InvalidRemoteException("invalid mock remote")); //here is our exception we are testing + when(fetchCommand.call()).thenThrow(new InvalidRemoteException("invalid mock remote")); // here + // is + // our + // exception + // we + // are + // testing - //refresh()->checkout + // refresh()->checkout CheckoutCommand checkoutCommand = mock(CheckoutCommand.class); - //refresh()->checkout->containsBranch + // refresh()->checkout->containsBranch ListBranchCommand listBranchCommand = mock(ListBranchCommand.class); when(git.checkout()).thenReturn(checkoutCommand); when(git.branchList()).thenReturn(listBranchCommand); @@ -381,20 +371,27 @@ public class JGitEnvironmentRepositoryTests { when(ref.getName()).thenReturn("/master"); when(listBranchCommand.call()).thenReturn(refs); - //refresh()->merge + // refresh()->merge MergeCommand mergeCommand = mock(MergeCommand.class); when(git.merge()).thenReturn(mergeCommand); - when(mergeCommand.call()).thenThrow(new NotMergedException()); //here is our exception we are testing + when(mergeCommand.call()).thenThrow(new NotMergedException()); // here + // is + // our + // exception + // we + // are + // testing - //refresh()->return git.getRepository().getRef("HEAD").getObjectId().getName(); + // refresh()->return + // git.getRepository().getRef("HEAD").getObjectId().getName(); Ref headRef = mock(Ref.class); - when(repository.getRef(anyString())).thenReturn(headRef); + when(repository.findRef(anyString())).thenReturn(headRef); - ObjectId newObjectId = ObjectId.fromRaw(new int[]{1,2,3,4,5}); + ObjectId newObjectId = ObjectId.fromRaw(new int[] { 1, 2, 3, 4, 5 }); when(headRef.getObjectId()).thenReturn(newObjectId); SearchPathLocator.Locations locations = this.repository.getLocations("bar", "staging", null); - assertEquals(locations.getVersion(),newObjectId.getName()); + assertEquals(locations.getVersion(), newObjectId.getName()); } @Test @@ -403,8 +400,6 @@ public class JGitEnvironmentRepositoryTests { Git git = mock(Git.class); CloneCommand cloneCommand = mock(CloneCommand.class); MockGitFactory factory = new MockGitFactory(git, cloneCommand); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); this.repository.setGitFactory(factory); //refresh()->shouldPull @@ -425,7 +420,7 @@ public class JGitEnvironmentRepositoryTests { when(git.fetch()).thenReturn(fetchCommand); when(fetchCommand.setRemote(anyString())).thenReturn(fetchCommand); when(fetchCommand.call()).thenReturn(fetchResult); - when(fetchResult.getTrackingRefUpdates()).thenReturn(Collections.EMPTY_LIST); + when(fetchResult.getTrackingRefUpdates()).thenReturn(Collections.emptyList()); //refresh()->checkout CheckoutCommand checkoutCommand = mock(CheckoutCommand.class); @@ -446,7 +441,7 @@ public class JGitEnvironmentRepositoryTests { //refresh()->return git.getRepository().getRef("HEAD").getObjectId().getName(); Ref headRef = mock(Ref.class); - when(repository.getRef(anyString())).thenReturn(headRef); + when(repository.findRef(anyString())).thenReturn(headRef); ObjectId newObjectId = ObjectId.fromRaw(new int[]{1,2,3,4,5}); when(headRef.getObjectId()).thenReturn(newObjectId); @@ -461,11 +456,9 @@ public class JGitEnvironmentRepositoryTests { Git git = mock(Git.class); CloneCommand cloneCommand = mock(CloneCommand.class); MockGitFactory factory = new MockGitFactory(git, cloneCommand); - JGitEnvironmentRepository repo = new JGitEnvironmentRepository( - this.environment); this.repository.setGitFactory(factory); - //refresh()->shouldPull + // refresh()->shouldPull StatusCommand statusCommand = mock(StatusCommand.class); Status status = mock(Status.class); when(git.status()).thenReturn(statusCommand); @@ -477,17 +470,17 @@ public class JGitEnvironmentRepositoryTests { when(statusCommand.call()).thenReturn(status); when(status.isClean()).thenReturn(true).thenReturn(false); - //refresh()->fetch + // refresh()->fetch FetchCommand fetchCommand = mock(FetchCommand.class); FetchResult fetchResult = mock(FetchResult.class); when(git.fetch()).thenReturn(fetchCommand); when(fetchCommand.setRemote(anyString())).thenReturn(fetchCommand); when(fetchCommand.call()).thenReturn(fetchResult); - when(fetchResult.getTrackingRefUpdates()).thenReturn(Collections.EMPTY_LIST); + when(fetchResult.getTrackingRefUpdates()).thenReturn(Collections.emptyList()); - //refresh()->checkout + // refresh()->checkout CheckoutCommand checkoutCommand = mock(CheckoutCommand.class); - //refresh()->checkout->containsBranch + // refresh()->checkout->containsBranch ListBranchCommand listBranchCommand = mock(ListBranchCommand.class); when(git.checkout()).thenReturn(checkoutCommand); when(git.branchList()).thenReturn(listBranchCommand); @@ -497,29 +490,36 @@ public class JGitEnvironmentRepositoryTests { when(ref.getName()).thenReturn("/master"); when(listBranchCommand.call()).thenReturn(refs); - //refresh()->merge + // refresh()->merge MergeCommand mergeCommand = mock(MergeCommand.class); when(git.merge()).thenReturn(mergeCommand); - when(mergeCommand.call()).thenThrow(new NotMergedException()); //here is our exception we are testing + when(mergeCommand.call()).thenThrow(new NotMergedException()); // here + // is + // our + // exception + // we + // are + // testing - //refresh()->hardReset + // refresh()->hardReset ResetCommand resetCommand = mock(ResetCommand.class); when(git.reset()).thenReturn(resetCommand); when(resetCommand.call()).thenReturn(ref); - //refresh()->return git.getRepository().getRef("HEAD").getObjectId().getName(); + // refresh()->return + // git.getRepository().getRef("HEAD").getObjectId().getName(); Ref headRef = mock(Ref.class); - when(repository.getRef(anyString())).thenReturn(headRef); + when(repository.findRef(anyString())).thenReturn(headRef); - ObjectId newObjectId = ObjectId.fromRaw(new int[]{1,2,3,4,5}); + ObjectId newObjectId = ObjectId.fromRaw(new int[] { 1, 2, 3, 4, 5 }); when(headRef.getObjectId()).thenReturn(newObjectId); SearchPathLocator.Locations locations = this.repository.getLocations("bar", "staging", "master"); - assertEquals(locations.getVersion(),newObjectId.getName()); + assertEquals(locations.getVersion(), newObjectId.getName()); } - + @Test - public void shouldDeleteBaseDirWhenCloneFails() throws Exception { + public void shouldDeleteBaseDirWhenCloneFails() throws Exception { Git mockGit = mock(Git.class); CloneCommand mockCloneCommand = mock(CloneCommand.class); @@ -527,19 +527,17 @@ public class JGitEnvironmentRepositoryTests { when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); when(mockCloneCommand.call()).thenThrow(new TransportException("failed to clone")); - JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( - this.environment); + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri("http://somegitserver/somegitrepo"); envRepository.setBasedir(this.basedir); - + try { envRepository.findOne("bar", "staging", "master"); - } - catch (Exception ex) { + } catch (Exception ex) { // expected - ignore } - + assertFalse("baseDir should be deleted when clone fails", this.basedir.exists()); } @@ -592,13 +590,14 @@ public class JGitEnvironmentRepositoryTests { CredentialsProvider provider = mockCloneCommand.getCredentialsProvider(); assertFalse(provider.isInteractive()); - CredentialItem.StringType stringCredential = new CredentialItem.StringType(PassphraseCredentialsProvider.PROMPT, true); + CredentialItem.StringType stringCredential = new CredentialItem.StringType(PassphraseCredentialsProvider.PROMPT, + true); assertTrue(provider.supports(stringCredential)); provider.get(new URIish(), stringCredential); assertEquals(stringCredential.getValue(), passphrase); } - + @Test public void gitCredentialsProviderFactoryCreatesPassphraseProvider() throws Exception { final String passphrase = "mypassphrase"; @@ -620,7 +619,8 @@ public class JGitEnvironmentRepositoryTests { CredentialsProvider provider = mockCloneCommand.getCredentialsProvider(); assertFalse(provider.isInteractive()); - CredentialItem.StringType stringCredential = new CredentialItem.StringType(PassphraseCredentialsProvider.PROMPT, true); + CredentialItem.StringType stringCredential = new CredentialItem.StringType(PassphraseCredentialsProvider.PROMPT, + true); assertTrue(provider.supports(stringCredential)); provider.get(new URIish(), stringCredential); @@ -640,8 +640,8 @@ public class JGitEnvironmentRepositoryTests { envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri("git+ssh://git@somegitserver/somegitrepo"); envRepository.setBasedir(new File("./mybasedir")); - envRepository.setGitCredentialsProvider(credentialsFactory.createFor( - envRepository.getUri(), username, password, null)); + envRepository.setGitCredentialsProvider( + credentialsFactory.createFor(envRepository.getUri(), username, password, null)); envRepository.setCloneOnStart(true); envRepository.afterPropertiesSet(); @@ -665,12 +665,11 @@ public class JGitEnvironmentRepositoryTests { Git mockGit = mock(Git.class); MockCloneCommand mockCloneCommand = new MockCloneCommand(mockGit); final String awsUri = "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test"; - + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); envRepository.setUri(awsUri); - envRepository.setGitCredentialsProvider(credentialsFactory.createFor( - envRepository.getUri(), null, null, null)); + envRepository.setGitCredentialsProvider(credentialsFactory.createFor(envRepository.getUri(), null, null, null)); envRepository.setCloneOnStart(true); envRepository.afterPropertiesSet(); @@ -693,14 +692,17 @@ public class JGitEnvironmentRepositoryTests { } catch (Exception e) { final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com"); JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance(); - // There's no public method that can be used to inspect the ssh configuration, so we'll reflect - // the configure method to allow us to check that the config property is set as expected. - Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class, Session.class ); + // There's no public method that can be used to inspect the ssh + // configuration, so we'll reflect + // the configure method to allow us to check that the config + // property is set as expected. + Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class, + Session.class); configure.setAccessible(true); Session session = mock(Session.class); ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class); - configure.invoke(factory, hc, session ); + configure.invoke(factory, hc, session); verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture()); configure.setAccessible(false); assertTrue("yes".equals(valueCaptor.getValue())); @@ -710,7 +712,7 @@ public class JGitEnvironmentRepositoryTests { @Test public void shouldPrintStacktraceIfDebugEnabled() throws Exception { final Log mockLogger = mock(Log.class); - JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment){ + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment) { @Override public void afterPropertiesSet() throws Exception { this.logger = mockLogger; @@ -728,6 +730,31 @@ public class JGitEnvironmentRepositoryTests { assertEquals("should call isDebugEnabled warn and debug", 3, numberOfInvocations); } + @Test + public void shouldSetTransportConfigCallbackOnCloneAndFetch() throws Exception { + Git mockGit = mock(Git.class); + FetchCommand fetchCommand = mock(FetchCommand.class); + when(mockGit.fetch()).thenReturn(fetchCommand); + when(fetchCommand.call()).thenReturn(mock(FetchResult.class)); + + CloneCommand mockCloneCommand = mock(CloneCommand.class); + when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); + when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); + + TransportConfigCallback configCallback = mock(TransportConfigCallback.class); + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment); + envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); + envRepository.setUri("http://somegitserver/somegitrepo"); + envRepository.setTransportConfigCallback(configCallback); + envRepository.setCloneOnStart(true); + + envRepository.afterPropertiesSet(); + verify(mockCloneCommand, times(1)).setTransportConfigCallback(configCallback); + + envRepository.fetch(mockGit, "master"); + verify(fetchCommand, times(1)).setTransportConfigCallback(configCallback); + } + class MockCloneCommand extends CloneCommand { private Git mockGit; @@ -749,13 +776,12 @@ public class JGitEnvironmentRepositoryTests { } } - class MockGitFactory extends JGitEnvironmentRepository.JGitFactory { private Git mockGit; private CloneCommand mockCloneCommand; - public MockGitFactory (Git mockGit, CloneCommand mockCloneCommand) { + public MockGitFactory(Git mockGit, CloneCommand mockCloneCommand) { this.mockGit = mockGit; this.mockCloneCommand = mockCloneCommand; } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProfilePlaceholderRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProfilePlaceholderRepositoryTests.java index 732ed9f3..1a5d3106 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProfilePlaceholderRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProfilePlaceholderRepositoryTests.java @@ -15,22 +15,27 @@ */ 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; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.util.StringUtils; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * @author Dave Syer @@ -46,6 +51,7 @@ public class MultipleJGitEnvironmentProfilePlaceholderRepositoryTests { public void init() throws Exception { String defaultUri = ConfigServerTestUtils.prepareLocalRepo("config-repo"); this.repository.setUri(defaultUri); + this.repository.setBasedir(new File("target/repos/parent_repo")); this.repository.setRepos(createRepositories()); } @@ -67,6 +73,7 @@ public class MultipleJGitEnvironmentProfilePlaceholderRepositoryTests { repo.setName(name); repo.setPattern(new String[] { pattern }); repo.setUri(uri); + repo.setBasedir(new File("target/repos/pattern_repos", name)); return repo; } @@ -84,11 +91,12 @@ public class MultipleJGitEnvironmentProfilePlaceholderRepositoryTests { Environment environment = this.repository.findOne("application", "test1-config-repo", "master"); assertEquals(1, environment.getPropertySources().size()); - assertEquals( - getUri("*").replace("{profile}", "test1-config-repo") - + "/application.yml", + String uri = getUri("*").replace("{profile}", "test1-config-repo"); + assertEquals(uri + "/application.yml", environment.getPropertySources().get(0).getName()); assertVersion(environment); + assertThat(StringUtils.cleanPath(getRepository(uri).getBasedir().toString()), + containsString("target/repos")); } @Test @@ -141,6 +149,13 @@ public class MultipleJGitEnvironmentProfilePlaceholderRepositoryTests { "test2-config-repo", "missing-config-repo" }); } + @SuppressWarnings("unchecked") + private JGitEnvironmentRepository getRepository(String uri) { + Map repos = (Map) ReflectionTestUtils + .getField(repository, "placeholders"); + return repos.get(uri); + } + private void assertVersion(Environment environment) { String version = environment.getVersion(); assertNotNull("version was null", version); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java index 87f0ad8b..94133374 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java @@ -16,6 +16,9 @@ package org.springframework.cloud.config.server.environment; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; + import java.io.File; import java.io.IOException; import java.util.LinkedHashMap; @@ -24,8 +27,10 @@ import java.util.Map; import org.eclipse.jgit.util.FileUtils; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; - +import org.junit.internal.matchers.ThrowableMessageMatcher; +import org.junit.rules.ExpectedException; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -38,8 +43,6 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import static org.junit.Assert.assertEquals; - /** * @author Andy Chan (iceycake) * @author Dave Syer @@ -51,6 +54,9 @@ public class MultipleJGitEnvironmentRepositoryIntegrationTests { private File basedir = new File("target/config"); + @Rule + public ExpectedException expected = ExpectedException.none(); + @Before public void init() throws Exception { if (this.basedir.exists()) { @@ -184,6 +190,17 @@ public class MultipleJGitEnvironmentRepositoryIntegrationTests { assertEquals(2, environment.getPropertySources().size()); } + @Test + public void nonWritableBasedir() throws IOException { + String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo"); + expected.expectCause(ThrowableMessageMatcher + .hasMessage(containsString("Cannot write parent"))); + this.context = new SpringApplicationBuilder(TestConfiguration.class).web(false) + .properties("spring.cloud.config.server.git.uri:" + defaultRepoUri, + "spring.cloud.config.server.git.basedir:/tmp") + .run(); + } + @Configuration @EnableConfigurationProperties(ConfigServerProperties.class) @Import({ PropertyPlaceholderAutoConfiguration.class, diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java index d751f1ee..aac5a068 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java @@ -15,22 +15,32 @@ */ package org.springframework.cloud.config.server.environment; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; +import org.eclipse.jgit.api.TransportConfigCallback; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; - +import org.junit.rules.ExpectedException; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository.PatternMatchingJGitEnvironmentRepository; import org.springframework.cloud.config.server.test.ConfigServerTestUtils; import org.springframework.core.env.StandardEnvironment; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - /** * @author Andy Chan (iceycake) * @author Dave Syer @@ -39,17 +49,23 @@ import static org.junit.Assert.assertTrue; */ public class MultipleJGitEnvironmentRepositoryTests { + @Rule + public ExpectedException exception = ExpectedException.none(); + private StandardEnvironment environment = new StandardEnvironment(); - private MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(this.environment); + private MultipleJGitEnvironmentRepository repository; + @Before public void init() throws Exception { String defaultUri = ConfigServerTestUtils.prepareLocalRepo("config-repo"); + this.repository = new MultipleJGitEnvironmentRepository(this.environment); this.repository.setUri(defaultUri); this.repository.setRepos(createRepositories()); } - private Map createRepositories() throws Exception { + private Map createRepositories() + throws Exception { String test1Uri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo"); Map repos = new HashMap<>(); @@ -57,12 +73,14 @@ public class MultipleJGitEnvironmentRepositoryTests { return repos; } - private PatternMatchingJGitEnvironmentRepository createRepository(String name, String pattern, String uri) { + 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.setPattern(new String[] { pattern }); repo.setUri(uri); + repo.setBasedir(new File(this.repository.getBasedir().getParentFile(), name)); return repo; } @@ -78,14 +96,15 @@ public class MultipleJGitEnvironmentRepositoryTests { 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); + assertTrue("version length was wrong", + version.length() >= 40 && version.length() <= 64); } @Test public void defaultRepoNested() throws IOException { String uri = ConfigServerTestUtils.prepareLocalRepo("another-config-repo"); this.repository.setUri(uri); - this.repository.setSearchPaths(new String[] {"sub"}); + this.repository.setSearchPaths(new String[] { "sub" }); this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -107,13 +126,13 @@ public class MultipleJGitEnvironmentRepositoryTests { public void defaultRepoTag() { Environment environment = this.repository.findOne("bar", "staging", "foo"); assertEquals(2, environment.getPropertySources().size()); - assertEquals(this.repository.getUri() + "/bar.properties", environment - .getPropertySources().get(0).getName()); + assertEquals(this.repository.getUri() + "/bar.properties", + environment.getPropertySources().get(0).getName()); assertVersion(environment); } @Test - public void defaultRepoBasedir() { + public void defaultRepoTwice() { this.repository.findOne("bar", "staging", "master"); Environment environment = this.repository.findOne("bar", "staging", "master"); assertEquals(2, environment.getPropertySources().size()); @@ -122,9 +141,18 @@ public class MultipleJGitEnvironmentRepositoryTests { assertVersion(environment); } + @Test + public void defaultRepoBasedir() { + repository.setBasedir(new File("target/testBase")); + assertThat(repository.getBasedir().toString(), containsString("target/testBase")); + assertThat(repository.getRepos().get("test1").getBasedir().toString(), + containsString("/test1")); + } + @Test public void mappingRepo() { - Environment environment = this.repository.findOne("test1-svc", "staging", "master"); + Environment environment = this.repository.findOne("test1-svc", "staging", + "master"); assertEquals(2, environment.getPropertySources().size()); assertEquals(getUri("*test1*") + "/test1-svc.properties", environment.getPropertySources().get(0).getName()); @@ -152,15 +180,70 @@ public class MultipleJGitEnvironmentRepositoryTests { assertVersion(environment); } + @Test + public void shouldSetTransportConfigCallback() throws Exception { + TransportConfigCallback mockCallback1 = mock(TransportConfigCallback.class); + TransportConfigCallback mockCallback2 = mock(TransportConfigCallback.class); + + PatternMatchingJGitEnvironmentRepository repo1 = createRepository("test1", "*test1*", "test1Uri"); + + PatternMatchingJGitEnvironmentRepository repo2 = createRepository("test2", "*test2*", "test2Uri"); + repo2.setTransportConfigCallback(mockCallback2); + + Map repos = new HashMap<>(); + repos.put("test1", repo1); + repos.put("test2", repo2); + + this.repository.setRepos(repos); + this.repository.setTransportConfigCallback(mockCallback1); + this.repository.afterPropertiesSet(); + + assertEquals(repo1.getTransportConfigCallback(), mockCallback1); + assertEquals(repo2.getTransportConfigCallback(), mockCallback2); + } + + @Test + // test for gh-700 + public void basedirCreatedIfNotExists() throws Exception { + Path tempDir = Files.createTempDirectory("basedirCreatedTest"); + File parent = new File(tempDir.toFile(), "parent"); + File basedir = new File(parent, "basedir"); + this.repository.setBasedir(basedir); + + assertThat(basedir).doesNotExist(); + + this.repository.afterPropertiesSet(); + + assertThat(basedir).exists(); + } + + @Test + // test for gh-700 + public void exceptionThrownIfBasedirDoesnotExistAndCannotBeCreated() throws Exception { + File basedir = mock(File.class); + File absoluteBasedir = mock(File.class); + when(basedir.getAbsoluteFile()).thenReturn(absoluteBasedir); + + when(absoluteBasedir.exists()).thenReturn(false); + when(absoluteBasedir.mkdir()).thenReturn(false); + + this.repository.setBasedir(basedir); + + this.exception.expect(IllegalStateException.class); + this.exception.expectMessage("Basedir does not exist and can not be created:"); + + this.repository.afterPropertiesSet(); + } private String getUri(String pattern) { String uri = null; - Map repoMappings = this.repository.getRepos(); + Map repoMappings = this.repository + .getRepos(); for (PatternMatchingJGitEnvironmentRepository repo : repoMappings.values()) { String[] mappingPattern = repo.getPattern(); - if (mappingPattern != null && mappingPattern.length!=0) { + if (mappingPattern != null && mappingPattern.length != 0) { uri = repo.getUri(); break; } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepositoryTests.java index f450a08a..8fe5d9ce 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 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. @@ -15,21 +15,21 @@ */ package org.springframework.cloud.config.server.environment; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + import org.junit.Before; import org.junit.Test; - import org.springframework.boot.WebApplicationType; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.server.environment.SearchPathLocator.Locations; import org.springframework.context.ConfigurableApplicationContext; -import static org.junit.Assert.assertEquals; - /** * @author Dave Syer * @author Spencer Gibb - * + * @author Venil Noronha */ public class NativeEnvironmentRepositoryTests { @@ -165,4 +165,28 @@ public class NativeEnvironmentRepositoryTests { environment.getPropertySources().get(0).getSource().get("foo")); } + @Test + public void locationAddLabelLocations() { + this.repository.setSearchLocations("classpath:/test/dev/"); + Environment environment = this.repository.findOne("foo", "development", "ignore"); + assertEquals(2, environment.getPropertySources().size()); + assertNotEquals("dev_bar", environment.getPropertySources().get(0).getSource().get("foo")); + } + + @Test + public void locationDontAddLabelLocations() { + this.repository.setSearchLocations("classpath:/test/dev/"); + this.repository.setAddLabelLocations(false); + Environment environment = this.repository.findOne("foo", "development", "ignore"); + assertEquals(1, environment.getPropertySources().size()); + assertEquals("dev_bar", environment.getPropertySources().get(0).getSource().get("foo")); + } + + @Test + public void locationNoDuplicates() { + this.repository.setSearchLocations("classpath:/test/{profile}", "classpath:/test/dev"); + Locations locations = this.repository.getLocations("foo", "dev", null); + assertEquals(1, locations.getLocations().length); + } + } diff --git a/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml b/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml index c780b861..f587c9bb 100644 --- a/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml +++ b/spring-cloud-config-server/src/test/resources/enable-bootstrap.yml @@ -3,5 +3,11 @@ spring: config: server: git: - uri: file:./target/repos/config-repo - bootstrap: true \ No newline at end of file + uri: file:./target/repos/encrypt-repo + bootstrap: true +encrypt: + key-store: + location: classpath:server.jks + password: letmein + secret: changeme + \ No newline at end of file diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/application.yml b/spring-cloud-config-server/src/test/resources/encrypt-repo/application.yml new file mode 100644 index 00000000..13b76fa2 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/application.yml @@ -0,0 +1,9 @@ +info: + foo: bar + +--- +spring: + profiles: encrypt +config: + foo: '{cipher}{key:mytestkey}AQCohs2V6P8/UiG6a4TF/CZTCBdt5Q7wvNvcyf6vs2ByK2ZYSM77Nu0sOAduxUpMbVwJ/syecmkIXR+hU3EfT2uqPieA7/v5n33ppqIQ9JAt5JggdYIGe+wX25zU3DTXOOJdAAMzNX+zjOVyCh0QtmJf/kFslg6NqQq0E+kSg3zBi3AnkKj5BLnLIxkjxzKA4mnDXpSm7ekLZZP2iQSYSW/82AC7UOLLzTqwInMI3tJLW1e9Ne+LDsjmSxA+nkK9zhidtXPwb/SPaNF74cJCEf9mgzzKYwJlwqChLzJt8UQ1jHwRc8B6FufmizUHSp27nxdtVB4HMqh3nNsMCy137Ces58T09ZS/y/cYNRxcFbp78MHFHUqAgbC0B/p5t6h4XbQ=' + diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/bar.properties b/spring-cloud-config-server/src/test/resources/encrypt-repo/bar.properties new file mode 100644 index 00000000..7daacd5d --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/bar.properties @@ -0,0 +1 @@ +foo: bar \ No newline at end of file diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG new file mode 100644 index 00000000..a6b4e397 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/COMMIT_EDITMSG @@ -0,0 +1 @@ +Add encrypted property diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/FETCH_HEAD b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/FETCH_HEAD new file mode 100644 index 00000000..527abd40 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/FETCH_HEAD @@ -0,0 +1,2 @@ +7df4a26d5437d9d4090cd5809967f870444cde8f not-for-merge branch 'raw' of dsyer@localhost:/home/dsyer/dev/platform/config/spring-platform-config-server/target/test-classes/config-repo +7df4a26d5437d9d4090cd5809967f870444cde8f not-for-merge tag 'foo' of dsyer@localhost:/home/dsyer/dev/platform/config/spring-platform-config-server/target/test-classes/config-repo diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/HEAD b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/HEAD new file mode 100644 index 00000000..cb089cd8 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/config b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/config new file mode 100644 index 00000000..9b73bf82 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/config @@ -0,0 +1,5 @@ +[core] + repositoryformatversion = 0 + filemode = true + logallrefupdates = true +[branch "raw"] diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/gitk.cache b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/gitk.cache new file mode 100644 index 00000000..b420ccba --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/gitk.cache @@ -0,0 +1,3 @@ +1 1 +7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 +1 diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/index b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/index new file mode 100644 index 00000000..e9aa8984 Binary files /dev/null and b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/index differ diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD new file mode 100644 index 00000000..0eda72a7 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/HEAD @@ -0,0 +1,7 @@ +0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Dave Syer 1406860717 -0700 +7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Ryan Baxter 1481905383 -0500 checkout: moving from raw to master +9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter 1481905407 -0500 checkout: moving from master to raw +7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter 1481905544 -0500 checkout: moving from raw to composite +7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter 1481905552 -0500 checkout: moving from composite to raw +7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer 1498491043 +0100 checkout: moving from raw to master +9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer 1498491468 +0100 commit: Add encrypted property diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/composite b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/composite new file mode 100644 index 00000000..67ab67c5 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/composite @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter 1481905474 -0500 branch: Created from raw diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master new file mode 100644 index 00000000..4310fccd --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/master @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer 1406860776 -0700 branch: Created from 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 +9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer 1498491468 +0100 commit: Add encrypted property diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/raw b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/raw new file mode 100644 index 00000000..c6423ee9 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/logs/refs/heads/raw @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Dave Syer 1406860717 -0700 diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/13/b76fa2acbef52a002372071d08d7967fee9146 b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/13/b76fa2acbef52a002372071d08d7967fee9146 new file mode 100644 index 00000000..c7dc2ed2 Binary files /dev/null and b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/13/b76fa2acbef52a002372071d08d7967fee9146 differ diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ad/5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ad/5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc new file mode 100644 index 00000000..e9b05f26 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/ad/5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc @@ -0,0 +1,4 @@ +xM +0]$o  1z{7p{ ZeP+GDvGJ8i#6pIb + ZVK&摸[FMQ +i\7Z-7:ܤ*3Q~Zۉ[+ս4Pj.\.gI \ No newline at end of file diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/e7/7c14ccb5f9e49c11b6d4172b76b0d3cf4cef56 b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/e7/7c14ccb5f9e49c11b6d4172b76b0d3cf4cef56 new file mode 100644 index 00000000..81eeb0ca Binary files /dev/null and b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/e7/7c14ccb5f9e49c11b6d4172b76b0d3cf4cef56 differ diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.idx b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.idx new file mode 100644 index 00000000..2a25a7b0 Binary files /dev/null and b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.idx differ diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.pack b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.pack new file mode 100644 index 00000000..a082f3c1 Binary files /dev/null and b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/objects/pack/pack-d4edd2290fa647beaa1255881228dc90c1d53fce.pack differ diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/composite b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/composite new file mode 100644 index 00000000..4389eb3a --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/composite @@ -0,0 +1 @@ +7df4a26d5437d9d4090cd5809967f870444cde8f diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master new file mode 100644 index 00000000..ae0c4a61 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/master @@ -0,0 +1 @@ +ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/raw b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/raw new file mode 100644 index 00000000..4389eb3a --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/heads/raw @@ -0,0 +1 @@ +7df4a26d5437d9d4090cd5809967f870444cde8f diff --git a/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/tags/foo b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/tags/foo new file mode 100644 index 00000000..4389eb3a --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/encrypt-repo/git/refs/tags/foo @@ -0,0 +1 @@ +7df4a26d5437d9d4090cd5809967f870444cde8f diff --git a/spring-cloud-config-server/src/test/resources/test/dev/ignore/application.properties b/spring-cloud-config-server/src/test/resources/test/dev/ignore/application.properties new file mode 100644 index 00000000..e9e0aaf5 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/test/dev/ignore/application.properties @@ -0,0 +1 @@ +foo: app \ No newline at end of file