Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws\Api;
3
 
4
use Aws\Exception\UnresolvedApiException;
5
 
6
/**
7
 * API providers.
8
 *
9
 * An API provider is a function that accepts a type, service, and version and
10
 * returns an array of API data on success or NULL if no API data can be created
11
 * for the provided arguments.
12
 *
13
 * You can wrap your calls to an API provider with the
14
 * {@see ApiProvider::resolve} method to ensure that API data is created. If the
15
 * API data is not created, then the resolve() method will throw a
16
 * {@see Aws\Exception\UnresolvedApiException}.
17
 *
18
 *     use Aws\Api\ApiProvider;
19
 *     $provider = ApiProvider::defaultProvider();
20
 *     // Returns an array or NULL.
21
 *     $data = $provider('api', 's3', '2006-03-01');
22
 *     // Returns an array or throws.
23
 *     $data = ApiProvider::resolve($provider, 'api', 'elasticfood', '2020-01-01');
24
 *
25
 * You can compose multiple providers into a single provider using
26
 * {@see Aws\or_chain}. This method accepts providers as arguments and
27
 * returns a new function that will invoke each provider until a non-null value
28
 * is returned.
29
 *
30
 *     $a = ApiProvider::filesystem(sys_get_temp_dir() . '/aws-beta-models');
31
 *     $b = ApiProvider::manifest();
32
 *
33
 *     $c = \Aws\or_chain($a, $b);
34
 *     $data = $c('api', 'betaservice', '2015-08-08'); // $a handles this.
35
 *     $data = $c('api', 's3', '2006-03-01');          // $b handles this.
36
 *     $data = $c('api', 'invalid', '2014-12-15');     // Neither handles this.
37
 */
