Completed
Push — master ( 2ed404...caa721 )
by Fabian
34:04 queued 22:36
created

Dispatcher::responseIsSuccessful()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
namespace IntegerNet\CallbackProxy;
3
4
use GuzzleHttp\Client;
5
use GuzzleHttp\Exception\RequestException;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\UriInterface;
9
10
/**
11
 * Dispatches a request to multiple targets, returns first successful response (HTTP 200) or last response if none are
12
 * successful
13
 */
14
class Dispatcher
15
{
16
    /**
17
     * @var Client
18
     */
19
    private $client;
20
    /**
21
     * @var UriInterface[]
22
     */
23
    private $targets;
24
25 39
    public function __construct(Client $client, UriInterface ...$targets)
26
    {
27 39
        $this->client = $client;
28 39
        $this->targets = $targets;
29 39
    }
30
31 39
    public function dispatch(RequestInterface $request, ResponseInterface $response, string $action): ResponseInterface
32
    {
33 39
        $firstSuccessfulResponse = null;
34 39
        foreach ($this->targets as $target) {
35 39
            $response = $this->dispatchSingle($request, $target, $action);
36 39
            if ($firstSuccessfulResponse === null && $this->responseIsSuccessful($response)) {
37 39
                $firstSuccessfulResponse = $response;
38
            }
39
        }
40 39
        return $firstSuccessfulResponse ?? $response;
41
    }
42
43 39
    private function dispatchSingle(RequestInterface $request, UriInterface $target, string $action) : ResponseInterface
44
    {
45 39
        $target = $target->withPath($target->getPath() . $action);
46
        try {
47 39
            return $this->responseWithTargetHeader($this->client->send($request->withUri($target)), $target);
48 9
        } catch (RequestException $e) {
49 9
            if ($e->getResponse() instanceof ResponseInterface) {
50 9
                return $this->responseWithTargetHeader($e->getResponse(), $target);
51
            }
52
            throw $e;
53
        }
54
    }
55
56 39
    private function responseWithTargetHeader(ResponseInterface $response, UriInterface $target)
57
    {
58 39
        return $response->withHeader('X-Response-From', $target->__toString());
59
    }
60
61 39
    private function responseIsSuccessful(ResponseInterface $response): bool
62
    {
63 39
        return $response->getStatusCode() >= 200 && $response->getStatusCode() < 300;
64
    }
65
}
66