Completed
Push — develop ( dc031d...86c271 )
by
unknown
14s
created

HttpLoader::load()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7.0071

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 36
ccs 18
cts 19
cp 0.9474
rs 6.7272
cc 7
eloc 19
nc 10
nop 1
crap 7.0071
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 GuzzleHttp\Exception\RequestException;
12
use GuzzleHttp\Psr7\Request;
13
use GuzzleHttp\Client;
14
use Psr\Http\Message\RequestInterface;
15
use Psr\Log\LoggerInterface;
16
use Symfony\Component\Validator\Constraints\Url;
17
use Symfony\Component\Validator\Validator\ValidatorInterface;
18
19
/**
20
 * load a file over http and process the data
21
 *
22
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
23
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
24
 * @link     http://swisscom.ch
25
 */
26
class HttpLoader implements LoaderInterface
27
{
28
    /**
29
     * @var ValidatorInterface
30
     */
31
    private $validator;
32
33
    /**
34
     * @var Client
35
     */
36
    private $client;
37
38
    /**
39
     * @var LoggerInterface
40
     */
41
    private $logger;
42
43
    /**
44
     * @var DispersalStrategyInterface
45
     */
46
    private $strategy;
47
48
    /**
49
     * doctrine cache
50
     *
51
     * @var CacheProvider
52
     */
53
    private $cache;
54
55
    /**
56
     * doctrine cache lifetime
57
     *
58
     * @var int
59
     */
60
    private $cacheLifetime;
61
62
    /**
63
     * @var array
64
     */
65
    private $options = [
66
        'storeKey' => 'httpLoader',
67
    ];
68
69
    /**
70
     * constructor
71
     *
72
     * @param ValidatorInterface $validator validator
73
     * @param Client             $client    http client
74
     * @param LoggerInterface    $logger    Logger
75
     */
76 8
    public function __construct(ValidatorInterface $validator, Client $client, LoggerInterface $logger)
77
    {
78 8
        $this->validator = $validator;
79 8
        $this->client = $client;
80 8
        $this->logger = $logger;
81 8
    }
82
83
    /**
84
     * @inheritDoc
85
     *
86
     * @param DispersalStrategyInterface $strategy dispersal strategy
87
     *
88
     * @return void
89
     */
90 6
    public function setDispersalStrategy(DispersalStrategyInterface $strategy)
91
    {
92 6
        $this->strategy = $strategy;
93 6
    }
94
95
    /**
96
     * @inheritDoc
97
     *
98
     * @param CacheProvider $cache          doctrine cache provider
99
     * @param string        $cacheNamespace cache namespace
100
     * @param int           $cacheLifetime  cache lifetime
101
     *
102
     * @return void
103
     */
104 2
    public function setCache(CacheProvider $cache, $cacheNamespace, $cacheLifetime)
105
    {
106 2
        $this->cache = $cache;
107 2
        $this->cache->setNamespace($cacheNamespace);
108 2
        $this->cacheLifetime = $cacheLifetime;
109 2
    }
110
111
    /**
112
     * @inheritDoc
113
     *
114
     * @param array $options cache strategy
115
     *
116
     * @return void
117
     */
118 2
    public function setOptions($options)
119
    {
120 2
        if (!empty($options['prefix'])) {
121 2
            $options['storeKey'] = $options['prefix'];
122 2
            unset($options['prefix']);
123
        }
124
125 2
        $this->options = array_merge($this->options, $options);
126 2
    }
127
128
    /**
129
     * check if the url is valid
130
     *
131
     * @param string $url url
132
     *
133
     * @return boolean
134
     */
135 2
    public function supports($url)
136
    {
137 2
        $error = $this->validator->validate($url, [new Url()]);
138
139 2
        return 0 === count($error);
140
    }
141
142
    /**
143
     * @inheritDoc
144
     *
145
     * @param string $input url
146
     *
147
     * @return ApiDefinition
148
     */
149 6
    public function load($input)
150
    {
151 6
        $retVal = new ApiDefinition();
152 6
        if (is_null($input)) {
153
            // if no thirdparty defined; abort now..
154
            return $retVal;
155
        }
156
157 6
        if (isset($this->strategy)) {
158 6
            if (isset($this->cache) && $this->cache->contains($this->options['storeKey'])) {
159 2
                $content = $this->cache->fetch($this->options['storeKey']);
160
            }
161
162 6
            $request = new Request('GET', $input);
163 6
            if (empty($content)) {
164 4
                $content = $this->fetchFile($request);
165
            }
166
167
            // store current host (name or ip) serving the API. This MUST be the host only and does not include the
168
            // scheme nor sub-paths. It MAY include a port. If the host is not included, the host serving the
169
            // documentation is to be used (including the port)
170 6
            $fallbackHost = array();
171 6
            $fallbackHost['host'] = sprintf(
172 6
                '%s://%s:%d',
173 6
                $request->getUri()->getScheme(),
174 6
                $request->getUri()->getHost(),
175 6
                $request->getUri()->getPort()
176
            );
177
178 6
            if ($this->strategy->supports($content)) {
179 4
                $retVal = $this->strategy->process($content, $fallbackHost);
180
            }
181
        }
182
183 6
        return $retVal;
184
    }
185
186
    /**
187
     * fetch file from remote destination
188
     *
189
     * @param RequestInterface $request request
190
     *
191
     * @return string
192
     */
193 4
    private function fetchFile(RequestInterface $request)
194
    {
195 4
        $content = "{}";
196
        try {
197 4
            $response = $this->client->send($request);
198 4
            $content = (string) $response->getBody();
199 4
            if (isset($this->cache)) {
200 4
                $this->cache->save($this->options['storeKey'], $content, $this->cacheLifetime);
201
            }
202
        } catch (RequestException $e) {
203
            $this->logger->info(
204
                "Unable to fetch File!",
205
                [
206
                    "message" => $e->getMessage(),
207
                    "url" => $request->getRequestTarget(),
208
                    "code" => (!empty($e->getResponse())? $e->getResponse()->getStatusCode() : 500)
209
                ]
210
            );
211
        }
212
213 4
        return $content;
214
    }
215
}
216