Skip to content

Commit

Permalink
feat: add generic method for config resolution
Browse files Browse the repository at this point in the history
Resolve config default values that uses just the ConfigurationResolver::resolve method, from just a single method. This avoids the overhead of having layers of methods for just consuming `ConfigurationResolver::resolve`, and instead this one will be called directly.
  • Loading branch information
yenfryherrerafeliz committed Nov 26, 2024
1 parent f1ad4f5 commit 2e87233
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 163 deletions.
101 changes: 57 additions & 44 deletions src/ClientResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ class ClientResolver
/** @var array */
private $argDefinitions;

/**
* When using this option as default please make sure that, your config
* has at least one data type defined in `valid` otherwise it will be
* defaulted to `string`. Also, the default value will be the falsy value
* based on the resolved data type. For example, the default for `string`
* will be `''` and for bool will be `false`.
*
* @var string
*/
const DEFAULT_FROM_ENV_INI = [
__CLASS__,
'_resolve_from_env_ini'
];

/** @var array Map of types to a corresponding function */
private static $typeMap = [
'resource' => 'is_resource',
Expand Down Expand Up @@ -91,7 +105,7 @@ class ClientResolver
'valid' => ['bool'],
'doc' => 'Set to true to disable endpoint urls configured using `AWS_ENDPOINT_URL` and `endpoint_url` shared config option.',
'fn' => [__CLASS__, '_apply_ignore_configured_endpoint_urls'],
'default' => [__CLASS__, '_default_ignore_configured_endpoint_urls'],
'default' => self::DEFAULT_FROM_ENV_INI,
],
'endpoint' => [
'type' => 'value',
Expand All @@ -105,7 +119,7 @@ class ClientResolver
'valid' => ['string'],
'doc' => 'Region to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of available regions.',
'fn' => [__CLASS__, '_apply_region'],
'default' => [__CLASS__, '_default_region']
'default' => self::DEFAULT_FROM_ENV_INI
],
'version' => [
'type' => 'value',
Expand Down Expand Up @@ -244,7 +258,7 @@ class ClientResolver
'valid' => ['bool', 'callable'],
'doc' => 'Set to true to disable request compression for supported operations',
'fn' => [__CLASS__, '_apply_disable_request_compression'],
'default' => [__CLASS__, '_default_disable_request_compression'],
'default' => self::DEFAULT_FROM_ENV_INI,
],
'request_min_compression_size_bytes' => [
'type' => 'value',
Expand Down Expand Up @@ -327,7 +341,7 @@ class ClientResolver
'valid' => ['array', 'string'],
'doc' => 'A comma-delimited list of supported regions sent in sigv4a requests.',
'fn' => [__CLASS__, '_apply_sigv4a_signing_region_set'],
'default' => [__CLASS__, '_default_sigv4a_signing_region_set']
'default' => self::DEFAULT_FROM_ENV_INI
]
];

Expand Down Expand Up @@ -397,7 +411,15 @@ public function resolve(array $args, HandlerList $list)
|| $a['default'] instanceof \Closure
)
) {
$args[$key] = $a['default']($args);
if ($a['default'] === self::DEFAULT_FROM_ENV_INI) {
$args[$key] = $a['default'](
$key,
$a['valid'][0] ?? 'string',
$args
);
} else {
$args[$key] = $a['default']($args);
}
} else {
$args[$key] = $a['default'];
}
Expand Down Expand Up @@ -590,15 +612,6 @@ public static function _apply_disable_request_compression($value, array &$args)
$args['config']['disable_request_compression'] = $value;
}

public static function _default_disable_request_compression(array &$args) {
return ConfigurationResolver::resolve(
'disable_request_compression',
false,
'bool',
$args
);
}

public static function _apply_min_compression_size($value, array &$args) {
if (is_callable($value)) {
$value = $value();
Expand Down Expand Up @@ -1259,16 +1272,6 @@ public static function _apply_suppress_php_deprecation_warning($value, &$args)
}
}

public static function _default_ignore_configured_endpoint_urls(array &$args)
{
return ConfigurationResolver::resolve(
'ignore_configured_endpoint_urls',
false,
'bool',
$args
);
}

public static function _default_endpoint(array &$args)
{
if ($args['config']['ignore_configured_endpoint_urls']
Expand Down Expand Up @@ -1318,16 +1321,6 @@ public static function _apply_sigv4a_signing_region_set($value, array &$args)
}
}

public static function _default_sigv4a_signing_region_set(array $args)
{
return ConfigurationResolver::resolve(
'sigv4a_signing_region_set',
'',
'string',
$args
);
}

