Passed
Push — master ( 670d61...49fd8e )
by Igor
02:16
created

ClientFactory   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 97.06%

Importance

Changes 0
Metric Value
wmc 10
eloc 32
dl 0
loc 66
ccs 33
cts 34
cp 0.9706
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createTransport() 0 28 5
A createClient() 0 7 1
A createCaller() 0 6 1
A createRequestObjectFactory() 0 9 2
A __construct() 0 3 1
1
<?php
2
/*
3
 * This file is part of JSON RPC Client.
4
 *
5
 * (c) Igor Lazarev <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Strider2038\JsonRpcClient;
12
13
use GuzzleHttp\Client;
14
use Psr\Log\LoggerInterface;
15
use Ramsey\Uuid\Uuid;
16
use Strider2038\JsonRpcClient\Exception\InvalidConfigException;
17
use Strider2038\JsonRpcClient\Request\RandomIntegerIdGenerator;
18
use Strider2038\JsonRpcClient\Request\RequestObjectFactory;
19
use Strider2038\JsonRpcClient\Request\UuidGenerator;
20
use Strider2038\JsonRpcClient\Response\ExceptionalResponseValidator;
21
use Strider2038\JsonRpcClient\Serialization\JsonObjectSerializer;
22
use Strider2038\JsonRpcClient\Service\Caller;
23
use Strider2038\JsonRpcClient\Service\HighLevelClient;
24
use Strider2038\JsonRpcClient\Transport\GuzzleHttpTransport;
25
use Strider2038\JsonRpcClient\Transport\TcpTransport;
26
use Strider2038\JsonRpcClient\Transport\TransportInterface;
27
use Strider2038\JsonRpcClient\Transport\TransportLoggingDecorator;
28
29
/**
30
 * @experimental API may be changed
31
 *
32
 * @author Igor Lazarev <[email protected]>
33
 */
34
class ClientFactory
35
{
36
    /** @var LoggerInterface|null */
37
    private $logger;
38
39 5
    public function __construct(LoggerInterface $logger = null)
40
    {
41 5
        $this->logger = $logger;
42 5
    }
43
44 5
    public function createClient(string $connection, array $options = []): ClientInterface
45
    {
46 5
        $requestObjectFactory = $this->createRequestObjectFactory();
47 5
        $transport = $this->createTransport($connection, $options);
48 4
        $caller = $this->createCaller($transport);
49
50 4
        return new HighLevelClient($requestObjectFactory, $caller);
51
    }
52
53 5
    private function createRequestObjectFactory(): RequestObjectFactory
54
    {
55 5
        if (class_exists(Uuid::class)) {
56 5
            $idGenerator = new UuidGenerator();
57
        } else {
58
            $idGenerator = new RandomIntegerIdGenerator();
59
        }
60
61 5
        return new RequestObjectFactory($idGenerator);
62
    }
63
64 4
    private function createCaller(TransportInterface $transport): Caller
65
    {
66 4
        $serializer = new JsonObjectSerializer();
67 4
        $validator = new ExceptionalResponseValidator();
68
69 4
        return new Caller($serializer, $transport, $validator);
70
    }
71
72 5
    private function createTransport(string $connection, array $options): TransportInterface
73
    {
74 5
        $scheme = strtolower(parse_url($connection, PHP_URL_SCHEME));
75 5
        $timeout = (float) ($options['timeout_ms'] ?? 1000);
76
77 5
        if ('tcp' === $scheme) {
78 2
            $transport = new TcpTransport($connection, (int) $timeout);
79 3
        } elseif ('http' === $scheme || 'https' === $scheme) {
80 2
            $guzzle = new Client([
81 2
                'base_uri' => $connection,
82 2
                'timeout'  => $timeout / 1000,
83
            ]);
84
85 2
            $transport = new GuzzleHttpTransport($guzzle);
86
        } else {
87 1
            throw new InvalidConfigException(
88 1
                sprintf(
89 1
                    'Unsupported protocol: "%s". Supported protocols: "tcp", "http", "https".',
90 1
                    $scheme
91
                )
92
            );
93
        }
94
95 4
        if ($this->logger) {
96 1
            $transport = new TransportLoggingDecorator($transport, $this->logger);
97
        }
98
99 4
        return $transport;
100
    }
101
}
102