Completed
Push — master ( 5e7d5e...db75a5 )
by Avtandil
07:05
created

ElasticSearchManager   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 277
Duplicated Lines 12.64 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 35
loc 277
ccs 0
cts 208
cp 0
rs 8.2608
c 0
b 0
f 0
wmc 40
lcom 1
cbo 1

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setEnabled() 0 6 1
A setTimeout() 0 6 1
B createIndex() 0 26 4
B deleteIndexes() 0 24 5
A deleteIndexesByAlias() 0 18 3
B addDocumentsToIndex() 0 33 5
A refreshIndex() 18 18 3
A performSearch() 17 17 3
B switchIndexAlias() 0 54 6
B createTemplate() 0 23 4
A ping() 0 8 2
A getClient() 0 4 1
A isEnabled() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ElasticSearchManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ElasticSearchManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of the Laravel Lodash package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[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
declare(strict_types=1);
11
12
namespace Longman\LaravelLodash\ElasticSearch;
13
14
use ElasticSearch\Client;
15
use InvalidArgumentException;
16
use RuntimeException;
17
18
class ElasticSearchManager implements ElasticSearchManagerContract
19
{
20
    /**
21
     * @var \ElasticSearch\Client
22
     */
23
    protected $client;
24
25
    /**
26
     * @var bool
27
     */
28
    protected $enabled;
29
30
    /**
31
     * @var int|null
32
     */
33
    protected $timeout;
34
35
    public function __construct(Client $client, bool $enabled = false)
36
    {
37
        $this->client = $client;
38
        $this->enabled = $enabled;
39
    }
40
41
    public function setEnabled(bool $enabled): ElasticSearchManagerContract
42
    {
43
        $this->enabled = $enabled;
44
45
        return $this;
46
    }
47
48
    public function setTimeout(int $timeout): ElasticSearchManagerContract
49
    {
50
        $this->timeout = $timeout;
51
52
        return $this;
53
    }
54
55
    public function createIndex(string $index_name, array $settings, array $mappings)
56
    {
57
        if (! $this->isEnabled()) {
58
            return;
59
        }
60
61
        $params = [
62
            'index' => $index_name,
63
            'body'  => [
64
                'settings' => $settings,
65
                'mappings' => $mappings,
66
            ],
67
        ];
68
69
        if (! empty($this->timeout)) {
70
            $params['client'] = [
71
                'timeout' => $this->timeout,
72
            ];
73
        }
74
75
        $response = $this->client->indices()->create($params);
76
77
        if ($response['acknowledged'] !== true) {
78
            throw new RuntimeException('Something went wrong during index creation');
79
        }
80
    }
81
82
    public function deleteIndexes(array $names)
83
    {
84
        if (! $this->isEnabled()) {
85
            return;
86
        }
87
        if (empty($names)) {
88
            throw new InvalidArgumentException('Index names can not be empty');
89
        }
90
91
        $params = [
92
            'index' => implode(',', $names),
93
        ];
94
95
        if (! empty($this->timeout)) {
96
            $params['client'] = [
97
                'timeout' => $this->timeout,
98
            ];
99
        }
100
101
        $response = $this->client->indices()->delete($params);
102
        if ($response['acknowledged'] !== true) {
103
            throw new RuntimeException('Something went wrong during index deletion');
104
        }
105
    }
106
107
    public function deleteIndexesByAlias(string $alias_name)
108
    {
109
        if (! $this->isEnabled()) {
110
            return;
111
        }
112
113
        $params = [
114
            'name' => $alias_name,
115
        ];
116
117
        $response = $this->client->indices()->getAlias($params);
118
        if (empty($response)) {
119
            throw new RuntimeException('Can not get alias ' . $alias_name);
120
        }
121
122
        $indexes = array_keys($response);
123
        $this->deleteIndexes($indexes);
124
    }
125
126
    public function addDocumentsToIndex(string $index_name, string $type_name, array $items)
127
    {
128
        if (! $this->isEnabled()) {
129
            return;
130
        }
131
132
        $params = [
133
            'body' => [],
134
        ];
135
136
        if (! empty($this->timeout)) {
137
            $params['client'] = [
138
                'timeout' => $this->timeout,
139
            ];
140
        }
141
142
        foreach ($items as $id => $item) {
143
            $params['body'][] = [
144
                'index' => [
145
                    '_index' => $index_name,
146
                    '_type'  => $type_name,
147
                    '_id'    => $id,
148
                ],
149
            ];
150
151
            $params['body'][] = $item;
152
        }
153
154
        $responses = $this->client->bulk($params);
155
        if ($responses['errors'] === true) {
156
            throw new RuntimeException('Error occurred during bulk insert');
157
        }
158
    }
159
160 View Code Duplication
    public function refreshIndex(string $index_name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
    {
162
        if (! $this->isEnabled()) {
163
            return;
164
        }
165
166
        $params = [
167
            'index' => $index_name,
168
        ];
169
170
        if (! empty($this->timeout)) {
171
            $params['client'] = [
172
                'timeout' => $this->timeout,
173
            ];
174
        }
175
176
        $this->client->indices()->refresh($params);
177
    }
178
179 View Code Duplication
    public function performSearch(ElasticSearchQueryContract $query): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
    {
181
        if (! $this->isEnabled()) {
182
            return [];
183
        }
184
185
        $params = $query->build();
186
        if (! empty($this->timeout)) {
187
            $params['client'] = [
188
                'timeout' => $this->timeout,
189
            ];
190
        }
191
192
        $results = $this->client->search($params);
193
194
        return $results;
195
    }
196
197
    public function switchIndexAlias(string $alias_name, string $index_name)
198
    {
199
        if (! $this->isEnabled()) {
200
            return;
201
        }
202
203
        $params = [
204
            'name' => $alias_name,
205
        ];
206
207
        $exists = $this->client->indices()->existsAlias($params);
208
209
        $actions = [];
210
        // If alias already exists remove from indexes
211
        if ($exists) {
212
            $params = [
213
                'name' => $alias_name,
214
            ];
215
216
            $response = $this->client->indices()->getAlias($params);
217
            if (empty($response)) {
218
                throw new RuntimeException('Can not get alias ' . $alias_name);
219
            }
220
221
            $indexes = array_keys($response);
222
223
            foreach ($indexes as $index) {
224
                $actions[] = [
225
                    'remove' => [
226
                        'index' => $index,
227
                        'alias' => $alias_name,
228
                    ],
229
                ];
230
            }
231
        }
232
233
        $actions[] = [
234
            'add' => [
235
                'index' => $index_name,
236
                'alias' => $alias_name,
237
            ],
238
        ];
239
240
        $params = [
241
            'body' => [
242
                'actions' => $actions,
243
            ],
244
        ];
245
246
        $response = $this->client->indices()->updateAliases($params);
247
        if ($response['acknowledged'] !== true) {
248
            throw new RuntimeException('Switching alias response error');
249
        }
250
    }
251
252
    public function createTemplate(string $name, array $settings)
253
    {
254
        if (! $this->isEnabled()) {
255
            return;
256
        }
257
258
        $params = [
259
            'name' => $name,
260
            'body' => $settings,
261
        ];
262
263
        if (! empty($this->timeout)) {
264
            $params['client'] = [
265
                'timeout' => $this->timeout,
266
            ];
267
        }
268
269
        $response = $this->client->indices()->putTemplate($params);
270
271
        if ($response['acknowledged'] !== true) {
272
            throw new RuntimeException('Something went wrong during template creation');
273
        }
274
    }
275
276
    public function ping(): bool
277
    {
278
        if (! $this->isEnabled()) {
279
            return false;
280
        }
281
282
        return $this->client->ping();
283
    }
284
285
    public function getClient(): Client
286
    {
287
        return $this->client;
288
    }
289
290
    public function isEnabled(): bool
291
    {
292
        return $this->enabled;
293
    }
294
}
295