public static function _apply_region($value, array &$args)
{
if (empty($value)) {
Expand All @@ -1336,16 +1329,6 @@ public static function _apply_region($value, array &$args)
$args['region'] = $value;
}

public static function _default_region($args)
{
return ConfigurationResolver::resolve(
'region',
'',
'string',
$args
);
}

public static function _missing_region(array $args)
{
$service = $args['service'] ?? '';
Expand All @@ -1362,6 +1345,36 @@ public static function _missing_region(array $args)
throw new IAE($msg);
}

/**
* Resolves a value from env or config.
*
* @param $key
* @param $expectedType
* @param $args
*
* @return mixed|string
*/
private static function _resolve_from_env_ini(
$key,
$expectedType,
$args
) {
static $typeDefaultMap = [
'int' => 0,
'bool' => false,
'boolean' => false,
'string' => '',
'array' => []
];

return ConfigurationResolver::resolve(
$key,
$typeDefaultMap[$expectedType] ?? '',
$expectedType,
$args
);
}

/**
* Extracts client options for the endpoint provider to its own array
*
Expand Down
165 changes: 46 additions & 119 deletions tests/ClientResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1701,23 +1701,13 @@ public function testEmitsDeprecationWarning()
* Tests the flag `use_aws_shared_config_files` is applied to the method
* for resolving a default value for a config.
*
* @param $resolverDefinition
* @param $args
* @param $expected
*
* @dataProvider methodAppliesUserAwsSharedFilesProvider
*
* @return void
*/
public function testMethodAppliesUseAwsSharedFiles(
$resolverDefinition,
$args,
$expected
): void
public function testResolveFromEnvIniUseAwsSharedFiles(): void
{
// The config being tested
$configKey = array_key_first($resolverDefinition);
$configValue = $expected ?? 'foo_value';
$configKey = 'foo-config-key';
$configValue = 'foo-config-value';
// Populate config file
$tempDir = sys_get_temp_dir();
$awsDir = $tempDir . "/.aws";
Expand All @@ -1734,12 +1724,49 @@ public function testMethodAppliesUseAwsSharedFiles(
putenv(ConfigurationResolver::ENV_CONFIG_FILE . "=" . $configFile);

try {
$resolver = new ClientResolver($resolverDefinition);
$resolvedArgs = $resolver->resolve($args, new HandlerList());
if ($expected) {
$this->assertEquals($expected, $resolvedArgs[$configKey]);
} else {
$this->assertNull($resolvedArgs[$configKey]);
$resolver = new ClientResolver([
$configKey => [
'type' => 'value',
'valid' => ['string'],
'fn' => function ($value, array &$args) use ($configKey) {
if (empty($value)) {
$args[$configKey] = null;

return;
}

$args[$configKey] = $value;
},
'default' => ClientResolver::DEFAULT_FROM_ENV_INI
]
]);
$testCases = [
[
'args' => [
'use_aws_shared_config_files' => true
],
'expected' => $configValue
],
[
'args' => [
'use_aws_shared_config_files' => false
],
'expected' => null
]
];
foreach ($testCases as $case) {
$resolvedArgs = $resolver->resolve(
$case['args'],
new HandlerList()
);
if ($case['expected']) {
$this->assertEquals(
$case['expected'],
$resolvedArgs[$configKey]
);
} else {
$this->assertNull($resolvedArgs[$configKey]);
}
}
} finally {
unlink($configFile);
Expand All @@ -1755,104 +1782,4 @@ public function testMethodAppliesUseAwsSharedFiles(
}
}
}

/**
* @return array[]
*/
public function methodAppliesUserAwsSharedFilesProvider(): array
{
// We use a custom apply function to prevent validation
// errors, since every apply method may have a
// different validation logic.
$customApplyFn = function ($config) {
return static function ($value, array &$args) use ($config) {
if (empty($value)) {
$args[$config] = null;

return;
}

$args[$config] = $value;
};
};

return [
'resolve_region_from_config' => [
'resolver_definition' => [
'region' => [
'type' => 'value',
'valid' => ['string'],
'fn' => $customApplyFn(
'region'
),
'default' => [
ClientResolver::class,
'_default_region'
]
]
],
'args' => [
'use_aws_shared_config_files' => true,
],
'expected' => 'foo-region'
],
'not_resolve_region_from_config' => [
'resolver_definition' => [
'region' => [
'type' => 'value',
'valid' => ['string'],
'fn' => $customApplyFn(
'region'
),
'default' => [
ClientResolver::class,
'_default_region'
]
]
],
'args' => [
'use_aws_shared_config_files' => false,
],
'expected' => null
],
'resolve_sigv4a_signing_region_set_from_config' => [
'resolver_definition' => [
'sigv4a_signing_region_set' => [
'type' => 'value',
'valid' => ['string'],
'fn' => $customApplyFn(
'sigv4a_signing_region_set'
),
'default' => [
ClientResolver::class,
'_default_sigv4a_signing_region_set'
]
]
],
'args' => [
'use_aws_shared_config_files' => true,
],
'expected' => 'foo-region'
],
'not_resolve_sigv4a_signing_region_set_from_config' => [
'resolver_definition' => [
'sigv4a_signing_region_set' => [
'type' => 'value',
'valid' => ['string'],
'fn' => $customApplyFn(
'sigv4a_signing_region_set'
),
'default' => [
ClientResolver::class,
'_default_sigv4a_signing_region_set'
]
]
],
'args' => [
'use_aws_shared_config_files' => false,
],
'expected' => null
]
];
}
}

0 comments on commit 2e87233

Please sign in to comment.