Proyectos de Subversion Moodle

Rev

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