Code

< 40 %
40-60 %
> 60 %
1
<?php
2
3
namespace Bankiru\Api\BrowserKit;
4
5
use ScayTrase\Api\IdGenerator\IdGeneratorInterface;
6
use ScayTrase\Api\JsonRpc\JsonRpcRequest;
7
use ScayTrase\Api\JsonRpc\JsonRpcRequestInterface;
8
use ScayTrase\Api\JsonRpc\RequestTransformation;
9
use ScayTrase\Api\Rpc\Exception\RemoteCallFailedException;
10
use ScayTrase\Api\Rpc\RpcClientInterface;
11
use ScayTrase\Api\Rpc\RpcRequestInterface;
12
use Symfony\Component\BrowserKit\Client;
13
use Symfony\Component\BrowserKit\Request;
14
use Symfony\Component\BrowserKit\Response;
15
16
final class JsonRpcClient implements RpcClientInterface
17
{
18
    /** @var Client */
19
    private $client;
20
    /**
21
     * @var string
22
     */
23
    private $uri;
24
    /**
25
     * @var IdGeneratorInterface
26
     */
27
    private $idGenerator;
28
29
    /**
30
     * JsonRpcClient constructor.
31
     *
32
     * @param Client               $client
33
     * @param string               $uri
34
     * @param IdGeneratorInterface $idGenerator
35
     */
36
    public function __construct(Client $client, $uri, IdGeneratorInterface $idGenerator)
37
    {
38
        $this->client      = $client;
39
        $this->uri         = $uri;
40
        $this->idGenerator = $idGenerator;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function invoke($calls)
47
    {
48
        try {
49
            if (!is_array($calls) && ($calls instanceof RpcRequestInterface)) {
50
                $transformedCall = $this->transformCall($calls);
51
52
                $httpRequest = $this->createHttpRequest($transformedCall);
53
                $this->client->request(
54
                    $httpRequest->getMethod(),
55
                    $httpRequest->getUri(),
56
                    [],
57
                    [],
58
                    $httpRequest->getServer(),
59
                    $httpRequest->getContent()
60
                );
61
62
                return new JsonRpcResponseCollection(
63
                    $this->checkResponse(),
64
                    [new RequestTransformation($calls, $transformedCall)]
65
                );
66
            }
67
68
            $requests     = [];
69
            $batchRequest = [];
70
71
            foreach ((array)$calls as $key => $call) {
72
                $transformedCall                  = $this->transformCall($call);
73
                $requests[spl_object_hash($call)] = new RequestTransformation($call, $transformedCall);
74
                $batchRequest[]                   = $transformedCall;
75
            }
76
77
            $this->client->restart();
78
79
            $httpRequest = $this->createHttpRequest($batchRequest);
80
            $this->client->request(
81
                $httpRequest->getMethod(),
82
                $httpRequest->getUri(),
83
                $httpRequest->getParameters(),
84
                [],
85
                $httpRequest->getServer(),
86
                $httpRequest->getContent()
87
            );
88
89
            return new JsonRpcResponseCollection(
90
                $this->checkResponse(),
91
                $requests
92
            );
93
        } catch (\Exception $exception) {
94
            throw new RemoteCallFailedException($exception->getMessage(), 0, $exception);
95
        }
96
    }
97
98
    /**
99
     * @param $requestBody
100
     *
101
     * @return Request
102
     */
103
    private function createHttpRequest($requestBody)
104
    {
105
        return new Request(
106
            $this->uri,
107
            'POST',
108
            [],
109
            [],
110
            [],
111
            [
112
                'HTTP_CONTENT_TYPE' => 'application/json',
113
                'HTTP_ACCEPT'       => 'application/json',
114
            ],
115
            json_encode($requestBody, JSON_PRETTY_PRINT)
116
        );
117
    }
118
119
    /**
120
     * @param RpcRequestInterface $call
121
     *
122
     * @return JsonRpcRequest
123
     */
124
    private function transformCall(RpcRequestInterface $call)
125
    {
126
        $transformedCall = $call;
127
        if ($call instanceof RpcRequestInterface && !($call instanceof JsonRpcRequestInterface)) {
128
            $transformedCall = JsonRpcRequest::fromRpcRequest($call, $this->idGenerator->getRequestIdentifier($call));
129
        }
130
131
        return $transformedCall;
132
    }
133
134
    /**
135
     * @return Response
136
     */
137
    private function checkResponse()
138
    {
139
        return $this->client->getInternalResponse();
140
    }
141
}
142