Completed
Push — master ( caa721...fceab7 )
by Fabian
14s queued 10s
created

Dispatcher::dispatchSingle()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

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