Passed
Pull Request — master (#10)
by Leonardo
01:41
created

GuzzleMiddleware   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 13
eloc 25
c 1
b 0
f 1
dl 0
loc 65
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A __invoke() 0 17 2
A isStatusCodeSuccess() 0 3 2
A isStatusCodeRangeValid() 0 3 2
A executeCircuitBreakerOnResponse() 0 19 4
A isStatusCodeRedirect() 0 3 2
1
<?php declare(strict_types=1);
2
3
namespace LeoCarmo\CircuitBreaker;
4
5
use Psr\Http\Message\RequestInterface;
6
use Psr\Http\Message\ResponseInterface;
7
8
class GuzzleMiddleware
9
{
10
    protected CircuitBreaker $circuitBreaker;
11
12
    public function __construct(CircuitBreaker $circuitBreaker)
13
    {
14
        $this->circuitBreaker = $circuitBreaker;
15
    }
16
17
    public function __invoke(callable $handler): \Closure
18
    {
19
        return function (RequestInterface $request, array $options) use ($handler) {
20
21
            if (! $this->circuitBreaker->isAvailable()) {
22
                throw new CircuitBreakerException(
23
                    sprintf('"%s" is not available', $this->circuitBreaker->getService())
24
                );
25
            }
26
27
            $promise = $handler($request, $options);
28
29
            return $promise->then(
30
                function (ResponseInterface $response) {
31
                    $this->executeCircuitBreakerOnResponse($response);
32
33
                    return $response;
34
                }
35
            );
36
        };
37
    }
38
39
    protected function executeCircuitBreakerOnResponse(ResponseInterface $response): void
40
    {
41
        $statusCode = $response->getStatusCode();
42
43
        if (! $this->isStatusCodeRangeValid($statusCode)) {
44
            $this->circuitBreaker->failure();
45
            return;
46
        }
47
48
        if ($this->isStatusCodeRedirect($statusCode)) {
49
            return;
50
        }
51
52
        if ($this->isStatusCodeSuccess($statusCode)) {
53
            $this->circuitBreaker->success();
54
            return;
55
        }
56
57
        $this->circuitBreaker->failure();
58
    }
59
60
    protected function isStatusCodeRangeValid(int $statusCode): bool
61
    {
62
        return ($statusCode >= 100 && $statusCode < 600);
63
    }
64
65
    protected function isStatusCodeRedirect(int $statusCode): bool
66
    {
67
        return ($statusCode >= 300 && $statusCode < 400);
68
    }
69
70
    protected function isStatusCodeSuccess(int $statusCode): bool
71
    {
72
        return ($statusCode >= 200 && $statusCode < 300);
73
    }
74
}