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