Skip to content

Commit 9f2e1ce

Browse files
committed
Merge remote-tracking branch 'origin/MC-20710' into MC-33394-pr-delivery
2 parents f442fa9 + 9cfadcf commit 9f2e1ce

File tree

18 files changed

+952
-3
lines changed

18 files changed

+952
-3
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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\Setup;
9+
10+
use Magento\AdvancedSearch\Model\Client\ClientResolver;
11+
12+
/**
13+
* Validate Elasticsearch connection
14+
*/
15+
class ConnectionValidator
16+
{
17+
/**
18+
* @var ClientResolver
19+
*/
20+
private $clientResolver;
21+
22+
/**
23+
* @param ClientResolver $clientResolver
24+
*/
25+
public function __construct(ClientResolver $clientResolver)
26+
{
27+
$this->clientResolver = $clientResolver;
28+
}
29+
30+
/**
31+
* Checks Elasticsearch Connection
32+
*
33+
* @param string $searchEngine
34+
* @return bool true if the connection succeeded, false otherwise
35+
*/
36+
public function validate(string $searchEngine): bool
37+
{
38+
try {
39+
$client = $this->clientResolver->create($searchEngine);
40+
return $client->testConnection();
41+
} catch (\Exception $e) {
42+
return false;
43+
}
44+
}
45+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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\Setup;
9+
10+
use Magento\Framework\App\Config\Storage\WriterInterface;
11+
use Magento\Framework\Exception\InputException;
12+
use Magento\Setup\Model\SearchConfigOptionsList;
13+
use Magento\Search\Setup\InstallConfigInterface;
14+
15+
/**
16+
* Configure Elasticsearch search engine based on installation input
17+
*/
18+
class InstallConfig implements InstallConfigInterface
19+
{
20+
private const CATALOG_SEARCH = 'catalog/search/';
21+
22+
/**
23+
* @var array
24+
*/
25+
private $searchConfigMapping = [
26+
SearchConfigOptionsList::INPUT_KEY_SEARCH_ENGINE => 'engine'
27+
];
28+
29+
/**
30+
* @var ConnectionValidator
31+
*/
32+
private $validator;
33+
34+
/**
35+
* @var WriterInterface
36+
*/
37+
private $configWriter;
38+
39+
/**
40+
* @param WriterInterface $configWriter
41+
* @param ConnectionValidator $validator
42+
* @param array $searchConfigMapping
43+
*/
44+
public function __construct(
45+
WriterInterface $configWriter,
46+
ConnectionValidator $validator,
47+
array $searchConfigMapping = []
48+
) {
49+
$this->configWriter = $configWriter;
50+
$this->validator = $validator;
51+
$this->searchConfigMapping = array_merge($this->searchConfigMapping, $searchConfigMapping);
52+
}
53+
54+
/**
55+
* @inheritDoc
56+
*/
57+
public function configure(array $inputOptions)
58+
{
59+
foreach ($inputOptions as $inputKey => $inputValue) {
60+
if (null === $inputValue || !isset($this->searchConfigMapping[$inputKey])) {
61+
continue;
62+
}
63+
$configKey = $this->searchConfigMapping[$inputKey];
64+
$this->configWriter->save(self::CATALOG_SEARCH . $configKey, $inputValue);
65+
}
66+
if (!$this->validator->validate($inputOptions[SearchConfigOptionsList::INPUT_KEY_SEARCH_ENGINE])) {
67+
throw new InputException(
68+
__(
69+
'Connection to Elasticsearch cannot be established. '
70+
. 'Please check the configuration and try again.'
71+
)
72+
);
73+
}
74+
}
75+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
17+
class ConnectionValidatorTest extends TestCase
18+
{
19+
/**
20+
* @var ConnectionValidator
21+
*/
22+
private $connectionValidator;
23+
24+
/**
25+
* @var ClientResolver|MockObject
26+
*/
27+
private $clientResolverMock;
28+
29+
/**
30+
* @var Elasticsearch|MockObject
31+
*/
32+
private $elasticsearchClientMock;
33+
34+
protected function setUp()
35+
{
36+
$this->clientResolverMock = $this->getMockBuilder(ClientResolver::class)
37+
->disableOriginalConstructor()
38+
->getMock();
39+
$this->elasticsearchClientMock = $this->getMockBuilder(Elasticsearch::class)
40+
->disableOriginalConstructor()
41+
->getMock();
42+
43+
$objectManager = new ObjectManager($this);
44+
$this->connectionValidator = $objectManager->getObject(
45+
ConnectionValidator::class,
46+
[
47+
'clientResolver' => $this->clientResolverMock
48+
]
49+
);
50+
}
51+
52+
public function testValidate()
53+
{
54+
$searchEngine = 'elasticsearch5';
55+
56+
$this->clientResolverMock
57+
->expects($this->once())
58+
->method('create')
59+
->with($searchEngine)
60+
->willReturn($this->elasticsearchClientMock);
61+
$this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(true);
62+
63+
$this->assertTrue($this->connectionValidator->validate($searchEngine));
64+
}
65+
66+
public function testValidateFail()
67+
{
68+
$searchEngine = 'elasticsearch5';
69+
70+
$this->clientResolverMock
71+
->expects($this->once())
72+
->method('create')
73+
->with($searchEngine)
74+
->willReturn($this->elasticsearchClientMock);
75+
$this->elasticsearchClientMock->expects($this->once())->method('testConnection')->willReturn(false);
76+
77+
$this->assertFalse($this->connectionValidator->validate($searchEngine));
78+
}
79+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
17+
class InstallConfigTest extends TestCase
18+
{
19+
/**
20+
* @var InstallConfig
21+
*/
22+
private $installConfig;
23+
24+
/**
25+
* @var ConnectionValidator|MockObject
26+
*/
27+
private $validatorMock;
28+
29+
/**
30+
* @var WriterInterface|MockObject
31+
*/
32+
private $configWriterMock;
33+
34+
protected function setup()
35+
{
36+
$this->validatorMock = $this->getMockBuilder(ConnectionValidator::class)
37+
->disableOriginalConstructor()
38+
->getMock();
39+
$this->configWriterMock = $this->getMockBuilder(WriterInterface::class)->getMockForAbstractClass();
40+
41+
$objectManager = new ObjectManager($this);
42+
$this->installConfig = $objectManager->getObject(
43+
InstallConfig::class,
44+
[
45+
'configWriter' => $this->configWriterMock,
46+
'validator' => $this->validatorMock,
47+
'searchConfigMapping' => [
48+
'elasticsearch-host' => 'elasticsearch5_server_hostname',
49+
'elasticsearch-port' => 'elasticsearch5_server_port',
50+
'elasticsearch-timeout' => 'elasticsearch5_server_timeout',
51+
'elasticsearch-index-prefix' => 'elasticsearch5_index_prefix',
52+
'elasticsearch-enable-auth' => 'elasticsearch5_enable_auth',
53+
'elasticsearch-username' => 'elasticsearch5_username',
54+
'elasticsearch-password' => 'elasticsearch5_password',
55+
]
56+
]
57+
);
58+
}
59+
60+
public function testConfigure()
61+
{
62+
$inputOptions = [
63+
'search-engine' => 'elasticsearch5',
64+
'elasticsearch-host' => 'localhost',
65+
'elasticsearch-port' => '9200'
66+
];
67+
68+
$this->configWriterMock
69+
->expects($this->at(0))
70+
->method('save')
71+
->with('catalog/search/engine', 'elasticsearch5');
72+
$this->configWriterMock
73+
->expects($this->at(1))
74+
->method('save')
75+
->with('catalog/search/elasticsearch5_server_hostname', 'localhost');
76+
$this->configWriterMock
77+
->expects($this->at(2))
78+
->method('save')
79+
->with('catalog/search/elasticsearch5_server_port', '9200');
80+
81+
$this->validatorMock->expects($this->once())->method('validate')->with('elasticsearch5')->willReturn(true);
82+
83+
$this->installConfig->configure($inputOptions);
84+
}
85+
86+
/**
87+
* @expectedException \Magento\Framework\Exception\InputException
88+
* @expectedExceptionMessage Connection to Elasticsearch cannot be established.
89+
*/
90+
public function testConfigureValidateFail()
91+
{
92+
$inputOptions = [
93+
'search-engine' => 'elasticsearch5',
94+
'elasticsearch-host' => 'es.domain.com',
95+
'elasticsearch-port' => '9200'
96+
];
97+
98+
$this->configWriterMock
99+
->expects($this->at(0))
100+
->method('save')
101+
->with('catalog/search/engine', 'elasticsearch5');
102+
$this->configWriterMock
103+
->expects($this->at(1))
104+
->method('save')
105+
->with('catalog/search/elasticsearch5_server_hostname', 'es.domain.com');
106+
$this->configWriterMock
107+
->expects($this->at(2))
108+
->method('save')
109+
->with('catalog/search/elasticsearch5_server_port', '9200');
110+
111+
$this->validatorMock->expects($this->once())->method('validate')->with('elasticsearch5')->willReturn(false);
112+
113+
$this->installConfig->configure($inputOptions);
114+
}
115+
}

app/code/Magento/Elasticsearch/etc/di.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,4 +511,24 @@
511511
</argument>
512512
</arguments>
513513
</type>
514+
<type name="Magento\Elasticsearch\Setup\InstallConfig">
515+
<arguments>
516+
<argument name="searchConfigMapping" xsi:type="array">
517+
<item name="elasticsearch-host" xsi:type="string">elasticsearch5_server_hostname</item>
518+
<item name="elasticsearch-port" xsi:type="string">elasticsearch5_server_port</item>
519+
<item name="elasticsearch-timeout" xsi:type="string">elasticsearch5_server_timeout</item>
520+
<item name="elasticsearch-index-prefix" xsi:type="string">elasticsearch5_index_prefix</item>
521+
<item name="elasticsearch-enable-auth" xsi:type="string">elasticsearch5_enable_auth</item>
522+
<item name="elasticsearch-username" xsi:type="string">elasticsearch5_username</item>
523+
<item name="elasticsearch-password" xsi:type="string">elasticsearch5_password</item>
524+
</argument>
525+
</arguments>
526+
</type>
527+
<type name="Magento\Search\Setup\CompositeInstallConfig">
528+
<arguments>
529+
<argument name="installConfigList" xsi:type="array">
530+
<item name="elasticsearch5" xsi:type="object">Magento\Elasticsearch\Setup\InstallConfig</item>
531+
</argument>
532+
</arguments>
533+
</type>
514534
</config>

app/code/Magento/Elasticsearch6/etc/di.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,24 @@
219219
</argument>
220220
</arguments>
221221
</type>
222+
<virtualType name="Magento\Elasticsearch6\Setup\InstallConfig" type="Magento\Elasticsearch\Setup\InstallConfig">
223+
<arguments>
224+
<argument name="searchConfigMapping" xsi:type="array">
225+
<item name="elasticsearch-host" xsi:type="string">elasticsearch6_server_hostname</item>
226+
<item name="elasticsearch-port" xsi:type="string">elasticsearch6_server_port</item>
227+
<item name="elasticsearch-timeout" xsi:type="string">elasticsearch6_server_timeout</item>
228+
<item name="elasticsearch-index-prefix" xsi:type="string">elasticsearch6_index_prefix</item>
229+
<item name="elasticsearch-enable-auth" xsi:type="string">elasticsearch6_enable_auth</item>
230+
<item name="elasticsearch-username" xsi:type="string">elasticsearch6_username</item>
231+
<item name="elasticsearch-password" xsi:type="string">elasticsearch6_password</item>
232+
</argument>
233+
</arguments>
234+
</virtualType>
235+
<type name="Magento\Search\Setup\CompositeInstallConfig">
236+
<arguments>
237+
<argument name="installConfigList" xsi:type="array">
238+
<item name="elasticsearch6" xsi:type="object">Magento\Elasticsearch6\Setup\InstallConfig</item>
239+
</argument>
240+
</arguments>
241+
</type>
222242
</config>

app/code/Magento/Elasticsearch7/etc/di.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,25 @@
221221
</argument>
222222
</arguments>
223223
</type>
224+
225+
<virtualType name="Magento\Elasticsearch7\Setup\InstallConfig" type="Magento\Elasticsearch\Setup\InstallConfig">
226+
<arguments>
227+
<argument name="searchConfigMapping" xsi:type="array">
228+
<item name="elasticsearch-host" xsi:type="string">elasticsearch7_server_hostname</item>
229+
<item name="elasticsearch-port" xsi:type="string">elasticsearch7_server_port</item>
230+
<item name="elasticsearch-timeout" xsi:type="string">elasticsearch7_server_timeout</item>
231+
<item name="elasticsearch-index-prefix" xsi:type="string">elasticsearch7_index_prefix</item>
232+
<item name="elasticsearch-enable-auth" xsi:type="string">elasticsearch7_enable_auth</item>
233+
<item name="elasticsearch-username" xsi:type="string">elasticsearch7_username</item>
234+
<item name="elasticsearch-password" xsi:type="string">elasticsearch7_password</item>
235+
</argument>
236+
</arguments>
237+
</virtualType>
238+
<type name="Magento\Search\Setup\CompositeInstallConfig">
239+
<arguments>
240+
<argument name="installConfigList" xsi:type="array">
241+
<item name="elasticsearch7" xsi:type="object">Magento\Elasticsearch7\Setup\InstallConfig</item>
242+
</argument>
243+
</arguments>
244+
</type>
224245
</config>

0 commit comments

Comments
 (0)