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 7a40a718..7c65c5b5 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 @@ -90,6 +90,16 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository */ private int timeout; + /** + * Time (in seconds) between refresh of the git repository + */ + private int refreshRate = 0; + + /** + * Time of the last refresh of the git repository + */ + private long lastRefresh; + /** * Flag to indicate that the repository should be cloned on startup (not on demand). * Generally leads to slower startup but faster first query. @@ -147,6 +157,15 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository this.timeout = timeout; } + public int getRefreshRate() { + return refreshRate; + } + + public void setRefreshRate(int refreshRate) { + this.refreshRate = refreshRate; + } + + public TransportConfigCallback getTransportConfigCallback() { return transportConfigCallback; } @@ -349,6 +368,11 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository protected boolean shouldPull(Git git) throws GitAPIException { boolean shouldPull; + + if (this.refreshRate > 0 && System.currentTimeMillis() - this.lastRefresh < (this.refreshRate * 1000)) { + return false; + } + Status gitStatus = git.status().call(); boolean isWorkingTreeClean = gitStatus.isClean(); String originUrl = git.getRepository().getConfig().getString("remote", "origin", @@ -394,6 +418,9 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository fetch.setRemote("origin"); fetch.setTagOpt(TagOpt.FETCH_TAGS); fetch.setRemoveDeletedRefs(deleteUntrackedBranches); + if (this.refreshRate > 0) { + this.setLastRefresh(System.currentTimeMillis()); + } configureCommand(fetch); try { @@ -621,6 +648,14 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } } + public void setLastRefresh(long lastRefresh) { + this.lastRefresh = lastRefresh; + } + + public long getLastRefresh() { + return lastRefresh; + } + /** * Wraps the static method calls to {@link org.eclipse.jgit.api.Git} and * {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit testing. 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 99b57fbc..29c14b69 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 @@ -85,6 +85,9 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository if (getTimeout() != 0 && repo.getTimeout() == 0) { repo.setTimeout(getTimeout()); } + if (getRefreshRate() != 0 && repo.getRefreshRate() == 0) { + repo.setRefreshRate(getRefreshRate()); + } String user = repo.getUsername(); String pass = repo.getPassword(); String passphrase = repo.getPassphrase(); 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 61f65557..f4be7d1d 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 @@ -332,6 +332,67 @@ public class JGitEnvironmentRepositoryTests { assertThat("shouldPull was false", shouldPull, is(true)); } + @Test + public void shouldNotRefresh() throws Exception { + Git git = mock(Git.class); + StatusCommand statusCommand = mock(StatusCommand.class); + Status status = mock(Status.class); + Repository repository = mock(Repository.class); + StoredConfig storedConfig = mock(StoredConfig.class); + + when(git.status()).thenReturn(statusCommand); + when(git.getRepository()).thenReturn(repository); + when(repository.getConfig()).thenReturn(storedConfig); + when(storedConfig.getString("remote", "origin", "url")).thenReturn("http://example/git"); + when(statusCommand.call()).thenReturn(status); + when(status.isClean()).thenReturn(true); + + JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment); + + repo.setLastRefresh(System.currentTimeMillis() - 5000); + repo.setRefreshRate(2); + + boolean shouldPull = repo.shouldPull(git); + + assertThat("shouldPull was false", shouldPull, is(true)); + + repo.setRefreshRate(30); + + shouldPull = repo.shouldPull(git); + + assertThat("shouldPull was true", shouldPull, is(false)); + } + + @Test + public void shouldUpdateLastRefresh() throws Exception { + Git git = mock(Git.class); + StatusCommand statusCommand = mock(StatusCommand.class); + Status status = mock(Status.class); + Repository repository = mock(Repository.class); + StoredConfig storedConfig = mock(StoredConfig.class); + FetchCommand fetchCommand = mock(FetchCommand.class); + FetchResult fetchResult = mock(FetchResult.class); + + when(git.status()).thenReturn(statusCommand); + when(git.getRepository()).thenReturn(repository); + when(fetchCommand.call()).thenReturn(fetchResult); + when(git.fetch()).thenReturn(fetchCommand); + when(repository.getConfig()).thenReturn(storedConfig); + when(storedConfig.getString("remote", "origin", "url")).thenReturn("http://example/git"); + when(statusCommand.call()).thenReturn(status); + when(status.isClean()).thenReturn(true); + + JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment); + + repo.setRefreshRate(1000); + repo.setLastRefresh(0); + repo.fetch(git, "master"); + + long timeDiff = System.currentTimeMillis() - repo.getLastRefresh(); + + assertThat("time difference ("+timeDiff+") was longer than 1 second", timeDiff < 1000L, is(true)); + } + @Test public void testFetchException() throws Exception { 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 30acff54..df157a59 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 @@ -105,6 +105,26 @@ public class MultipleJGitEnvironmentRepositoryIntegrationTests { assertEquals(2, environment.getPropertySources().size()); } + @Test + public void mappingRepoWithRefreshRate() throws IOException { + String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo"); + String test1RepoUri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo"); + + Map repoMapping = new LinkedHashMap(); + repoMapping.put("spring.cloud.config.server.git.repos[test1].pattern", "*test1*"); + repoMapping.put("spring.cloud.config.server.git.repos[test1].uri", test1RepoUri); + repoMapping.put("spring.cloud.config.server.git.refreshRate", "30"); + this.context = new SpringApplicationBuilder(TestConfiguration.class).web(false) + .properties("spring.cloud.config.server.git.uri:" + defaultRepoUri) + .properties(repoMapping).run(); + EnvironmentRepository repository = this.context + .getBean(EnvironmentRepository.class); + repository.findOne("test1-svc", "staging", "master"); + Environment environment = repository.findOne("test1-svc", "staging", "master"); + assertEquals(2, environment.getPropertySources().size()); + assertEquals(((MultipleJGitEnvironmentRepository) repository).getRepos().get("test1").getRefreshRate(), 30); + } + @Test public void mappingRepoWithProfile() throws IOException { String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");