Skip to content

Commit 772d330

Browse files
committed
MC-20710: Add Elasticsearch configuration parameters to console
- add unit tests
1 parent f1c2fb7 commit 772d330

File tree

10 files changed

+534
-23
lines changed

10 files changed

+534
-23
lines changed

app/code/Magento/Elasticsearch/Setup/ConnectionValidator.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,14 @@ public function __construct(ClientResolver $clientResolver)
3636
*/
3737
public function validate($configuration)
3838
{
39-
if (isset($configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_SKIP_VALIDATION])
40-
&& $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_SKIP_VALIDATION]
41-
) {
42-
return true;
43-
}
44-
4539
$configOptions = [
46-
'hostname' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_HOST],
47-
'port' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_PORT],
48-
'index' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_INDEX_PREFIX],
49-
'enableAuth' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_ENABLE_AUTH],
40+
'hostname' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_HOST] ?? null,
41+
'port' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_PORT] ?? null,
42+
'index' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_INDEX_PREFIX] ?? null,
43+
'enableAuth' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_ENABLE_AUTH] ?? false,
5044
'username' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_USERNAME] ?? null,
5145
'password' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_PASSWORD] ?? null,
52-
'timeout' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_TIMEOUT]
46+
'timeout' => $configuration[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_TIMEOUT] ?? null
5347
];
5448

