Passed
Push — master ( b091a1...a43e6f )
by Pavel
03:13
created

JsonRpcClient::invoke()   B

Complexity

Conditions 5
Paths 13

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 5.0014

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 25
cts 26
cp 0.9615
rs 8.439
c 0
b 0
f 0
cc 5
eloc 23
nc 13
nop 1
crap 5.0014
1
<?php
2
3
namespace ScayTrase\Api\JsonRpc;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Exception\GuzzleException;
7
use GuzzleHttp\Psr7\Request;
8
use Psr\Http\Message\UriInterface;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\NullLogger;
11
use ScayTrase\Api\IdGenerator\IdGeneratorInterface;
12
use ScayTrase\Api\IdGenerator\UuidGenerator;
13
use ScayTrase\Api\Rpc\Exception\RemoteCallFailedException;
14
use ScayTrase\Api\Rpc\RpcClientInterface;
15
use ScayTrase\Api\Rpc\RpcRequestInterface;
16
17
final class JsonRpcClient implements RpcClientInterface
18
{
19
    const VERSION = '2.0';
20
21
    /** @var ClientInterface */
22
    private $client;
23
    /** @var UriInterface|string */
24
    private $uri;
25
    /** @var IdGeneratorInterface */
26
    private $idGenerator;
27
    /** @var LoggerInterface */
28
    private $logger;
29
30
    /**
31
     * JsonRpcClient constructor.
32
     *
33
     * @param ClientInterface           $client
34
     * @param UriInterface|string       $endpoint
35
     * @param IdGeneratorInterface|null $idGenerator
36
     * @param LoggerInterface           $logger
37
     */
38 18
    public function __construct(
39
        ClientInterface $client,
40
        $endpoint,
41
        IdGeneratorInterface $idGenerator = null,
42
        LoggerInterface $logger = null
43
    ) {
44 18
        $this->client      = $client;
45 18
        $this->uri         = $endpoint;
46 18
        $this->idGenerator = $idGenerator ?: new UuidGenerator();
47 18
        $this->logger      = $logger ?: new NullLogger();
48 18
    }
49
50
    /** {@inheritdoc} */
51 18
    public function invoke($calls)
52
    {
53
        try {
54 18
            if (!is_array($calls)) {
55 8
                if (!($calls instanceof RpcRequestInterface)) {
56 1
                    throw new \InvalidArgumentException(
57
                        'Request should be either array or single RpcRequestInterface instance'
58 1
                    );
59
                }
60 7
                $transformedCall = $this->transformCall($calls);
61
62 7
                return new JsonRpcResponseCollection(
63 7
                    $this->client->sendAsync(
64 7
                        $this->createHttpRequest($transformedCall)
65 7
                    ),
66 7
                    [new RequestTransformation($calls, $transformedCall)]
67 7
                );
68
            }
69
70 10
            $requests     = [];
71 10
            $batchRequest = [];
72
73 10
            foreach ($calls as $key => $call) {
74 10
                $transformedCall                  = $this->transformCall($call);
75 10
                $requests[spl_object_hash($call)] = new RequestTransformation($call, $transformedCall);
76 10
                $batchRequest[]                   = $transformedCall;
77 10
            }
78
79 10
            return new JsonRpcResponseCollection(
80 10
                $this->client->sendAsync($this->createHttpRequest($batchRequest)),
81 10
                $requests,
82 10
                $this->logger
83 10
            );
84 1
        } catch (GuzzleException $exception) {
85
            throw new RemoteCallFailedException($exception->getMessage(), 0, $exception);
86
        }
87
    }
88
89
    /**
90
     * @param $requestBody
91
     *
92
     * @return Request
93
     */
94 17
    private function createHttpRequest($requestBody)
95
    {
96 17
        return new Request(
97 17
            'POST',
98 17
            $this->uri,
99
            [
100 17
                'Content-Type' => 'application/json',
101 17
                'Accept'       => 'application/json',
102 17
            ],
103 17
            json_encode($requestBody, JSON_PRETTY_PRINT)
104 17
        );
105
    }
106
107
    /**
108
     * @param RpcRequestInterface $call
109
     *
110
     * @return JsonRpcRequestInterface
111
     */
112 17
    private function transformCall(RpcRequestInterface $call)
113
    {
114 17
        if ($call instanceof JsonRpcRequestInterface) {
115 16
            return $call;
116
        }
117
118 1
        return JsonRpcRequest::fromRpcRequest($call, $this->idGenerator->getRequestIdentifier($call));
119
    }
120
}
121