|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* HttpLoader |
|
4
|
|
|
*/ |
|
5
|
|
|
|
|
6
|
|
|
namespace Graviton\ProxyBundle\Definition\Loader; |
|
7
|
|
|
|
|
8
|
|
|
use Graviton\ProxyBundle\Definition\ApiDefinition; |
|
9
|
|
|
use Graviton\ProxyBundle\Definition\Loader\DispersalStrategy\DispersalStrategyInterface; |
|
10
|
|
|
use Doctrine\Common\Cache\CacheProvider; |
|
11
|
|
|
use Guzzle\Http\Client; |
|
12
|
|
|
use Guzzle\Http\Message\RequestInterface; |
|
13
|
|
|
use Psr\Log\LoggerInterface; |
|
14
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
15
|
|
|
use Symfony\Component\Validator\Constraints\Url; |
|
16
|
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface; |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* load a file over http and process the data |
|
20
|
|
|
* |
|
21
|
|
|
* @author List of contributors <https://github.com/libgraviton/graviton/graphs/contributors> |
|
22
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GNU Public License |
|
23
|
|
|
* @link http://swisscom.ch |
|
24
|
|
|
*/ |
|
25
|
|
|
class HttpLoader implements LoaderInterface |
|
26
|
|
|
{ |
|
27
|
|
|
/** |
|
28
|
|
|
* @var ValidatorInterface |
|
29
|
|
|
*/ |
|
30
|
|
|
private $validator; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* @var Client |
|
34
|
|
|
*/ |
|
35
|
|
|
private $client; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* @var LoggerInterface |
|
39
|
|
|
*/ |
|
40
|
|
|
private $logger; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @var DispersalStrategyInterface |
|
44
|
|
|
*/ |
|
45
|
|
|
private $strategy; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* doctrine cache |
|
49
|
|
|
* |
|
50
|
|
|
* @var CacheProvider |
|
51
|
|
|
*/ |
|
52
|
|
|
private $cache; |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* doctrine cache lifetime |
|
56
|
|
|
* |
|
57
|
|
|
* @var int |
|
58
|
|
|
*/ |
|
59
|
|
|
private $cacheLifetime; |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* @var array curl options to apply on each request |
|
63
|
|
|
*/ |
|
64
|
|
|
private $curlOptions = []; |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* @var array |
|
68
|
|
|
*/ |
|
69
|
|
|
private $options = [ |
|
70
|
|
|
'storeKey' => 'httpLoader', |
|
71
|
|
|
]; |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* constructor |
|
75
|
|
|
* |
|
76
|
|
|
* @param ValidatorInterface $validator validator |
|
77
|
|
|
* @param Client $client http client |
|
78
|
|
|
* @param LoggerInterface $logger Logger |
|
79
|
|
|
*/ |
|
80
|
8 |
|
public function __construct(ValidatorInterface $validator, Client $client, LoggerInterface $logger) |
|
81
|
|
|
{ |
|
82
|
8 |
|
$this->validator = $validator; |
|
83
|
8 |
|
$this->client = $client; |
|
84
|
8 |
|
$this->logger = $logger; |
|
85
|
8 |
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* @inheritDoc |
|
89
|
|
|
* |
|
90
|
|
|
* @param DispersalStrategyInterface $strategy dispersal strategy |
|
91
|
|
|
* |
|
92
|
|
|
* @return void |
|
93
|
|
|
*/ |
|
94
|
6 |
|
public function setDispersalStrategy(DispersalStrategyInterface $strategy) |
|
95
|
|
|
{ |
|
96
|
6 |
|
$this->strategy = $strategy; |
|
97
|
6 |
|
} |
|
98
|
|
|
|
|
99
|
|
|
/** |
|
100
|
|
|
* @inheritDoc |
|
101
|
|
|
* |
|
102
|
|
|
* @param CacheProvider $cache doctrine cache provider |
|
103
|
|
|
* @param string $cacheNamespace cache namespace |
|
104
|
|
|
* @param int $cacheLifetime cache lifetime |
|
105
|
|
|
* |
|
106
|
|
|
* @return void |
|
107
|
|
|
*/ |
|
108
|
2 |
|
public function setCache(CacheProvider $cache, $cacheNamespace, $cacheLifetime) |
|
109
|
|
|
{ |
|
110
|
2 |
|
$this->cache = $cache; |
|
111
|
2 |
|
$this->cache->setNamespace($cacheNamespace); |
|
112
|
2 |
|
$this->cacheLifetime = $cacheLifetime; |
|
113
|
2 |
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* set curl options |
|
117
|
|
|
* |
|
118
|
|
|
* @param array $curlOptions the curl options |
|
119
|
|
|
* |
|
120
|
|
|
* @return void |
|
121
|
|
|
*/ |
|
122
|
|
|
public function setCurlOptions(array $curlOptions) |
|
123
|
|
|
{ |
|
124
|
|
|
$this->curlOptions = $curlOptions; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* @inheritDoc |
|
129
|
|
|
* |
|
130
|
|
|
* @param array $options cache strategy |
|
131
|
|
|
* |
|
132
|
|
|
* @return void |
|
133
|
|
|
*/ |
|
134
|
2 |
|
public function setOptions($options) |
|
135
|
|
|
{ |
|
136
|
2 |
|
if (!empty($options['prefix'])) { |
|
137
|
2 |
|
$options['storeKey'] = $options['prefix']; |
|
138
|
2 |
|
unset($options['prefix']); |
|
139
|
1 |
|
} |
|
140
|
|
|
|
|
141
|
2 |
|
$this->options = array_merge($this->options, $options); |
|
142
|
2 |
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* check if the url is valid |
|
146
|
|
|
* |
|
147
|
|
|
* @param string $url url |
|
148
|
|
|
* |
|
149
|
|
|
* @return boolean |
|
150
|
|
|
*/ |
|
151
|
2 |
|
public function supports($url) |
|
152
|
|
|
{ |
|
153
|
2 |
|
$error = $this->validator->validate($url, [new Url()]); |
|
154
|
|
|
|
|
155
|
2 |
|
return 0 === count($error); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* Applies the specified curl option on a request |
|
160
|
|
|
* |
|
161
|
|
|
* @param RequestInterface $request request |
|
162
|
|
|
* |
|
163
|
|
|
* @return void |
|
164
|
|
|
*/ |
|
165
|
6 |
|
protected function applyCurlOptions($request) |
|
166
|
|
|
{ |
|
167
|
6 |
|
$curl = $request->getCurlOptions(); |
|
168
|
6 |
View Code Duplication |
foreach ($this->curlOptions as $option => $value) { |
|
|
|
|
|
|
169
|
|
|
$option = 'CURLOPT_'.strtoupper($option); |
|
170
|
|
|
$curl->set(constant($option), $value); |
|
171
|
3 |
|
} |
|
172
|
6 |
|
$curl->set(constant('CURLOPT_CAINFO'), __DIR__.'/../../Resources/cert/cacert.pem'); |
|
173
|
6 |
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* @inheritDoc |
|
177
|
|
|
* |
|
178
|
|
|
* @param string $input url |
|
179
|
|
|
* |
|
180
|
|
|
* @return ApiDefinition |
|
181
|
|
|
*/ |
|
182
|
6 |
|
public function load($input) |
|
183
|
|
|
{ |
|
184
|
6 |
|
$retVal = new ApiDefinition(); |
|
185
|
6 |
|
if (isset($this->strategy)) { |
|
186
|
6 |
|
$request = $this->client->get($input); |
|
187
|
6 |
|
$this->applyCurlOptions($request); |
|
188
|
6 |
|
if (isset($this->cache) && $this->cache->contains($this->options['storeKey'])) { |
|
189
|
2 |
|
$content = $this->cache->fetch($this->options['storeKey']); |
|
190
|
|
|
|
|
191
|
2 |
|
if (empty($content)) { |
|
192
|
1 |
|
$content = $this->fetchFile($request); |
|
193
|
|
|
} |
|
194
|
1 |
|
} else { |
|
195
|
|
|
//$content = $this->fetchFile($request); |
|
196
|
4 |
|
$content = file_get_contents('/Users/taafeba2/development/swisscom/graviton-api-zgkb-bap/vendor/graviton/graviton/app/cache/swagger.json'); |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
// store current host (name or ip) serving the API. This MUST be the host only and does not include the |
|
200
|
|
|
// scheme nor sub-paths. It MAY include a port. If the host is not included, the host serving the |
|
201
|
|
|
// documentation is to be used (including the port) |
|
202
|
6 |
|
$fallbackHost = array(); |
|
203
|
6 |
|
$fallbackHost['host'] = sprintf( |
|
204
|
6 |
|
'%s://%s:%d', |
|
205
|
6 |
|
$request->getScheme(), |
|
206
|
6 |
|
$request->getHost(), |
|
207
|
6 |
|
$request->getPort() |
|
208
|
3 |
|
); |
|
209
|
6 |
|
if ($this->strategy->supports($content)) { |
|
210
|
4 |
|
$retVal = $this->strategy->process($content, $fallbackHost); |
|
211
|
2 |
|
} |
|
212
|
3 |
|
} |
|
213
|
|
|
|
|
214
|
6 |
|
return $retVal; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
/** |
|
218
|
|
|
* fetch file from remote destination |
|
219
|
|
|
* |
|
220
|
|
|
* @param RequestInterface $request request |
|
221
|
|
|
* |
|
222
|
|
|
* @return string |
|
223
|
|
|
*/ |
|
224
|
|
|
private function fetchFile(RequestInterface $request) |
|
225
|
|
|
{ |
|
226
|
|
|
$content = "{}"; |
|
227
|
|
|
try { |
|
228
|
|
|
$response = $request->send(); |
|
229
|
|
|
$content = $response->getBody(true); |
|
230
|
|
|
if (isset($this->cache)) { |
|
231
|
|
|
$this->cache->save($this->options['storeKey'], $content, $this->cacheLifetime); |
|
232
|
|
|
} |
|
233
|
|
|
} catch (\Guzzle\Http\Exception\HttpException $e) { |
|
234
|
|
|
$this->logger->info( |
|
235
|
|
|
"Unable to fetch File!", |
|
236
|
|
|
[ |
|
237
|
|
|
"message" => $e->getMessage(), |
|
238
|
|
|
"url" => $request->getUrl(), |
|
239
|
|
|
"code" => (!empty($request->getResponse())? $request->getResponse()->getStatusCode() : 500) |
|
240
|
|
|
] |
|
241
|
|
|
); |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
return $content; |
|
245
|
|
|
} |
|
246
|
|
|
} |
|
247
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.