From 1360dc10ce696fbab951948e9dcca31e9c10e9aa Mon Sep 17 00:00:00 2001 From: lwilhelm Date: Thu, 5 Oct 2023 10:18:02 +0200 Subject: [PATCH] delete GitConfigurationRepository This commit deletes the `GitConfigurationRepository` and related classes. It has been deprecated for a while. A planned new feature of configs with structured types would require adding more testing for this repository. Instead of making this effort, the repo is removed prior to developing this new feature instead. --- .../baigan/service/github/GitCacheLoader.java | 160 ----------------- .../baigan/service/github/GitConfig.java | 45 ----- .../github/GitConfigurationRepository.java | 54 ------ .../org/zalando/baigan/e2e/End2EndIT.java | 88 ++++++++- .../org/zalando/baigan/e2e/TestContext.java | 88 --------- .../ConfigurationServiceBeanFactoryIT.java | 41 ++--- .../service/github/GitCacheLoaderTest.java | 170 ------------------ 7 files changed, 98 insertions(+), 548 deletions(-) delete mode 100644 src/main/java/org/zalando/baigan/service/github/GitCacheLoader.java delete mode 100644 src/main/java/org/zalando/baigan/service/github/GitConfig.java delete mode 100644 src/main/java/org/zalando/baigan/service/github/GitConfigurationRepository.java delete mode 100644 src/test/java/org/zalando/baigan/e2e/TestContext.java delete mode 100644 src/test/java/org/zalando/baigan/service/github/GitCacheLoaderTest.java diff --git a/src/main/java/org/zalando/baigan/service/github/GitCacheLoader.java b/src/main/java/org/zalando/baigan/service/github/GitCacheLoader.java deleted file mode 100644 index 4f6c7fd..0000000 --- a/src/main/java/org/zalando/baigan/service/github/GitCacheLoader.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.zalando.baigan.service.github; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; - -import org.eclipse.egit.github.core.RepositoryContents; -import org.eclipse.egit.github.core.RepositoryId; -import org.eclipse.egit.github.core.client.GitHubClient; -import org.eclipse.egit.github.core.service.ContentsService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.zalando.baigan.model.Configuration; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.guava.GuavaModule; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Strings; -import com.google.common.cache.CacheLoader; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; - -import javax.annotation.Nonnull; - -import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; -import static org.apache.commons.codec.binary.Base64.*; - -/** - * This class implements the {@link CacheLoader} offering Configuration loading - * from a remote Git repository. - * - * @author mchand - * - */ -public class GitCacheLoader - extends CacheLoader> { - - private static final Logger LOG = LoggerFactory - .getLogger(GitCacheLoader.class); - - private String latestSha; - - private GitConfig config; - - private final ListeningExecutorService executorService = listeningDecorator(Executors.newFixedThreadPool(1)); - private ObjectMapper objectMapper = new ObjectMapper().registerModule(new GuavaModule()); - - private final ContentsService contentsService; - - private static ContentsService buildContentsService(@Nonnull final GitConfig gitConfig) { - Objects.requireNonNull(gitConfig, "gitConfig is required"); - final GitHubClient client = new GitHubClient(gitConfig.getGitHost()); - client.setOAuth2Token(gitConfig.getOauthToken()); - return new ContentsService(client); - } - - public GitCacheLoader(@Nonnull final GitConfig gitConfig) { - this(gitConfig, buildContentsService(gitConfig)); - } - - @VisibleForTesting - GitCacheLoader(GitConfig gitConfig, ContentsService contentsService) { - this.config = gitConfig; - this.contentsService = contentsService; - } - - @Override - public Map load(String key) throws Exception { - final RepositoryContents contents = getContentsForFile(key); - if (contents != null) { - return updateContent(contents); - } - LOG.warn("Failed to load the repository contents for {}", key); - return ImmutableMap.of(); - } - - private Map updateContent( - @Nonnull final RepositoryContents contents) { - final String contentsSha = contents.getSha(); - LOG.info("Loading the new repository contents [ SHA:{} ; NAME:{} ] ", - contentsSha, contents.getPath()); - - final List configurations = getConfigurations(getTextContent(contents)); - - latestSha = contentsSha; - - final ImmutableMap.Builder builder = ImmutableMap.builder(); - for (final Configuration each : configurations) { - builder.put(each.getAlias(), each); - } - return builder.build(); - } - - public ListenableFuture> reload(final String key, - final Map oldValue) throws Exception { - return createFuture(key, oldValue); - } - - private ListenableFuture> createFuture( - final String sourceFile, - final Map oldValue) { - - final Callable> callable = () -> { - final RepositoryContents contents = getContentsForFile(sourceFile); - // If the contents is null, return old value, this is to - // preserve in case Github is down. - // If the hash is null which is very unlikely, or it is same as - // the earlier one, we don't reload it - if (contents == null || Strings.isNullOrEmpty(contents.getSha()) - || contents.getSha().equals(latestSha)) { - return oldValue; - } - return updateContent(contents); - }; - - return executorService.submit(callable); - } - - private RepositoryContents getContentsForFile(final String sourceFile) { - - try { - final List contents = contentsService - .getContents( - new RepositoryId(config.getRepoOwner(), - config.getRepoName()), - sourceFile, config.getRepoRefs()); - return contents.get(0); - } catch (Exception e) { - LOG.warn("Failed to get contents from the Github repository ", e); - } - return null; - } - - private String getTextContent(final RepositoryContents content) { - final String stringContent = content.getContent(); - return new String(decodeBase64(stringContent.getBytes())); - } - - private List getConfigurations(final String text) { - try { - return objectMapper.readValue(text, - new TypeReference>() { - }); - } catch (IOException e) { - LOG.warn( - "Exception while deserializing the Configuration from the Github repository contents." + - "Please check to see if if matches the Configuration schema at " + - "https://github.com/zalando/baigan-config.", - e); - } - return ImmutableList.of(); - } - -} \ No newline at end of file diff --git a/src/main/java/org/zalando/baigan/service/github/GitConfig.java b/src/main/java/org/zalando/baigan/service/github/GitConfig.java deleted file mode 100644 index 181aa94..0000000 --- a/src/main/java/org/zalando/baigan/service/github/GitConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.zalando.baigan.service.github; - -public class GitConfig { - private String repoRefs; - private String repoName; - private String repoOwner; - private String gitHost; - private String oauthToken; - private String sourceFile; - - public GitConfig(String gitHost, String repoOwner, String repoName, - String repoRefs, String sourceFile, String oauthToken) { - this.repoRefs = repoRefs; - this.repoName = repoName; - this.repoOwner = repoOwner; - this.gitHost = gitHost; - this.oauthToken = oauthToken; - this.sourceFile = sourceFile; - } - - public String getRepoRefs() { - return repoRefs; - } - - public String getRepoName() { - return repoName; - } - - public String getRepoOwner() { - return repoOwner; - } - - public String getGitHost() { - return gitHost; - } - - public String getOauthToken() { - return oauthToken; - } - - public String getSourceFile() { - return sourceFile; - } - -} \ No newline at end of file diff --git a/src/main/java/org/zalando/baigan/service/github/GitConfigurationRepository.java b/src/main/java/org/zalando/baigan/service/github/GitConfigurationRepository.java deleted file mode 100644 index 05a8578..0000000 --- a/src/main/java/org/zalando/baigan/service/github/GitConfigurationRepository.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.zalando.baigan.service.github; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.LoadingCache; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.zalando.baigan.model.Configuration; -import org.zalando.baigan.service.AbstractConfigurationRepository; - -import javax.annotation.Nonnull; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -/** - * Implementation of {link ConfigurationRepository} supporting Github as - * the persistence storage for the baigan configuration. - * - * Deprecated since 0.16.0, use some more reliable repository. - * - * @author mchand - */ -@Deprecated -public class GitConfigurationRepository extends AbstractConfigurationRepository { - private static final Logger LOG = LoggerFactory.getLogger(GitConfigurationRepository.class); - - private final LoadingCache> cachedConfigurations; - private final GitConfig gitConfig; - - public GitConfigurationRepository(long refreshIntervalInMinutes, GitConfig gitConfig) { - this.gitConfig = gitConfig; - cachedConfigurations = CacheBuilder.newBuilder() - .refreshAfterWrite(refreshIntervalInMinutes, TimeUnit.MINUTES) - .build(new GitCacheLoader(gitConfig)); - } - - @Nonnull - @Override - public Optional get(@Nonnull String key) { - try { - return Optional.ofNullable(cachedConfigurations.get(gitConfig.getSourceFile()).get(key)); - } catch (ExecutionException e) { - LOG.warn("Exception while trying to get configuration for key {}", key, e); - } - return Optional.empty(); - } - - @Override - public void put(@Nonnull String key, @Nonnull String value) { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/test/java/org/zalando/baigan/e2e/End2EndIT.java b/src/test/java/org/zalando/baigan/e2e/End2EndIT.java index 86f164f..bd221c0 100644 --- a/src/test/java/org/zalando/baigan/e2e/End2EndIT.java +++ b/src/test/java/org/zalando/baigan/e2e/End2EndIT.java @@ -1,21 +1,42 @@ package org.zalando.baigan.e2e; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.kms.AWSKMS; +import com.amazonaws.services.kms.AWSKMSClientBuilder; import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.AmazonS3Exception; +import com.amazonaws.services.s3.model.CreateBucketRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.localstack.LocalStackContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; +import org.zalando.baigan.BaiganSpringContext; +import org.zalando.baigan.annotation.ConfigurationServiceScan; import org.zalando.baigan.fixture.SomeConfiguration; +import org.zalando.baigan.service.ConfigurationRepository; +import org.zalando.baigan.service.aws.S3ConfigurationRepositoryBuilder; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; -import static org.zalando.baigan.e2e.TestContext.S3_CONFIG_BUCKET; -import static org.zalando.baigan.e2e.TestContext.S3_CONFIG_KEY; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.KMS; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; +import static org.zalando.baigan.e2e.End2EndIT.RepoConfig.S3_CONFIG_BUCKET; +import static org.zalando.baigan.e2e.End2EndIT.RepoConfig.S3_CONFIG_KEY; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = {TestContext.class}) +@ContextConfiguration(classes = {End2EndIT.RepoConfig.class}) public class End2EndIT { @Autowired @@ -31,4 +52,65 @@ public void givenS3Configuration_whenConfigurationIsChangedOnS3_thenConfiguratio Thread.sleep(1100); assertThat(someConfiguration.someValue(), equalTo("a value")); } + + @ComponentScan(basePackageClasses = BaiganSpringContext.class) + @ConfigurationServiceScan(basePackages = "org.zalando.baigan.fixture") + @Testcontainers + static class RepoConfig { + + public static final String S3_CONFIG_BUCKET = "some-bucket"; + public static final String S3_CONFIG_KEY = "some-key"; + + @Container + private static final LocalStackContainer localstack = new LocalStackContainer( + DockerImageName.parse("localstack/localstack:2.1.0") + ).withServices(S3, KMS).withEnv("DEFAULT_REGION", Regions.EU_CENTRAL_1.getName()); + + @Bean + ConfigurationRepository configurationRepository(AmazonS3 amazonS3, AWSKMS kms) { + amazonS3.putObject(S3_CONFIG_BUCKET, S3_CONFIG_KEY, "[]"); + + return new S3ConfigurationRepositoryBuilder() + .bucketName(S3_CONFIG_BUCKET) + .key(S3_CONFIG_KEY) + .s3Client(amazonS3) + .kmsClient(kms) + .refreshIntervalInSeconds(1) + .build(); + } + + @Bean + AWSKMS kms() { + localstack.start(); + return AWSKMSClientBuilder.standard().withEndpointConfiguration( + new AwsClientBuilder.EndpointConfiguration( + localstack.getEndpointOverride(KMS).toString(), localstack.getRegion() + ) + ).build(); + } + + @Bean + AmazonS3 amazonS3() { + localstack.start(); + AmazonS3 s3 = AmazonS3ClientBuilder.standard().withEndpointConfiguration( + new AwsClientBuilder.EndpointConfiguration( + localstack.getEndpointOverride(S3).toString(), localstack.getRegion() + ) + ).withCredentials( + new AWSStaticCredentialsProvider( + new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + ) + ).build(); + + try { + s3.createBucket(new CreateBucketRequest(S3_CONFIG_BUCKET, localstack.getRegion())); + } catch (AmazonS3Exception e) { + if (!e.getErrorCode().equals("BucketAlreadyOwnedByYou")) { + throw e; + } + } + + return s3; + } + } } diff --git a/src/test/java/org/zalando/baigan/e2e/TestContext.java b/src/test/java/org/zalando/baigan/e2e/TestContext.java deleted file mode 100644 index 61bafd1..0000000 --- a/src/test/java/org/zalando/baigan/e2e/TestContext.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.zalando.baigan.e2e; - -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.regions.Regions; -import com.amazonaws.services.kms.AWSKMS; -import com.amazonaws.services.kms.AWSKMSClientBuilder; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; -import com.amazonaws.services.s3.model.AmazonS3Exception; -import com.amazonaws.services.s3.model.CreateBucketRequest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.testcontainers.containers.localstack.LocalStackContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; -import org.testcontainers.utility.DockerImageName; -import org.zalando.baigan.BaiganSpringContext; -import org.zalando.baigan.annotation.ConfigurationServiceScan; -import org.zalando.baigan.service.ConfigurationRepository; -import org.zalando.baigan.service.aws.S3ConfigurationRepositoryBuilder; - -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.KMS; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; - -@Configuration -@ComponentScan(basePackageClasses = BaiganSpringContext.class) -@ConfigurationServiceScan(basePackages = "org.zalando.baigan.fixture") -@Testcontainers -class TestContext { - - public static final String S3_CONFIG_BUCKET = "some-bucket"; - public static final String S3_CONFIG_KEY = "some-key"; - - @Container - private static final LocalStackContainer localstack = new LocalStackContainer( - DockerImageName.parse("localstack/localstack:2.1.0") - ).withServices(S3, KMS).withEnv("DEFAULT_REGION", Regions.EU_CENTRAL_1.getName()); - - @Bean - ConfigurationRepository configurationRepository(AmazonS3 amazonS3, AWSKMS kms) { - amazonS3.putObject(S3_CONFIG_BUCKET, S3_CONFIG_KEY, "[]"); - - return new S3ConfigurationRepositoryBuilder() - .bucketName(S3_CONFIG_BUCKET) - .key(S3_CONFIG_KEY) - .s3Client(amazonS3) - .kmsClient(kms) - .refreshIntervalInSeconds(1) - .build(); - } - - @Bean - AWSKMS kms() { - localstack.start(); - return AWSKMSClientBuilder.standard().withEndpointConfiguration( - new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpointOverride(KMS).toString(), localstack.getRegion() - ) - ).build(); - } - - @Bean - AmazonS3 amazonS3() { - localstack.start(); - AmazonS3 s3 = AmazonS3ClientBuilder.standard().withEndpointConfiguration( - new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpointOverride(S3).toString(), localstack.getRegion() - ) - ).withCredentials( - new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) - ) - ).build(); - - try { - s3.createBucket(new CreateBucketRequest(S3_CONFIG_BUCKET, localstack.getRegion())); - } catch (AmazonS3Exception e) { - if (!e.getErrorCode().equals("BucketAlreadyOwnedByYou")) { - throw e; - } - } - - return s3; - } -} diff --git a/src/test/java/org/zalando/baigan/proxy/ConfigurationServiceBeanFactoryIT.java b/src/test/java/org/zalando/baigan/proxy/ConfigurationServiceBeanFactoryIT.java index bdce511..2ffeda4 100644 --- a/src/test/java/org/zalando/baigan/proxy/ConfigurationServiceBeanFactoryIT.java +++ b/src/test/java/org/zalando/baigan/proxy/ConfigurationServiceBeanFactoryIT.java @@ -9,16 +9,12 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.zalando.baigan.BaiganSpringContext; -import org.zalando.baigan.annotation.BaiganConfig; import org.zalando.baigan.annotation.ConfigurationServiceScan; -import org.zalando.baigan.context.SpringTestContext; +import org.zalando.baigan.fixture.SomeConfiguration; import org.zalando.baigan.service.ConfigurationRepository; -import org.zalando.baigan.service.github.GitConfig; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -30,24 +26,19 @@ @ContextConfiguration(classes = {ConfigurationServiceBeanFactoryIT.TestContext.class}) public class ConfigurationServiceBeanFactoryIT { - @Configuration - @ComponentScan( - basePackageClasses = {BaiganSpringContext.class}, - excludeFilters = @ComponentScan.Filter( - classes = SpringTestContext.class, - type = FilterType.ASSIGNABLE_TYPE)) + @ComponentScan(basePackageClasses = {BaiganSpringContext.class}) @ConfigurationServiceScan(basePackages = "org.zalando.baigan.proxy") static class TestContext { @Bean - ConfigurationRepository configurationRepository(final GitConfig configuration) { + ConfigurationRepository configurationRepository(final SomeConfiguration someConfiguration) { return mock(ConfigurationRepository.class); } - @Bean(name = "gitConfiguration") - GitConfig gitConfiguration() { - final GitConfig config = mock(GitConfig.class); - when(config.getGitHost()).thenReturn("raw.com"); + @Bean(name = "someConfiguration") + SomeConfiguration someConfiguration() { + final SomeConfiguration config = mock(SomeConfiguration.class); + when(config.someValue()).thenReturn("a value"); return config; } @@ -72,8 +63,8 @@ public Object postProcessBeforeInitialization(final Object bean, final String be @Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { - if ("gitConfiguration".equals(beanName)) { - when(((GitConfig) bean).getGitHost()).thenReturn("post-processed.com"); + if ("someConfiguration".equals(beanName)) { + when(((SomeConfiguration) bean).someValue()).thenReturn("a post-processed value"); } return bean; } @@ -95,25 +86,19 @@ public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFac } } - @BaiganConfig - public interface TestFeature { - - Boolean enabled(); - } - @Autowired - private GitConfig gitConfig; + private SomeConfiguration someConfig; @Autowired private MyDependency myDependency; @Test - public void allowsPostProcessingOfBeans() throws Exception { - assertThat(gitConfig.getGitHost(), is("post-processed.com")); + public void allowsPostProcessingOfBeans() { + assertThat(someConfig.someValue(), is("a post-processed value")); } @Test - public void allowsPostProcessingOfFactoryBeans() throws Exception { + public void allowsPostProcessingOfFactoryBeans() { assertThat(myDependency, is(notNullValue())); } } diff --git a/src/test/java/org/zalando/baigan/service/github/GitCacheLoaderTest.java b/src/test/java/org/zalando/baigan/service/github/GitCacheLoaderTest.java deleted file mode 100644 index 10b9484..0000000 --- a/src/test/java/org/zalando/baigan/service/github/GitCacheLoaderTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.zalando.baigan.service.github; - -import com.google.common.collect.ImmutableList; -import com.google.common.util.concurrent.ListenableFuture; -import org.apache.commons.codec.binary.Base64; -import org.eclipse.egit.github.core.RepositoryContents; -import org.eclipse.egit.github.core.service.ContentsService; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.zalando.baigan.model.Configuration; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.IOException; -import java.security.MessageDigest; -import java.util.Map; - -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -public class GitCacheLoaderTest { - - private String testConfiguration1 = "[{ \"alias\": \"express.feature.toggle\", \"description\": \"Feature toggle\", \"defaultValue\": false, \"conditions\": [ { " - + " \"value\": true, \"conditionType\": { \"onValue\": \"3\", \"type\": \"Equals\" }, \"paramName\": \"appdomain\" } ] }]"; - - private String testConfiguration2 = "[{ \"alias\": \"express.feature.toggle\", \"description\": \"Feature toggle\", \"defaultValue\": false, \"conditions\": [ { " - + " \"value\": true, \"conditionType\": { \"onValue\": \"3\", \"type\": \"Equals\" }, \"paramName\": \"appdomain\" } ] }," - + "{ \"alias\": \"express.feature.serviceUrl\", \"description\": \"Feature Service Url\", \"defaultValue\": \"\", \"conditions\": [ { " - + " \"value\": \"http://express.trucks.zalan.do\", \"conditionType\": { \"onValue\": \"1\", \"type\": \"Equals\" }, " - + " \"paramName\": \"appdomain\" } ] }]"; - - @Test - public void testLoad() throws Exception { - - final GitConfig config = new GitConfig("somehost", "someowner", - "somerepo", "master", "somefile", "aoth_token"); - final ContentsService contentService = mock(ContentsService.class); - - final GitCacheLoader loader = new GitCacheLoader(config, - contentService); - - when(contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration1))); - - final Map configurations = loader.load("staging.json"); - assertThat(configurations.size(), equalTo(1)); - assertThat(configurations.get("express.feature.toggle"), notNullValue()); - - } - - @Test - public void testReload() throws Exception { - - final GitConfig config = new GitConfig("somehost", "someowner", - "somerepo", "master", "somefile", "aoth_token"); - final ContentsService contentService = mock(ContentsService.class); - - final GitCacheLoader loader = new GitCacheLoader(config, - contentService); - - when(contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration1))); - - Map configurations = loader.load("staging.json"); - assertThat(configurations.size(), equalTo(1)); - assertThat(configurations.get("express.feature.toggle"), notNullValue()); - - when(contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration2))); - - final ListenableFuture> configurations2Future = loader - .reload("staging.json", configurations); - - final Map configurations2 = configurations2Future - .get(); - assertThat(configurations2, not(configurations)); - - assertThat(configurations2.size(), equalTo(2)); - assertThat(configurations.get("express.feature.toggle"), notNullValue()); - - assertThat(configurations2.get("express.feature.serviceUrl"), notNullValue()); - } - - @Test - public void testForegoReloadForUnchanged() throws Exception { - - final GitConfig config = new GitConfig("somehost", "someowner", - "somerepo", "master", "somefile", "aoth_token"); - final ContentsService contentService = mock(ContentsService.class); - - final GitCacheLoader loader = new GitCacheLoader(config, contentService); - - when(contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration2))); - - final Map configurations1 = loader.load("staging.json"); - - when(contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration2))); - - final ListenableFuture> configurations2Future = loader - .reload("staging.json", configurations1); - - final Map configurations2 = configurations2Future.get(); - - assertThat(configurations2, equalTo(configurations1)); - } - - @Test - public void testReloadWithIOExceptionInConcentService() throws Exception { - - final GitConfig config = new GitConfig("somehost", "someowner", - "somerepo", "master", "somefile", "aoth_token"); - final ContentsService contentService = mock(ContentsService.class); - final GitCacheLoader loader = new GitCacheLoader(config, contentService); - - when( - contentService.getContents(any(), - eq("staging.json"), - eq("master"))) - .thenReturn(ImmutableList - .of(createRepositoryContents(testConfiguration1))); - - - Map configurations = loader.load("staging.json"); - assertThat(configurations.size(), equalTo(1)); - assertThat(configurations.get("express.feature.toggle"), - notNullValue()); - - //throw exception on retrieval - doThrow(new IOException()) - .when(contentService).getContents(any(), - eq("staging.json"), - eq("master")); - - final ListenableFuture> configurations2Future = loader - .reload("staging.json", configurations); - - final Map configurations2 = configurations2Future.get(); - assertThat(configurations2, equalTo(configurations)); - - } - - private RepositoryContents createRepositoryContents(final String text) throws Exception { - final RepositoryContents contents = new RepositoryContents(); - byte[] base64OfConfig1 = Base64.encodeBase64(text.getBytes()); - contents.setContent(new String(base64OfConfig1)); - contents.setSha(new String(MessageDigest.getInstance("MD5").digest(text.getBytes()))); - contents.setEncoding("base64"); - return contents; - } -}