Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws;
3
 
4
use Aws\Endpoint\PartitionEndpointProvider;
5
use Aws\Endpoint\PartitionInterface;
6
use Aws\EndpointV2\EndpointProviderV2;
7
use Aws\EndpointV2\EndpointDefinitionProvider;
8
 
9
class MultiRegionClient implements AwsClientInterface
10
{
11
    use AwsClientTrait;
12
 
13
    /** @var AwsClientInterface[] A pool of clients keyed by region. */
14
    private $clientPool = [];
15
    /** @var callable */
16
    private $factory;
17
    /** @var PartitionInterface */
18
    private $partition;
19
    /** @var array */
20
    private $args;
21
    /** @var array */
22
    private $config;
23
    /** @var HandlerList */
24
    private $handlerList;
25
    /** @var array */
26
    private $aliases;
27
    /** @var callable */
28
    private $customHandler;
29
 
30
    public static function getArguments()
31
    {
32
        $args = array_intersect_key(
33
            ClientResolver::getDefaultArguments(),
34
            ['service' => true, 'region' => true]
35
        );
36
        $args['region']['required'] = false;
1441 ariadna 37
        unset($args['region']['fn']);
38
        unset($args['region']['default']);
1 efrain 39
 
40
        return $args + [
1441 ariadna 41
                'client_factory' => [
42
                    'type' => 'config',
43
                    'valid' => ['callable'],
44
                    'doc' => 'A callable that takes an array of client'
45
                        . ' configuration arguments and returns a regionalized'
46
                        . ' client.',
47
                    'required' => true,
48
                    'internal' => true,
49
                    'default' => function (array $args) {
50
                        $namespace = manifest($args['service'])['namespace'];
51
                        $klass = "Aws\\{$namespace}\\{$namespace}Client";
52
                        $region = isset($args['region']) ? $args['region'] : null;
1 efrain 53
 
1441 ariadna 54
                        return function (array $args) use ($klass, $region) {
55
                            if ($region && empty($args['region'])) {
56
                                $args['region'] = $region;
57
                            }
58
 
59
                            return new $klass($args);
60
                        };
61
                    },
62
                ],
63
                'partition' => [
64
                    'type'    => 'config',
65
                    'valid'   => ['string', PartitionInterface::class],
66
                    'doc'     => 'AWS partition to connect to. Valid partitions'
67
                        . ' include "aws," "aws-cn," and "aws-us-gov." Used to'
68
                        . ' restrict the scope of the mapRegions method.',
69
                    'default' => function (array $args) {
70
                        $region = isset($args['region']) ? $args['region'] : '';
71
                        return PartitionEndpointProvider::defaultProvider()
72
                            ->getPartition($region, $args['service']);
73
                    },
74
                    'fn'      => function ($value, array &$args) {
75
                        if (is_string($value)) {
76
                            $value = PartitionEndpointProvider::defaultProvider()
77
                                ->getPartitionByName($value);
1 efrain 78
                        }
79
 
1441 ariadna 80
                        if (!$value instanceof PartitionInterface) {
81
                            throw new \InvalidArgumentException('No valid partition'
82
                                . ' was provided. Provide a concrete partition or'
83
                                . ' the name of a partition (e.g., "aws," "aws-cn,"'
84
                                . ' or "aws-us-gov").'
85
                            );
86
                        }
87
                        $ruleset = EndpointDefinitionProvider::getEndpointRuleset(
88
                            $args['service'],
89
                            isset($args['version']) ? $args['version'] : 'latest'
1 efrain 90
                        );
1441 ariadna 91
                        $partitions = EndpointDefinitionProvider::getPartitions();
92
                        $args['endpoint_provider'] = new EndpointProviderV2($ruleset, $partitions);
1 efrain 93
                    }
1441 ariadna 94
                ],
95
            ];
1 efrain 96
    }
97
 
98
    /**
99
     * The multi-region client constructor accepts the following options:
100
     *
101
     * - client_factory: (callable) An optional callable that takes an array of
102
     *   client configuration arguments and returns a regionalized client.
103
     * - partition: (Aws\Endpoint\Partition|string) AWS partition to connect to.
104
     *   Valid partitions include "aws," "aws-cn," and "aws-us-gov." Used to
105
     *   restrict the scope of the mapRegions method.
106
     * - region: (string) Region to connect to when no override is provided.
107
     *   Used to create the default client factory and determine the appropriate
108
     *   AWS partition when present.
109
     *
110
     * @param array $args Client configuration arguments.
111
     */
112
    public function __construct(array $args = [])
113
    {
114
        if (!isset($args['service'])) {
115
            $args['service'] = $this->parseClass();
116
        }
117
 
118
        $this->handlerList = new HandlerList(function (
119
            CommandInterface $command
120
        ) {
121
            list($region, $args) = $this->getRegionFromArgs($command->toArray());
122
            $command = $this->getClientFromPool($region)
123
                ->getCommand($command->getName(), $args);
124
 
125
            if ($this->isUseCustomHandler()) {
126
                $command->getHandlerList()->setHandler($this->customHandler);
127
            }
128
 
129
            return $this->executeAsync($command);
130
        });
131
 
132
        $argDefinitions = static::getArguments();
133
        $resolver = new ClientResolver($argDefinitions);
134
        $args = $resolver->resolve($args, $this->handlerList);
135
        $this->config = $args['config'];
136
        $this->factory = $args['client_factory'];
137
        $this->partition = $args['partition'];
138
        $this->args = array_diff_key($args, $args['config']);
139
    }
140
 
141
    /**
142
     * Get the region to which the client is configured to send requests by
143
     * default.
144
     *
145
     * @return string
146
     */
147
    public function getRegion()
148
    {
149
        return $this->getClientFromPool()->getRegion();
150
    }
151
 
152
    /**
153
     * Create a command for an operation name.
154
     *
155
     * Special keys may be set on the command to control how it behaves,
156
     * including:
157
     *
158
     * - @http: Associative array of transfer specific options to apply to the
159
     *   request that is serialized for this command. Available keys include
160
     *   "proxy", "verify", "timeout", "connect_timeout", "debug", "delay", and
161
     *   "headers".
162
     * - @region: The region to which the command should be sent.
163
     *
164
     * @param string $name Name of the operation to use in the command
165
     * @param array  $args Arguments to pass to the command
166
     *
167
     * @return CommandInterface
168
     * @throws \InvalidArgumentException if no command can be found by name
169
     */
170
    public function getCommand($name, array $args = [])
171
    {
172
        return new Command($name, $args, clone $this->getHandlerList());
173
    }
174
 
175
    public function getConfig($option = null)
176
    {
177
        if (null === $option) {
178
            return $this->config;
179
        }
180
 
181
        if (isset($this->config[$option])) {
182
            return $this->config[$option];
183
        }
184
 
185
        return $this->getClientFromPool()->getConfig($option);
186
    }
187
 
188
    public function getCredentials()
189
    {
190
        return $this->getClientFromPool()->getCredentials();
191
    }
192
 
193
    public function getHandlerList()
194
    {
195
        return $this->handlerList;
196
    }
197
 
198
    public function getApi()
199
    {
200
        return $this->getClientFromPool()->getApi();
201
    }
202
 
203
    public function getEndpoint()
204
    {
205
        return $this->getClientFromPool()->getEndpoint();
206
    }
207
 
208
    public function useCustomHandler(callable $handler)
209
    {
210
        $this->customHandler = $handler;
211
    }
212
 
213
    private function isUseCustomHandler()
214
    {
215
        return isset($this->customHandler);
216
    }
217
 
218
    /**
219
     * @param string $region    Omit this argument or pass in an empty string to
220
     *                          allow the configured client factory to apply the
221
     *                          region.
222
     *
223
     * @return AwsClientInterface
224
     */
225
    protected function getClientFromPool($region = '')
226
    {
227
        if (empty($this->clientPool[$region])) {
228
            $factory = $this->factory;
229
            $this->clientPool[$region] = $factory(
230
                array_replace($this->args, array_filter(['region' => $region]))
231
            );
232
        }
233
 
234
        return $this->clientPool[$region];
235
    }
236
 
237
    /**
238
     * Parse the class name and return the "service" name of the client.
239
     *
240
     * @return string
241
     */
242
    private function parseClass()
243
    {
244
        $klass = get_class($this);
245
 
246
        if ($klass === __CLASS__) {
247
            return '';
248
        }
249
 
250
        return strtolower(substr($klass, strrpos($klass, '\\') + 1, -17));
251
    }
252
 
253
    private function getRegionFromArgs(array $args)
254
    {
255
        $region = isset($args['@region'])
256
            ? $args['@region']
257
            : $this->getRegion();
258
        unset($args['@region']);
259
 
260
        return [$region, $args];
261
    }
262
}