Completed
Push — master ( d608d1...623c6b )
by Alessandro
08:12 queued 06:25
created

ClientRegistry::getClient()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
ccs 14
cts 14
cp 1
rs 8.9713
cc 3
eloc 14
nc 4
nop 2
crap 3
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 29
    public function __construct(EventDispatcherInterface $eventDispatcher, string $environment)
35
    {
36 29
        $this->clients = [];
37 29
        $this->configurations = [];
38 29
        $this->environment = $environment;
39 29
        $this->eventDispatcher = $eventDispatcher;
40 29
    }
41
42
    /**
43
     * @param array $configurations
44
     */
45 29
    public function addClientsConfigurations(array $configurations)
46
    {
47 29
        foreach ($configurations as $name => $conf) {
48 29
            $this->addClientConfiguration($name, $conf);
49
        }
50 29
    }
51
52
    /**
53
     * @param string $name
54
     * @param array  $conf
55
     */
56 29
    private function addClientConfiguration(string $name, array $conf)
57
    {
58 29
        $this->configurations[$name] = $this->buildClientConfiguration($conf);
59 29
    }
60
61
    /**
62
     * @param array $conf
63
     *
64
     * @return ClientConfiguration
65
     */
66 29
    private function buildClientConfiguration(array $conf): ClientConfiguration
67
    {
68 29
        return new ClientConfiguration(
69 29
            $this->buildConnectionUri($conf['hosts']),
70 29
            $conf['username'],
71 29
            $conf['password'],
72 29
            $conf['authSource'],
73
            [
74 29
                'replicaSet' => $conf['replicaSet'],
75 29
                'ssl' => $conf['ssl'],
76 29
                'connectTimeoutMS' => $conf['connectTimeoutMS'],
77 29
                'readPreference' => $conf['readPreference']
78
            ]
79
        );
80
    }
81
82
    /**
83
     * @param array $hosts
84
     *
85
     * @return string
86
     */
87 29
    private function buildConnectionUri(array $hosts): string
88
    {
89 29
        return implode(
90 29
            ',',
91 29
            array_map(
92 29
                function(array $host) {
93 29
                    return sprintf("%s:%d", $host['host'], $host['port']);
94 29
                },
95 29
                $hosts
96
            )
97
        );
98
    }
99
100
    /**
101
     * @param string $name
102
     * @param string $databaseName
103
     *
104
     * @return Client
105
     */
106 10
    public function getClientForDatabase(string $name, string $databaseName): Client
107
    {
108 10
        return $this->getClient($name, $databaseName);
109
    }
110
111
    /**
112
     * @return array
113
     */
114 1
    public function getClientNames(): array
115
    {
116 1
        return array_keys($this->clients);
117
    }
118
119
    /**
120
     * @param string $name
121
     * @param string $databaseName
122
     *
123
     * @return Client
124
     */
125 27
    public function getClient(string $name, string $databaseName = null): Client
126
    {
127 27
        $clientKey = !is_null($databaseName) ? $name.'.'.$databaseName : $name;
128
129 27
        if (!isset($this->clients[$clientKey])) {
130 27
            $conf = $this->configurations[$name];
131 27
            $uri = sprintf('mongodb://%s', $conf->getHosts());
132 27
            $options = array_merge(
133
                [
134 27
                    'database' => $databaseName,
135 27
                    'authSource' => $conf->getAuthSource() ?? $databaseName
136
                ],
137 27
                $conf->getOptions()
138
            );
139 27
            $this->clients[$clientKey] = $this->buildClient($name, $uri, $options, []);
140
141 27
            $this->eventDispatcher->dispatch(
142 27
                ConnectionEvent::CLIENT_CREATED,
143 27
                new ConnectionEvent($clientKey)
144
            );
145
        }
146
147 27
        return $this->clients[$clientKey];
148
    }
149
150
    /**
151
     * @param string $clientName
152
     * @param string $uri
153
     * @param array  $options
154
     * @param array  $driverOptions
155
     *
156
     * @return Client
157
     */
158 27
    private function buildClient(string $clientName, string $uri, array $options, array $driverOptions): Client
159
    {
160 27
        if ('dev' === $this->environment) {
161 5
            return new BundleClient($uri, $options, $driverOptions, $clientName, $this->eventDispatcher);
162
        }
163
164 22
        return new Client($uri, $options, $driverOptions);
165
    }
166
}
167