Completed
Pull Request — master (#62)
by .
03:13
created

ClientRegistry   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 98.21%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 157
ccs 55
cts 56
cp 0.9821
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A addClientsConfigurations() 0 6 2
A addClientConfiguration() 0 4 1
A buildClientConfiguration() 0 16 1
A buildConnectionUri() 0 16 2
A getClientForDatabase() 0 4 1
A getClientNames() 0 4 1
A getClient() 0 24 3
A buildClient() 0 8 2
1
<?php declare(strict_types=1);
2
3
namespace Facile\MongoDbBundle\Services;
4
5
use Facile\MongoDbBundle\Capsule\Client as BundleClient;
6
use Facile\MongoDbBundle\Event\ConnectionEvent;
7
use Facile\MongoDbBundle\Models\ClientConfiguration;
8
use MongoDB\Client;
9
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
10
11
/**
12
 * Class ClientRegistry.
13
 * @internal
14
 */
15
final class ClientRegistry
16
{
17
    /** @var Client[] */
18
    private $clients;
19
    /** @var ClientConfiguration[] */
20
    private $configurations;
21
    /** @var string */
22
    private $environment;
23
    /** @var EventDispatcherInterface */
24
    private $eventDispatcher;
25
26
    /**
27
     * ClientRegistry constructor.
28
     *
29
     * @param EventDispatcherInterface $eventDispatcher
30
     * @param string $environment
31
     *
32
     * @internal param DataCollectorLoggerInterface $logger
33
     */
34 30
    public function __construct(EventDispatcherInterface $eventDispatcher, string $environment)
35
    {
36 30
        $this->clients = [];
37 30
        $this->configurations = [];
38 30
        $this->environment = $environment;
39 30
        $this->eventDispatcher = $eventDispatcher;
40 30
    }
41
42
    /**
43
     * @param array $configurations
44
     */
45 30
    public function addClientsConfigurations(array $configurations)
46
    {
47 30
        foreach ($configurations as $name => $conf) {
48 30
            $this->addClientConfiguration($name, $conf);
49
        }
50 30
    }
51
52
    /**
53
     * @param string $name
54
     * @param array $conf
55
     */
56 30
    private function addClientConfiguration(string $name, array $conf)
57
    {
58 30
        $this->configurations[$name] = $this->buildClientConfiguration($conf);
59 30
    }
60
61
    /**
62
     * @param array $conf
63
     *
64
     * @return ClientConfiguration
65
     */
66 30
    private function buildClientConfiguration(array $conf): ClientConfiguration
67
    {
68 30
        return new ClientConfiguration(
69 30
            $conf['proto'],
70 30
            $this->buildConnectionUri($conf['hosts']),
71 30
            $conf['username'],
72 30
            $conf['password'],
73 30
            $conf['authSource'],
74
            [
75 30
                'replicaSet' => $conf['replicaSet'],
76 30
                'ssl' => $conf['ssl'],
77 30
                'connectTimeoutMS' => $conf['connectTimeoutMS'],
78 30
                'readPreference' => $conf['readPreference']
79
            ]
80
        );
81
    }
82
83
    /**
84
     * @param array $hosts
85
     *
86
     * @return string
87
     */
88 30
    private function buildConnectionUri(array $hosts): string
89
    {
90 30
        return implode(
91 30
            ',',
92 30
            array_map(
93 30
                function (array $host) {
94 30
                    if (!$host['port']) {
95
                        return $host['host'];
96
                    }
97
98 30
                    return sprintf("%s:%d", $host['host'], $host['port']);
99 30
                },
100 30
                $hosts
101
            )
102
        );
103
    }
104
105
    /**
106
     * @param string $name
107
     * @param string $databaseName
108
     *
109
     * @return Client
110
     */
111 11
    public function getClientForDatabase(string $name, string $databaseName): Client
112
    {
113 11
        return $this->getClient($name, $databaseName);
114
    }
115
116
    /**
117
     * @return array
118
     */
119 1
    public function getClientNames(): array
120
    {
121 1
        return array_keys($this->clients);
122
    }
123
124
    /**
125
     * @param string $name
126
     * @param string $databaseName
127
     *
128
     * @return Client
129
     */
130 28
    public function getClient(string $name, string $databaseName = null): Client
131
    {
132 28
        $clientKey = null !== $databaseName ? $name . '.' . $databaseName : $name;
133
134 28
        if (! isset($this->clients[$clientKey])) {
135 28
            $conf = $this->configurations[$name];
136 28
            $uri = sprintf('%s://%s', $conf->getProto(), $conf->getHosts());
137 28
            $options = array_merge(
138
                [
139 28
                    'database' => $databaseName,
140 28
                    'authSource' => $conf->getAuthSource() ?? $databaseName ?? 'admin'
141
                ],
142 28
                $conf->getOptions()
143
            );
144 28
            $this->clients[$clientKey] = $this->buildClient($name, $uri, $options, []);
145
146 28
            $this->eventDispatcher->dispatch(
147 28
                ConnectionEvent::CLIENT_CREATED,
148 28
                new ConnectionEvent($clientKey)
149
            );
150
        }
151
152 28
        return $this->clients[$clientKey];
153
    }
154
155
    /**
156
     * @param string $clientName
157
     * @param string $uri
158
     * @param array $options
159
     * @param array $driverOptions
160
     *
161
     * @return Client
162
     */
163 28
    private function buildClient(string $clientName, string $uri, array $options, array $driverOptions): Client
164
    {
165 28
        if ('dev' === $this->environment) {
166 5
            return new BundleClient($uri, $options, $driverOptions, $clientName, $this->eventDispatcher);
167
        }
168
169 23
        return new Client($uri, $options, $driverOptions);
170
    }
171
}
172