5549
try {

app/code/Magento/Elasticsearch/Setup/InstallConfig.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
use Magento\Setup\Model\SearchConfigOptionsList;
1313
use Magento\Search\Setup\InstallConfigInterface;
1414

15+
/**
16+
* Configure Elasticsearch search engine based on installation input
17+
*/
1518
class InstallConfig implements InstallConfigInterface
1619
{
1720
private const CATALOG_SEARCH = 'catalog/search/';
@@ -41,7 +44,7 @@ class InstallConfig implements InstallConfigInterface
4144
public function __construct(
4245
WriterInterface $configWriter,
4346
ConnectionValidator $validator,
44-
array $searchConfigMapping
47+
array $searchConfigMapping = []
4548
) {
4649
$this->configWriter = $configWriter;
4750
$this->validator = $validator;
@@ -53,22 +56,32 @@ public function __construct(
5356
*/
5457
public function configure(array $inputOptions)
5558
{
56-
if (!isset($inputOptions['skip-elasticsearch-validation']) || !$inputOptions['skip-elasticsearch-validation']) {
59+
if ($this->doValidation($inputOptions)) {
5760
if (!$this->validator->validate($inputOptions)) {
5861
throw new InputException(__('Could not connect to Elasticsearch server.'));
5962
}
6063
}
6164

6265
foreach ($inputOptions as $inputKey => $inputValue) {
63-
if (null === $inputValue) {
64-
continue;
65-
}
66-
$configKey = $this->searchConfigMapping[$inputKey] ?? null;
67-
if (empty($configKey)) {
66+
if (null === $inputValue || !isset($this->searchConfigMapping[$inputKey])) {
6867
continue;
6968
}
70-
69+
$configKey = $this->searchConfigMapping[$inputKey];
7170
$this->configWriter->save(self::CATALOG_SEARCH . $configKey, $inputValue);
7271
}
7372
}
73+
74+
/**
75+
* Check if elasticsearch validation should be performed
76+
*
77+
* @param array $inputOptions
78+
* @return bool
79+
*/
80+
private function doValidation(array $inputOptions)
81+
{
82+
if (isset($inputOptions[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_SKIP_VALIDATION])) {
83+
return !$inputOptions[SearchConfigOptionsList::INPUT_KEY_ELASTICSEARCH_SKIP_VALIDATION];
84+
}
85+
return true;
86+
}
7487
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\Test\Unit\Setup;
9+
10+
use Magento\AdvancedSearch\Model\Client\ClientResolver;
11+
use Magento\Elasticsearch\Setup\ConnectionValidator;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
13+
use Magento\Elasticsearch\Elasticsearch5\Model\Client\Elasticsearch;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class ConnectionValidatorTest extends TestCase
17+
{
18+
private $connectionValidator;
19+
20+
private $clientResolverMock;
21+
22+
private $elasticsearchClientMock;
23+
24+
protected function setUp()
25+
{
26+
$this->clientResolverMock = $this->getMockBuilder(ClientResolver::class)
27+
->disableOriginalConstructor()
28+
->getMock();
29+
$this->elasticsearchClientMock = $this->getMockBuilder(Elasticsearch::class)
30+
->disableOriginalConstructor()
31+
->getMock();
32+
33+
$objectManager = new ObjectManager($this);
34+
$this->connectionValidator = $objectManager->getObject(
35+
ConnectionValidator::class,
36+
[
37+
'clientResolver' => $this->clientResolverMock
38+
]
39+
);
40+
}
41+
42+
public function testValidate()
43+
{
44+
$configuration = [
45+
'search-engine' => 'elasticsearch5',
46+
'elasticsearch-host' => 'localhost',
47+
'elasticsearch-port' => '9200',
48+
'elasticsearch-index-prefix' => 'm2',
49+
'elasticsearch-enable-auth' => false,
50+
'elasticsearch-timeout' => 20
51+
];
52+
$mappedConfig = [
53+
'hostname' => 'localhost',
54+
'port' => '9200',
55+
'index' => 'm2',
56+
'enableAuth' => false,
57+
'username' => null,
58+
'password' => null,
59+
'timeout' => 20
60+
];
61+
62+
$this->clientResolverMock
63+
->expects($this->once())
64+
->method('create')
65+
->with($configuration['search-engine'], $mappedConfig)
66+
->willReturn($this->elasticsearchClientMock);
67+
$this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(true);
68+
69+
$this->assertTrue($this->connectionValidator->validate($configuration));
70+
}
71+
72+
public function testValidateFail()
73+
{
74+
$configuration = [
75+
'search-engine' => 'elasticsearch5',
76+
'elasticsearch-host' => 'localhost',
77+
'elasticsearch-port' => '9200',
78+
'elasticsearch-index-prefix' => 'm2',
79+
'elasticsearch-enable-auth' => true,
80+
'elasticsearch-timeout' => 20
81+
];
82+
$mappedConfig = [
83+
'hostname' => 'localhost',
84+
'port' => '9200',
85+
'index' => 'm2',
86+
'enableAuth' => true,
87+
'username' => null,
88+
'password' => null,
89+
'timeout' => 20
90+
];
91+
92+
$this->clientResolverMock
93+
->expects($this->once())
94+
->method('create')
95+
->with($configuration['search-engine'], $mappedConfig)
96+
->willReturn($this->elasticsearchClientMock);
97+
$this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(false);
98+
99+
$this->assertFalse($this->connectionValidator->validate($configuration));
100+
}
101+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\Test\Unit\Setup;
9+
10+
use Magento\Elasticsearch\Setup\ConnectionValidator;
11+
use Magento\Elasticsearch\Setup\InstallConfig;
12+
use Magento\Framework\App\Config\Storage\WriterInterface;
13+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class InstallConfigTest extends TestCase
17+
{
18+
private $installConfig;
19+
20+
private $validatorMock;
21+
22+
private $configWriterMock;
23+
24+
protected function setup()
25+
{
26+
$this->validatorMock = $this->getMockBuilder(ConnectionValidator::class)
27+
->disableOriginalConstructor()
28+
->getMock();
29+
$this->configWriterMock = $this->getMockBuilder(WriterInterface::class)->getMockForAbstractClass();
30+
31+
32+
$objectManager = new ObjectManager($this);
33+
$this->installConfig = $objectManager->getObject(
34+
InstallConfig::class,
35+
[
36+
'configWriter' => $this->configWriterMock,
37+
'validator' => $this->validatorMock,
38+
'searchConfigMapping' => [
39+
'elasticsearch-host' => 'elasticsearch5_server_hostname',
40+
'elasticsearch-port' => 'elasticsearch5_server_port',
41+
'elasticsearch-timeout' => 'elasticsearch5_server_timeout',
42+
'elasticsearch-index-prefix' => 'elasticsearch5_index_prefix',
43+
'elasticsearch-enable-auth' => 'elasticsearch5_enable_auth',
44+
'elasticsearch-username' => 'elasticsearch5_username',
45+
'elasticsearch-password' => 'elasticsearch5_password',
46+
]
47+
]
48+
);
49+
}
50+
51+
public function testConfigure()
52+
{
53+
$inputOptions = [
54+
'search-engine' => 'elasticsearch5',
55+
'elasticsearch-host' => 'localhost',
56+
'elasticsearch-port' => '9200'
57+
];
58+
59+
$this->validatorMock->expects($this->once())->method('validate')->with($inputOptions)->willReturn(true);
60+
$this->configWriterMock
61+
->expects($this->at(0))
62+
->method('save')
63+
->with('catalog/search/engine', 'elasticsearch5');
64+
$this->configWriterMock
65+
->expects($this->at(1))
66+
->method('save')
67+
->with('catalog/search/elasticsearch5_server_hostname', 'localhost');
68+
$this->configWriterMock
69+
->expects($this->at(2))
70+
->method('save')
71+
->with('catalog/search/elasticsearch5_server_port', '9200');
72+
73+
$this->installConfig->configure($inputOptions);
74+
}
75+
76+
/**
77+
* @expectedException \Magento\Framework\Exception\InputException
78+
* @expectedExceptionMessage Could not connect to Elasticsearch server.
79+
*/
80+
public function testConfigureValidateFail()
81+
{
82+
$inputOptions = [
83+
'search-engine' => 'elasticsearch5',
84+
'elasticsearch-host' => 'es.domain.com',
85+
'elasticsearch-port' => '9200'
86+
];
87+
88+
$this->validatorMock->expects($this->once())->method('validate')->with($inputOptions)->willReturn(false);
89+
$this->configWriterMock->expects($this->never())->method('save');
90+
91+
$this->installConfig->configure($inputOptions);
92+
}
93+
94+
public function testConfigureWithSkipValidation()
95+
{
96+
$inputOptions = [
97+
'search-engine' => 'elasticsearch5',
98+
'elasticsearch-host' => 'localhost',
99+
'elasticsearch-port' => '9200',
100+
'skip-elasticsearch-validation' => true
101+
];
102+
103+
$this->validatorMock->expects($this->never())->method('validate');
104+
$this->configWriterMock
105+
->expects($this->at(0))
106+
->method('save')
107+
->with('catalog/search/engine', 'elasticsearch5');
108+
$this->configWriterMock
109+
->expects($this->at(1))
110+
->method('save')
111+
->with('catalog/search/elasticsearch5_server_hostname', 'localhost');
112+
$this->configWriterMock
113+
->expects($this->at(2))
114+
->method('save')
115+
->with('catalog/search/elasticsearch5_server_port', '9200');
116+
117+
$this->installConfig->configure($inputOptions);
118+
}
119+
}

app/code/Magento/Search/Setup/CompositeInstallConfig.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
use Magento\Framework\Exception\InputException;
1111

12+
/**
13+
* Composite object uses the proper InstallConfigInterface implementation for the engine being configured
14+
*/
1215
class CompositeInstallConfig implements InstallConfigInterface
1316
{
1417
/**
@@ -33,7 +36,7 @@ public function configure(array $inputOptions)
3336

3437
if (!isset($this->installConfigList[$searchEngine])) {
3538
//TODO better exception handling
36-
throw new InputException(__('Unable to configure search engine ' . $searchEngine));
39+
throw new InputException(__('Unable to configure search engine: ' . $searchEngine));
3740
}
3841
$installConfig = $this->installConfigList[$searchEngine];
3942

app/code/Magento/Search/Setup/InstallConfigInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
use Magento\Framework\Exception\InputException;
1111

12+
/**
13+
* Configure search engine from installation input
14+
*/
1215
interface InstallConfigInterface
1316
{
1417
/**

0 commit comments

Comments
 (0)