Completed
Push — feature/EVO-8289_proxy_bundle_... ( 5c5976 )
by Bastian
11:46
created

HttpLoader::setDispersalStrategy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
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) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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