Skip to content

Commit 40cf7ee

Browse files
saranyaillaalter-mage
authored andcommitted
fix: wait for security service while configuring the http client mutual auth (#1697)
1 parent 8207549 commit 40cf7ee

File tree

10 files changed

+30
-25
lines changed

10 files changed

+30
-25
lines changed

src/main/java/com/aws/greengrass/componentmanager/ClientConfigurationUtils.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,12 @@ public static String getGreengrassServiceEndpoint(DeviceConfiguration deviceConf
9797
*
9898
* @param deviceConfiguration {@link DeviceConfiguration}
9999
* @return configured http client
100+
* @throws TLSAuthException if there is an issue configuring the http client
100101
*/
101-
public static ApacheHttpClient.Builder getConfiguredClientBuilder(DeviceConfiguration deviceConfiguration) {
102+
public static ApacheHttpClient.Builder getConfiguredClientBuilder(DeviceConfiguration deviceConfiguration)
103+
throws TLSAuthException {
102104
ApacheHttpClient.Builder httpClient = ProxyUtils.getSdkHttpClientBuilder();
103-
104-
try {
105-
configureClientMutualTLS(httpClient, deviceConfiguration);
106-
} catch (TLSAuthException e) {
107-
logger.atWarn("configure-greengrass-mutual-auth")
108-
.log("Error during configure greengrass client mutual auth", e);
109-
}
105+
configureClientMutualTLS(httpClient, deviceConfiguration);
110106
return httpClient;
111107
}
112108

src/main/java/com/aws/greengrass/deployment/DeploymentDocumentDownloader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.aws.greengrass.util.RetryUtils;
2626
import com.aws.greengrass.util.SerializerFactory;
2727
import com.aws.greengrass.util.Utils;
28+
import com.aws.greengrass.util.exceptions.TLSAuthException;
2829
import lombok.AccessLevel;
2930
import lombok.Getter;
3031
import lombok.Setter;
@@ -222,6 +223,9 @@ private GetDeploymentConfigurationResponse getDeploymentConfiguration(String dep
222223
} catch (SdkClientException e) {
223224
throw new RetryableDeploymentDocumentDownloadException(
224225
"Failed to contact Greengrass cloud or unable to parse response", e);
226+
} catch (TLSAuthException e) {
227+
throw new RetryableClientErrorException(
228+
"Failed to contact Greengrass cloud or unable to parse response", e);
225229
}
226230
return deploymentConfiguration;
227231
}

src/main/java/com/aws/greengrass/iot/IotCloudHelper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.aws.greengrass.util.BaseRetryableAccessor;
1212
import com.aws.greengrass.util.CrashableSupplier;
1313
import com.aws.greengrass.util.Utils;
14+
import com.aws.greengrass.util.exceptions.TLSAuthException;
1415
import lombok.NoArgsConstructor;
1516
import software.amazon.awssdk.http.AbortableInputStream;
1617
import software.amazon.awssdk.http.ExecutableHttpRequest;
@@ -47,10 +48,11 @@ public class IotCloudHelper {
4748
* @param body Http body for the request
4849
* @return Http response corresponding to http request for path
4950
* @throws AWSIotException when unable to send the request successfully
51+
* @throws TLSAuthException when unable to configure the client with mTLS
5052
*/
5153
public IotCloudResponse sendHttpRequest(final IotConnectionManager connManager, String thingName, final String path,
5254
final String verb, final byte[] body)
53-
throws AWSIotException {
55+
throws AWSIotException, TLSAuthException {
5456
URI uri = null;
5557
try {
5658
uri = connManager.getURI();

src/main/java/com/aws/greengrass/iot/IotConnectionManager.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.aws.greengrass.util.LockFactory;
1414
import com.aws.greengrass.util.LockScope;
1515
import com.aws.greengrass.util.Utils;
16+
import com.aws.greengrass.util.exceptions.TLSAuthException;
1617
import software.amazon.awssdk.http.SdkHttpClient;
1718

1819
import java.io.Closeable;
@@ -55,9 +56,9 @@ public URI getURI() throws DeviceConfigurationException {
5556

5657
/**
5758
* Initializes and returns the SdkHttpClient.
58-
*
59+
* @throws TLSAuthException when unable to initialize the SdkHttpClient
5960
*/
60-
public SdkHttpClient getClient() {
61+
public SdkHttpClient getClient() throws TLSAuthException {
6162
try (LockScope ls = LockScope.lock(lock)) {
6263
if (this.client == null) {
6364
this.client = initConnectionManager();
@@ -81,7 +82,7 @@ private void reconfigureOnConfigChange() {
8182
});
8283
}
8384

84-
private SdkHttpClient initConnectionManager() {
85+
private SdkHttpClient initConnectionManager() throws TLSAuthException {
8586
return ClientConfigurationUtils.getConfiguredClientBuilder(deviceConfiguration).build();
8687
}
8788

src/main/java/com/aws/greengrass/security/SecurityService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ public final class SecurityService {
4848
private static final String KEY_TYPE = "keyType";
4949
private static final String KEY_URI = "keyUri";
5050
private static final String CERT_URI = "certificateUri";
51-
5251
// retry 3 times with exponential backoff, start with 200ms,
5352
// if service still not available, pop exception to the caller
5453
private static final RetryUtils.RetryConfig GET_KEY_MANAGERS_RETRY_CONFIG = RetryUtils.RetryConfig.builder()
55-
.initialRetryInterval(Duration.ofMillis(200)).maxAttempt(3)
54+
.initialRetryInterval(Duration.ofSeconds(5)).maxAttempt(Integer.MAX_VALUE)
55+
.maxRetryInterval(Duration.ofSeconds(30))
5656
.retryableExceptions(Collections.singletonList(ServiceUnavailableException.class)).build();
5757

5858
// retry 4 times with exponential backoff, start with 300ms,

src/main/java/com/aws/greengrass/tes/CredentialRequestHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.aws.greengrass.util.DefaultConcurrentHashMap;
2222
import com.aws.greengrass.util.LockFactory;
2323
import com.aws.greengrass.util.LockScope;
24+
import com.aws.greengrass.util.exceptions.TLSAuthException;
2425
import com.fasterxml.jackson.core.JsonProcessingException;
2526
import com.fasterxml.jackson.databind.DeserializationFeature;
2627
import com.fasterxml.jackson.databind.JsonNode;
@@ -312,7 +313,7 @@ private byte[] getCredentialsBypassCache() {
312313

313314
tesCache.get(iotCredentialsPath).expiry = newExpiry;
314315
tesCache.get(iotCredentialsPath).credentials = response;
315-
} catch (AWSIotException e) {
316+
} catch (AWSIotException | TLSAuthException e) {
316317
// Http connection error should expire immediately
317318
String responseString = "Failed to get connection";
318319
response = responseString.getBytes(StandardCharsets.UTF_8);

src/main/java/com/aws/greengrass/util/GreengrassServiceClientFactory.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.aws.greengrass.deployment.exceptions.DeviceConfigurationException;
1313
import com.aws.greengrass.logging.api.Logger;
1414
import com.aws.greengrass.logging.impl.LogManager;
15+
import com.aws.greengrass.util.exceptions.TLSAuthException;
1516
import lombok.AccessLevel;
1617
import lombok.Getter;
1718
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
@@ -138,9 +139,10 @@ public String getConfigValidationError() {
138139
* Initializes and returns GreengrassV2DataClient.
139140
* Note that this method can return null if there is a config validation error.
140141
* @deprecated use fetchGreengrassV2DataClient instead.
142+
* @throws TLSAuthException if the client is not configured properly.
141143
*/
142144
@Deprecated
143-
public GreengrassV2DataClient getGreengrassV2DataClient() {
145+
public GreengrassV2DataClient getGreengrassV2DataClient() throws TLSAuthException {
144146
try (LockScope ls = LockScope.lock(lock)) {
145147
if (getConfigValidationError() != null) {
146148
logger.atWarn()
@@ -158,8 +160,9 @@ public GreengrassV2DataClient getGreengrassV2DataClient() {
158160
/**
159161
* Initializes and returns GreengrassV2DataClient.
160162
* @throws DeviceConfigurationException when fails to validate configs.
163+
* @throws TLSAuthException when fails to configure the client
161164
*/
162-
public GreengrassV2DataClient fetchGreengrassV2DataClient() throws DeviceConfigurationException {
165+
public GreengrassV2DataClient fetchGreengrassV2DataClient() throws DeviceConfigurationException, TLSAuthException {
163166
try (LockScope ls = LockScope.lock(lock)) {
164167
if (getConfigValidationError() != null) {
165168
logger.atWarn()
@@ -176,14 +179,14 @@ public GreengrassV2DataClient fetchGreengrassV2DataClient() throws DeviceConfigu
176179
}
177180

178181
// Caching a http client since it only needs to be recreated if the cert/keys change
179-
private void configureHttpClient(DeviceConfiguration deviceConfiguration) {
182+
private void configureHttpClient(DeviceConfiguration deviceConfiguration) throws TLSAuthException {
180183
logger.atDebug().log("Configuring http client for greengrass v2 data client");
181184
ApacheHttpClient.Builder httpClientBuilder =
182185
ClientConfigurationUtils.getConfiguredClientBuilder(deviceConfiguration);
183186
cachedHttpClient = httpClientBuilder.build();
184187
}
185188

186-
private void configureClient(DeviceConfiguration deviceConfiguration) {
189+
private void configureClient(DeviceConfiguration deviceConfiguration) throws TLSAuthException {
187190
if (cachedHttpClient == null) {
188191
configureHttpClient(deviceConfiguration);
189192
}

src/test/java/com/aws/greengrass/componentmanager/ComponentServiceHelperTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void GIVEN_component_version_requirements_WHEN_resolve_component_version_THEN_se
124124

125125
@Test
126126
void GIVEN_component_version_requirements_WHEN_service_no_resource_found_THEN_throw_no_available_version_exception()
127-
throws DeviceConfigurationException {
127+
throws Exception {
128128
String expMessage = "Component A has no usable version satisfying requirements B";
129129
when(clientFactory.fetchGreengrassV2DataClient()).thenReturn(client);
130130
when(client.resolveComponentCandidates(any(ResolveComponentCandidatesRequest.class)))
@@ -142,7 +142,7 @@ void GIVEN_component_version_requirements_WHEN_service_no_resource_found_THEN_th
142142

143143
@Test
144144
void GIVEN_component_version_requirements_WHEN_service_incompatible_platform_claim_THEN_throw_incompatible_platform_claim_exception()
145-
throws DeviceConfigurationException {
145+
throws Exception {
146146
String expMessage = "The latest version of Component A doesn't claim platform B compatibility";
147147
when(clientFactory.fetchGreengrassV2DataClient()).thenReturn(client);
148148
when(client.resolveComponentCandidates(any(ResolveComponentCandidatesRequest.class)))

src/test/java/com/aws/greengrass/componentmanager/builtins/GreengrassRepositoryDownloaderTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import com.aws.greengrass.config.Topic;
1515
import com.aws.greengrass.dependency.Context;
1616
import com.aws.greengrass.deployment.DeviceConfiguration;
17-
import com.aws.greengrass.deployment.exceptions.DeviceConfigurationException;
1817
import com.aws.greengrass.deployment.exceptions.RetryableServerErrorException;
1918
import com.aws.greengrass.testcommons.testutilities.GGExtension;
2019
import com.aws.greengrass.util.GreengrassServiceClientFactory;
@@ -87,7 +86,7 @@ class GreengrassRepositoryDownloaderTest {
8786
Context context;
8887

8988
@BeforeEach
90-
void beforeEach() throws DeviceConfigurationException {
89+
void beforeEach() throws Exception {
9190
lenient().when(clientFactory.fetchGreengrassV2DataClient()).thenReturn(client);
9291
}
9392

src/test/java/com/aws/greengrass/deployment/DeploymentDocumentDownloaderTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.aws.greengrass.dependency.Context;
1111
import com.aws.greengrass.deployment.converter.DeploymentDocumentConverter;
1212
import com.aws.greengrass.deployment.exceptions.DeploymentTaskFailureException;
13-
import com.aws.greengrass.deployment.exceptions.DeviceConfigurationException;
1413
import com.aws.greengrass.deployment.exceptions.RetryableClientErrorException;
1514
import com.aws.greengrass.deployment.exceptions.RetryableDeploymentDocumentDownloadException;
1615
import com.aws.greengrass.deployment.exceptions.RetryableServerErrorException;
@@ -98,7 +97,7 @@ class DeploymentDocumentDownloaderTest {
9897
private DeploymentDocumentDownloader downloader;
9998

10099
@BeforeEach
101-
void beforeEach() throws DeviceConfigurationException {
100+
void beforeEach() throws Exception {
102101
when(greengrassServiceClientFactory.fetchGreengrassV2DataClient()).thenReturn(greengrassV2DataClient);
103102
lenient().when(deviceConfiguration.isDeviceConfiguredToTalkToCloud()).thenReturn(true);
104103
when(deviceConfiguration.getThingName()).thenReturn(thingNameTopic);

0 commit comments

Comments
 (0)