38
class ApiProvider
39
{
40
    /** @var array A map of public API type names to their file suffix. */
41
    private static $typeMap = [
42
        'api'       => 'api-2',
43
        'paginator' => 'paginators-1',
44
        'waiter'    => 'waiters-2',
45
        'docs'      => 'docs-2',
46
    ];
47
 
48
    /** @var array API manifest */
49
    private $manifest;
50
 
51
    /** @var string The directory containing service models. */
52
    private $modelsDir;
53
 
54
    /**
55
     * Resolves an API provider and ensures a non-null return value.
56
     *
57
     * @param callable $provider Provider function to invoke.
58
     * @param string   $type     Type of data ('api', 'waiter', 'paginator').
59
     * @param string   $service  Service name.
60
     * @param string   $version  API version.
61
     *
62
     * @return array
63
     * @throws UnresolvedApiException
64
     */
65
    public static function resolve(callable $provider, $type, $service, $version)
66
    {
67
        // Execute the provider and return the result, if there is one.
68
        $result = $provider($type, $service, $version);
69
        if (is_array($result)) {
70
            if (!isset($result['metadata']['serviceIdentifier'])) {
71
                $result['metadata']['serviceIdentifier'] = $service;
72
            }
73
            return $result;
74
        }
75
 
76
        // Throw an exception with a message depending on the inputs.
77
        if (!isset(self::$typeMap[$type])) {
78
            $msg = "The type must be one of: " . implode(', ', self::$typeMap);
79
        } elseif ($service) {
80
            $msg = "The {$service} service does not have version: {$version}.";
81
        } else {
82
            $msg = "You must specify a service name to retrieve its API data.";
83
        }
84
 
85
        throw new UnresolvedApiException($msg);
86
    }
87
 
88
    /**
89
     * Default SDK API provider.
90
     *
91
     * This provider loads pre-built manifest data from the `data` directory.
92
     *
93
     * @return self
94
     */
95
    public static function defaultProvider()
96
    {
97
        return new self(__DIR__ . '/../data', \Aws\manifest());
98
    }
99
 
100
    /**
101
     * Loads API data after resolving the version to the latest, compatible,
102
     * available version based on the provided manifest data.
103
     *
104
     * Manifest data is essentially an associative array of service names to
105
     * associative arrays of API version aliases.
106
     *
107
     * [
108
     *   ...
109
     *   'ec2' => [
110
     *     'latest'     => '2014-10-01',
111
     *     '2014-10-01' => '2014-10-01',
112
     *     '2014-09-01' => '2014-10-01',
113
     *     '2014-06-15' => '2014-10-01',
114
     *     ...
115
     *   ],
116
     *   'ecs' => [...],
117
     *   'elasticache' => [...],
118
     *   ...
119
     * ]
120
     *
121
     * @param string $dir      Directory containing service models.
122
     * @param array  $manifest The API version manifest data.
123
     *
124
     * @return self
125
     */
126
    public static function manifest($dir, array $manifest)
127
    {
128
        return new self($dir, $manifest);
129
    }
130
 
131
    /**
132
     * Loads API data from the specified directory.
133
     *
134
     * If "latest" is specified as the version, this provider must glob the
135
     * directory to find which is the latest available version.
136
     *
137
     * @param string $dir Directory containing service models.
138
     *
139
     * @return self
140
     * @throws \InvalidArgumentException if the provided `$dir` is invalid.
141
     */
142
    public static function filesystem($dir)
143
    {
144
        return new self($dir);
145
    }
146
 
147
    /**
148
     * Retrieves a list of valid versions for the specified service.
149
     *
150
     * @param string $service Service name
151
     *
152
     * @return array
153
     */
154
    public function getVersions($service)
155
    {
156
        if (!isset($this->manifest)) {
157
            $this->buildVersionsList($service);
158
        }
159
 
160
        if (!isset($this->manifest[$service]['versions'])) {
161
            return [];
162
        }
163
 
164
        return array_values(array_unique($this->manifest[$service]['versions']));
165
    }
166
 
167
    /**
168
     * Execute the provider.
169
     *
170
     * @param string $type    Type of data ('api', 'waiter', 'paginator').
171
     * @param string $service Service name.
172
     * @param string $version API version.
173
     *
174
     * @return array|null
175
     */
176
    public function __invoke($type, $service, $version)
177
    {
178
        // Resolve the type or return null.
179
        if (isset(self::$typeMap[$type])) {
180
            $type = self::$typeMap[$type];
181
        } else {
182
            return null;
183
        }
184
 
185
        // Resolve the version or return null.
186
        if (!isset($this->manifest)) {
187
            $this->buildVersionsList($service);
188
        }
189
 
190
        if (!isset($this->manifest[$service]['versions'][$version])) {
191
            return null;
192
        }
193
 
194
        $version = $this->manifest[$service]['versions'][$version];
195
        $path = "{$this->modelsDir}/{$service}/{$version}/{$type}.json";
196
 
197
        try {
198
            return \Aws\load_compiled_json($path);
199
        } catch (\InvalidArgumentException $e) {
200
            return null;
201
        }
202
    }
203
 
204
    /**
205
     * @param string $modelsDir Directory containing service models.
206
     * @param array  $manifest  The API version manifest data.
207
     */
208
    private function __construct($modelsDir, array $manifest = null)
209
    {
210
        $this->manifest = $manifest;
211
        $this->modelsDir = rtrim($modelsDir, '/');
212
        if (!is_dir($this->modelsDir)) {
213
            throw new \InvalidArgumentException(
214
                "The specified models directory, {$modelsDir}, was not found."
215
            );
216
        }
217
    }
218
 
219
    /**
220
     * Build the versions list for the specified service by globbing the dir.
221
     */
222
    private function buildVersionsList($service)
223
    {
224
        $dir = "{$this->modelsDir}/{$service}/";
225
 
226
        if (!is_dir($dir)) {
227
            return;
228
        }
229
 
230
        // Get versions, remove . and .., and sort in descending order.
231
        $results = array_diff(scandir($dir, SCANDIR_SORT_DESCENDING), ['..', '.']);
232
 
233
        if (!$results) {
234
            $this->manifest[$service] = ['versions' => []];
235
        } else {
236
            $this->manifest[$service] = [
237
                'versions' => [
238
                    'latest' => $results[0]
239
                ]
240
            ];
241
            $this->manifest[$service]['versions'] += array_combine($results, $results);
242
        }
243
    }
244
}