From 62022c7de10afa006bf61d5d2dd2ef9ff2dd88a0 Mon Sep 17 00:00:00 2001 From: realturner Date: Fri, 16 Jul 2021 15:42:37 +0800 Subject: [PATCH] Migrate AppConfig to SDK v2 to detect and use web identify token --- service/pom.xml | 12 ++- .../storage/DynamicConfigurationManager.java | 73 ++++++++++--------- .../DynamicConfigurationManagerTest.java | 34 ++++----- 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/service/pom.xml b/service/pom.xml index db440160e..936c91dc1 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -255,6 +255,10 @@ jackson-jaxrs-json-provider + + software.amazon.awssdk + sts + software.amazon.awssdk s3 @@ -267,6 +271,10 @@ software.amazon.awssdk dynamodb + + software.amazon.awssdk + appconfig + com.amazonaws aws-java-sdk-core @@ -275,10 +283,6 @@ com.amazonaws aws-java-sdk-s3 - - com.amazonaws - aws-java-sdk-appconfig - redis.clients diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManager.java index c812c750f..ba4ff1e02 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManager.java @@ -1,31 +1,29 @@ package org.whispersystems.textsecuregcm.storage; -import com.amazonaws.ClientConfiguration; -import com.amazonaws.auth.InstanceProfileCredentialsProvider; -import com.amazonaws.services.appconfig.AmazonAppConfig; -import com.amazonaws.services.appconfig.AmazonAppConfigClient; -import com.amazonaws.services.appconfig.model.GetConfigurationRequest; -import com.amazonaws.services.appconfig.model.GetConfigurationResult; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.google.common.annotations.VisibleForTesting; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.util.Util; - -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import java.nio.charset.StandardCharsets; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; +import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; +import software.amazon.awssdk.services.appconfig.AppConfigClient; +import software.amazon.awssdk.services.appconfig.model.GetConfigurationRequest; +import software.amazon.awssdk.services.appconfig.model.GetConfigurationResponse; public class DynamicConfigurationManager { @@ -33,11 +31,11 @@ public class DynamicConfigurationManager { private final String environment; private final String configurationName; private final String clientId; - private final AmazonAppConfig appConfigClient; + private final AppConfigClient appConfigClient; private final AtomicReference configuration = new AtomicReference<>(); - private GetConfigurationResult lastConfigResult; + private GetConfigurationResponse lastConfigResult; private boolean initialized = false; @@ -50,15 +48,20 @@ public class DynamicConfigurationManager { private static final Logger logger = LoggerFactory.getLogger(DynamicConfigurationManager.class); public DynamicConfigurationManager(String application, String environment, String configurationName) { - this(AmazonAppConfigClient.builder() - .withClientConfiguration(new ClientConfiguration().withClientExecutionTimeout(10000).withRequestTimeout(10000)) - .withCredentials(InstanceProfileCredentialsProvider.getInstance()) - .build(), - application, environment, configurationName, UUID.randomUUID().toString()); + this(AppConfigClient.builder() + .overrideConfiguration(ClientOverrideConfiguration.builder() + .apiCallTimeout(Duration.ofMillis(10000)) + .apiCallAttemptTimeout(Duration.ofMillis(10000)).build()) + /* To specify specific credential provider: + https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html + */ + .build(), + application, environment, configurationName, UUID.randomUUID().toString()); } @VisibleForTesting - public DynamicConfigurationManager(AmazonAppConfig appConfigClient, String application, String environment, String configurationName, String clientId) { + public DynamicConfigurationManager(AppConfigClient appConfigClient, String application, String environment, + String configurationName, String clientId) { this.appConfigClient = appConfigClient; this.application = application; this.environment = environment; @@ -99,21 +102,24 @@ public class DynamicConfigurationManager { } private Optional retrieveDynamicConfiguration() throws JsonProcessingException { - final String previousVersion = lastConfigResult != null ? lastConfigResult.getConfigurationVersion() : null; + final String previousVersion = lastConfigResult != null ? lastConfigResult.configurationVersion() : null; - lastConfigResult = appConfigClient.getConfiguration(new GetConfigurationRequest().withApplication(application) - .withEnvironment(environment) - .withConfiguration(configurationName) - .withClientId(clientId) - .withClientConfigurationVersion(previousVersion)); + lastConfigResult = appConfigClient.getConfiguration(GetConfigurationRequest.builder() + .application(application) + .environment(environment) + .configuration(configurationName) + .clientId(clientId) + .clientConfigurationVersion(previousVersion) + .build()); final Optional maybeDynamicConfiguration; - if (!StringUtils.equals(lastConfigResult.getConfigurationVersion(), previousVersion)) { - logger.info("Received new config version: {}", lastConfigResult.getConfigurationVersion()); + if (!StringUtils.equals(lastConfigResult.configurationVersion(), previousVersion)) { + logger.info("Received new config version: {}", lastConfigResult.configurationVersion()); maybeDynamicConfiguration = - parseConfiguration(StandardCharsets.UTF_8.decode(lastConfigResult.getContent().asReadOnlyBuffer()).toString()); + parseConfiguration( + StandardCharsets.UTF_8.decode(lastConfigResult.content().asByteBuffer().asReadOnlyBuffer()).toString()); } else { // No change since last version maybeDynamicConfiguration = Optional.empty(); @@ -123,7 +129,8 @@ public class DynamicConfigurationManager { } @VisibleForTesting - public static Optional parseConfiguration(final String configurationYaml) throws JsonProcessingException { + public static Optional parseConfiguration(final String configurationYaml) + throws JsonProcessingException { final DynamicConfiguration configuration = OBJECT_MAPPER.readValue(configurationYaml, DynamicConfiguration.class); final Set> violations = VALIDATOR.validate(configuration); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManagerTest.java index 200df2782..93c25960a 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamicConfigurationManagerTest.java @@ -1,42 +1,40 @@ package org.whispersystems.textsecuregcm.storage; -import com.amazonaws.services.appconfig.AmazonAppConfig; -import com.amazonaws.services.appconfig.model.GetConfigurationRequest; -import com.amazonaws.services.appconfig.model.GetConfigurationResult; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; - -import java.nio.ByteBuffer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.services.appconfig.AppConfigClient; +import software.amazon.awssdk.services.appconfig.model.GetConfigurationRequest; +import software.amazon.awssdk.services.appconfig.model.GetConfigurationResponse; public class DynamicConfigurationManagerTest { private DynamicConfigurationManager dynamicConfigurationManager; - private AmazonAppConfig appConfig; + private AppConfigClient appConfig; @Before public void setup() { - this.appConfig = mock(AmazonAppConfig.class); + this.appConfig = mock(AppConfigClient.class); this.dynamicConfigurationManager = new DynamicConfigurationManager(appConfig, "foo", "bar", "baz", "poof"); } @Test public void testGetConfig() { ArgumentCaptor captor = ArgumentCaptor.forClass(GetConfigurationRequest.class); - when(appConfig.getConfiguration(captor.capture())).thenReturn(new GetConfigurationResult().withContent(ByteBuffer.wrap("test: true".getBytes())) - .withConfigurationVersion("1")); + when(appConfig.getConfiguration(captor.capture())).thenReturn( + GetConfigurationResponse.builder().content(SdkBytes.fromByteArray("test: true".getBytes())).configurationVersion("1").build()); dynamicConfigurationManager.start(); - assertThat(captor.getValue().getApplication()).isEqualTo("foo"); - assertThat(captor.getValue().getEnvironment()).isEqualTo("bar"); - assertThat(captor.getValue().getConfiguration()).isEqualTo("baz"); - assertThat(captor.getValue().getClientId()).isEqualTo("poof"); + assertThat(captor.getValue().application()).isEqualTo("foo"); + assertThat(captor.getValue().environment()).isEqualTo("bar"); + assertThat(captor.getValue().configuration()).isEqualTo("baz"); + assertThat(captor.getValue().clientId()).isEqualTo("poof"); assertThat(dynamicConfigurationManager.getConfiguration()).isNotNull(); }