vendor/aws/aws-sdk-php/src/Retry/ConfigurationProvider.php line 158

Open in your IDE?
  1. <?php
  2. namespace Aws\Retry;
  3. use Aws\AbstractConfigurationProvider;
  4. use Aws\CacheInterface;
  5. use Aws\ConfigurationProviderInterface;
  6. use Aws\Retry\Exception\ConfigurationException;
  7. use GuzzleHttp\Promise;
  8. use GuzzleHttp\Promise\PromiseInterface;
  9. /**
  10.  * A configuration provider is a function that returns a promise that is
  11.  * fulfilled with a {@see \Aws\Retry\ConfigurationInterface}
  12.  * or rejected with an {@see \Aws\Retry\Exception\ConfigurationException}.
  13.  *
  14.  * <code>
  15.  * use Aws\Sts\RegionalEndpoints\ConfigurationProvider;
  16.  * $provider = ConfigurationProvider::defaultProvider();
  17.  * // Returns a ConfigurationInterface or throws.
  18.  * $config = $provider()->wait();
  19.  * </code>
  20.  *
  21.  * Configuration providers can be composed to create configuration using
  22.  * conditional logic that can create different configurations in different
  23.  * environments. You can compose multiple providers into a single provider using
  24.  * {@see \Aws\Retry\ConfigurationProvider::chain}. This function
  25.  * accepts providers as variadic arguments and returns a new function that will
  26.  * invoke each provider until a successful configuration is returned.
  27.  *
  28.  * <code>
  29.  * // First try an INI file at this location.
  30.  * $a = ConfigurationProvider::ini(null, '/path/to/file.ini');
  31.  * // Then try an INI file at this location.
  32.  * $b = ConfigurationProvider::ini(null, '/path/to/other-file.ini');
  33.  * // Then try loading from environment variables.
  34.  * $c = ConfigurationProvider::env();
  35.  * // Combine the three providers together.
  36.  * $composed = ConfigurationProvider::chain($a, $b, $c);
  37.  * // Returns a promise that is fulfilled with a configuration or throws.
  38.  * $promise = $composed();
  39.  * // Wait on the configuration to resolve.
  40.  * $config = $promise->wait();
  41.  * </code>
  42.  */
  43. class ConfigurationProvider extends AbstractConfigurationProvider
  44.     implements ConfigurationProviderInterface
  45. {
  46.     const DEFAULT_MAX_ATTEMPTS 3;
  47.     const DEFAULT_MODE 'legacy';
  48.     const ENV_MAX_ATTEMPTS 'AWS_MAX_ATTEMPTS';
  49.     const ENV_MODE 'AWS_RETRY_MODE';
  50.     const ENV_PROFILE 'AWS_PROFILE';
  51.     const INI_MAX_ATTEMPTS 'max_attempts';
  52.     const INI_MODE 'retry_mode';
  53.     public static $cacheKey 'aws_retries_config';
  54.     protected static $interfaceClass ConfigurationInterface::class;
  55.     protected static $exceptionClass ConfigurationException::class;
  56.     /**
  57.      * Create a default config provider that first checks for environment
  58.      * variables, then checks for a specified profile in the environment-defined
  59.      * config file location (env variable is 'AWS_CONFIG_FILE', file location
  60.      * defaults to ~/.aws/config), then checks for the "default" profile in the
  61.      * environment-defined config file location, and failing those uses a default
  62.      * fallback set of configuration options.
  63.      *
  64.      * This provider is automatically wrapped in a memoize function that caches
  65.      * previously provided config options.
  66.      *
  67.      * @param array $config
  68.      *
  69.      * @return callable
  70.      */
  71.     public static function defaultProvider(array $config = [])
  72.     {
  73.         $configProviders = [self::env()];
  74.         if (
  75.             !isset($config['use_aws_shared_config_files'])
  76.             || $config['use_aws_shared_config_files'] != false
  77.         ) {
  78.             $configProviders[] = self::ini();
  79.         }
  80.         $configProviders[] = self::fallback();
  81.         $memo self::memoize(
  82.             call_user_func_array([ConfigurationProvider::class, 'chain'], $configProviders)
  83.         );
  84.         if (isset($config['retries'])
  85.             && $config['retries'] instanceof CacheInterface
  86.         ) {
  87.             return self::cache($memo$config['retries'], self::$cacheKey);
  88.         }
  89.         return $memo;
  90.     }
  91.     /**
  92.      * Provider that creates config from environment variables.
  93.      *
  94.      * @return callable
  95.      */
  96.     public static function env()
  97.     {
  98.         return function () {
  99.             // Use config from environment variables, if available
  100.             $mode getenv(self::ENV_MODE);
  101.             $maxAttempts getenv(self::ENV_MAX_ATTEMPTS)
  102.                 ? getenv(self::ENV_MAX_ATTEMPTS)
  103.                 : self::DEFAULT_MAX_ATTEMPTS;
  104.             if (!empty($mode)) {
  105.                 return Promise\Create::promiseFor(
  106.                     new Configuration($mode$maxAttempts)
  107.                 );
  108.             }
  109.             return self::reject('Could not find environment variable config'
  110.                 ' in ' self::ENV_MODE);
  111.         };
  112.     }
  113.     /**
  114.      * Fallback config options when other sources are not set.
  115.      *
  116.      * @return callable
  117.      */
  118.     public static function fallback()
  119.     {
  120.         return function () {
  121.             return Promise\Create::promiseFor(
  122.                 new Configuration(self::DEFAULT_MODEself::DEFAULT_MAX_ATTEMPTS)
  123.             );
  124.         };
  125.     }
  126.     /**
  127.      * Config provider that creates config using a config file whose location
  128.      * is specified by an environment variable 'AWS_CONFIG_FILE', defaulting to
  129.      * ~/.aws/config if not specified
  130.      *
  131.      * @param string|null $profile  Profile to use. If not specified will use
  132.      *                              the "default" profile.
  133.      * @param string|null $filename If provided, uses a custom filename rather
  134.      *                              than looking in the default directory.
  135.      *
  136.      * @return callable
  137.      */
  138.     public static function ini(
  139.         $profile null,
  140.         $filename null
  141.     ) {
  142.         $filename $filename ?: (self::getDefaultConfigFilename());
  143.         $profile $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
  144.         return function () use ($profile$filename) {
  145.             if (!@is_readable($filename)) {
  146.                 return self::reject("Cannot read configuration from $filename");
  147.             }
  148.             $data = \Aws\parse_ini_file($filenametrue);
  149.             if ($data === false) {
  150.                 return self::reject("Invalid config file: $filename");
  151.             }
  152.             if (!isset($data[$profile])) {
  153.                 return self::reject("'$profile' not found in config file");
  154.             }
  155.             if (!isset($data[$profile][self::INI_MODE])) {
  156.                 return self::reject("Required retry config values
  157.                     not present in INI profile '{$profile}' ({$filename})");
  158.             }
  159.             $maxAttempts = isset($data[$profile][self::INI_MAX_ATTEMPTS])
  160.                 ? $data[$profile][self::INI_MAX_ATTEMPTS]
  161.                 : self::DEFAULT_MAX_ATTEMPTS;
  162.             return Promise\Create::promiseFor(
  163.                 new Configuration(
  164.                     $data[$profile][self::INI_MODE],
  165.                     $maxAttempts
  166.                 )
  167.             );
  168.         };
  169.     }
  170.     /**
  171.      * Unwraps a configuration object in whatever valid form it is in,
  172.      * always returning a ConfigurationInterface object.
  173.      *
  174.      * @param  mixed $config
  175.      * @return ConfigurationInterface
  176.      * @throws \InvalidArgumentException
  177.      */
  178.     public static function unwrap($config)
  179.     {
  180.         if (is_callable($config)) {
  181.             $config $config();
  182.         }
  183.         if ($config instanceof PromiseInterface) {
  184.             $config $config->wait();
  185.         }
  186.         if ($config instanceof ConfigurationInterface) {
  187.             return $config;
  188.         }
  189.         // An integer value for this config indicates the legacy 'retries'
  190.         // config option, which is incremented to translate to max attempts
  191.         if (is_int($config)) {
  192.             return new Configuration('legacy'$config 1);
  193.         }
  194.         if (is_array($config) && isset($config['mode'])) {
  195.             $maxAttempts = isset($config['max_attempts'])
  196.                 ? $config['max_attempts']
  197.                 : self::DEFAULT_MAX_ATTEMPTS;
  198.             return new Configuration($config['mode'], $maxAttempts);
  199.         }
  200.         throw new \InvalidArgumentException('Not a valid retry configuration'
  201.             ' argument.');
  202.     }
  203. }