-
Notifications
You must be signed in to change notification settings - Fork 54
feat: add ability to configure tes error cache expire time #1751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7a35e70
6cd26a4
732599d
4698da7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| import com.aws.greengrass.authorization.exceptions.AuthorizationException; | ||
| import com.aws.greengrass.config.Topic; | ||
| import com.aws.greengrass.config.Topics; | ||
| import com.aws.greengrass.config.WhatHappened; | ||
| import com.aws.greengrass.dependency.ImplementsService; | ||
| import com.aws.greengrass.dependency.State; | ||
| import com.aws.greengrass.deployment.DeviceConfiguration; | ||
|
|
@@ -41,6 +42,14 @@ public class TokenExchangeService extends GreengrassService implements AwsCreden | |
| private String iotRoleAlias; | ||
| private HttpServerImpl server; | ||
|
|
||
| public static final String CLOUD_4XX_ERROR_CACHE_TOPIC = "error4xxCredentialRetryInSec"; | ||
| public static final String CLOUD_5XX_ERROR_CACHE_TOPIC = "error5xxCredentialRetryInSec"; | ||
| public static final String UNKNOWN_ERROR_CACHE_TOPIC = "errorUnknownCredentialRetryInSec"; | ||
| private static final int MINIMUM_ERROR_CACHE_IN_SEC = 10; | ||
| private int cloud4xxErrorCache; | ||
| private int cloud5xxErrorCache; | ||
| private int unknownErrorCache; | ||
|
|
||
| private final AuthorizationHandler authZHandler; | ||
| private final CredentialRequestHandler credentialRequestHandler; | ||
|
|
||
|
|
@@ -57,24 +66,69 @@ public TokenExchangeService(Topics topics, | |
| AuthorizationHandler authZHandler, DeviceConfiguration deviceConfiguration) { | ||
| super(topics); | ||
| port = Coerce.toInt(config.lookup(CONFIGURATION_CONFIG_KEY, PORT_TOPIC).dflt(DEFAULT_PORT)); | ||
|
|
||
| deviceConfiguration.getIotRoleAlias().subscribe((why, newv) -> { | ||
| iotRoleAlias = Coerce.toString(newv); | ||
| }); | ||
|
|
||
| this.authZHandler = authZHandler; | ||
| this.credentialRequestHandler = credentialRequestHandler; | ||
|
|
||
| cloud4xxErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_4XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_4XX_ERROR_CACHE_TOPIC)), CLOUD_4XX_ERROR_CACHE_TOPIC); | ||
| cloud5xxErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_5XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_5XX_ERROR_CACHE_TOPIC)), CLOUD_5XX_ERROR_CACHE_TOPIC); | ||
| unknownErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.UNKNOWN_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| UNKNOWN_ERROR_CACHE_TOPIC)), UNKNOWN_ERROR_CACHE_TOPIC); | ||
|
|
||
| credentialRequestHandler.configureCacheSettings(cloud4xxErrorCache, cloud5xxErrorCache, unknownErrorCache); | ||
|
|
||
| // Subscribe to cache configuration changes | ||
| config.subscribe((why, node) -> { | ||
saranyailla marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (node != null && node.childOf(PORT_TOPIC)) { | ||
| if (why.equals(WhatHappened.timestampUpdated)) { | ||
| return; | ||
| } | ||
| if (node != null && (node.childOf(PORT_TOPIC) | ||
| || node.childOf(CLOUD_4XX_ERROR_CACHE_TOPIC) | ||
| || node.childOf(CLOUD_5XX_ERROR_CACHE_TOPIC) | ||
| || node.childOf(UNKNOWN_ERROR_CACHE_TOPIC))) { | ||
|
Comment on lines
+94
to
+97
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: We don't need to execute this callback if the what happened events are irrelevant to this. For eg, see how we don't take an action if the what happened event doesn't show a change in value. |
||
| logger.atDebug("tes-config-change").kv("node", node).kv("why", why).log(); | ||
|
|
||
| port = Coerce.toInt(node); | ||
| Topic activePortTopic = config.lookup(CONFIGURATION_CONFIG_KEY, ACTIVE_PORT_TOPIC); | ||
| if (port != Coerce.toInt(activePortTopic)) { | ||
| logger.atInfo("tes-config-change").kv(PORT_TOPIC, port).kv("node", node).kv("why", why) | ||
| .log("Restarting TES server due to port config change"); | ||
|
|
||
| int newCloud4xxErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_4XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_4XX_ERROR_CACHE_TOPIC)), CLOUD_4XX_ERROR_CACHE_TOPIC); | ||
| int newCloud5xxErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_5XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_5XX_ERROR_CACHE_TOPIC)), CLOUD_5XX_ERROR_CACHE_TOPIC); | ||
| int newUnknownErrorCache = validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.UNKNOWN_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| UNKNOWN_ERROR_CACHE_TOPIC)), UNKNOWN_ERROR_CACHE_TOPIC); | ||
|
|
||
| if (port != Coerce.toInt(activePortTopic) | ||
| || cloud4xxErrorCache != newCloud4xxErrorCache | ||
| || cloud5xxErrorCache != newCloud5xxErrorCache | ||
| || unknownErrorCache != newUnknownErrorCache) { | ||
|
|
||
| cloud4xxErrorCache = newCloud4xxErrorCache; | ||
| cloud5xxErrorCache = newCloud5xxErrorCache; | ||
| unknownErrorCache = newUnknownErrorCache; | ||
|
|
||
| credentialRequestHandler.configureCacheSettings( | ||
| newCloud4xxErrorCache, newCloud5xxErrorCache, newUnknownErrorCache); | ||
|
|
||
| logger.atInfo("tes-config-change") | ||
| .kv("node", node).kv("why", why) | ||
| .log("Restarting TES server due to config change"); | ||
| requestRestart(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe you should be able to change the error cache time during runtime and without restart. I don't see why not. This would change the subscription handler logic to only request restart if the port changes. This would be useful because TES restarts cause a lot of dependent component restarts, which we want to avoid if possible. |
||
| } | ||
| } | ||
| }); | ||
| deviceConfiguration.getIotRoleAlias().subscribe((why, newv) -> { | ||
| iotRoleAlias = Coerce.toString(newv); | ||
| }); | ||
|
|
||
| this.authZHandler = authZHandler; | ||
| this.credentialRequestHandler = credentialRequestHandler; | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -95,6 +149,7 @@ protected void startup() { | |
| .log("Attempting to start server at configured port {}", port); | ||
| try { | ||
| validateConfig(); | ||
| validateAllCacheConfigs(); | ||
| server = new HttpServerImpl(port, credentialRequestHandler); | ||
| server.start(); | ||
| logger.atInfo().log("Started server at port {}", server.getServerPort()); | ||
|
|
@@ -130,6 +185,26 @@ private void validateConfig() { | |
| } | ||
| } | ||
|
|
||
| private void validateAllCacheConfigs() { | ||
| validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_4XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_4XX_ERROR_CACHE_TOPIC)), CLOUD_4XX_ERROR_CACHE_TOPIC); | ||
| validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.CLOUD_5XX_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| CLOUD_5XX_ERROR_CACHE_TOPIC)), CLOUD_5XX_ERROR_CACHE_TOPIC); | ||
| validateCacheConfig(Coerce.toInt(config.findOrDefault( | ||
| CredentialRequestHandler.UNKNOWN_ERROR_CACHE_IN_SEC, CONFIGURATION_CONFIG_KEY, | ||
| UNKNOWN_ERROR_CACHE_TOPIC)), UNKNOWN_ERROR_CACHE_TOPIC); | ||
| } | ||
|
|
||
| private int validateCacheConfig(int newCacheValue, String topic) { | ||
| if (newCacheValue < MINIMUM_ERROR_CACHE_IN_SEC) { | ||
| throw new IllegalArgumentException( | ||
| "Error cache value for " + topic + " must be at least " + MINIMUM_ERROR_CACHE_IN_SEC + " seconds"); | ||
| } | ||
| return newCacheValue; | ||
| } | ||
|
|
||
| @Override | ||
| public AwsCredentials resolveCredentials() { | ||
| return credentialRequestHandler.getAwsCredentials(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it was already like this, but expiryDuration is more appropriate than expiryTime