Skip to content

Commit 1674453

Browse files
MAGECLOUD-3205: Provide ElasticsSuite auto-configuration (#439)
1 parent 6d9ef44 commit 1674453

File tree

23 files changed

+1297
-106
lines changed

23 files changed

+1297
-106
lines changed

dist/.magento.env.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,28 @@
262262
# elasticsearch_index_prefix: magento #
263263
# elasticsearch_server_timeout: '15' #
264264
#######################################################################################################################
265+
# ELASTICSUITE_CONFIGURATION - use this variable to retain customized ElasticSuite service settings #
266+
# between deployments. All configs provided in this configuration are nested in main ElasticSuite #
267+
# config section 'system/default/smile_elasticsuite_core_base_settings' #
268+
# Magento Version: 2.2.0 and later #
269+
# Default value: Depends on template configuration of ElasticSearch (i.e. default number of replicas and shards) #
270+
# and ElasticSearch host. #
271+
# es_client: #
272+
# servers: 'localhost:9200' #
273+
# indices_settings: #
274+
# number_of_shards: 1 #
275+
# number_of_replicas: 0 #
276+
# Stages: deploy #
277+
# Example: #
278+
# stage: #
279+
# deploy: #
280+
# ELASTICSUITE_CONFIGURATION: #
281+
# es_client: #
282+
# servers: 'remote-host:9200' #
283+
# indices_settings: #
284+
# number_of_shards: 3 #
285+
# number_of_replicas: 3 #
286+
#######################################################################################################################
265287
# CRON_CONSUMERS_RUNNER - use this variable to make sure message queues are running after a deployment. #
266288
# By default, the deployment process overwrites all settings in the env.php file #
267289
# cron_run — a boolean value that enables or disables the consumers_runner cron job. #

src/App/Container.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ function () {
244244
$this->container->make(ConfigValidator\Deploy\DatabaseConfiguration::class),
245245
$this->container->make(ConfigValidator\Deploy\ResourceConfiguration::class),
246246
$this->container->make(ConfigValidator\Deploy\SessionConfiguration::class),
247+
$this->container->make(ConfigValidator\Deploy\ElasticSuiteIntegrity::class),
247248
],
248249
ValidatorInterface::LEVEL_WARNING => [
249250
$this->container->make(ConfigValidator\Deploy\AdminData::class),

src/App/GenericException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,11 @@
1010
*/
1111
class GenericException extends \Exception
1212
{
13+
/**
14+
* @inheritDoc
15+
*/
16+
public function __construct(string $message, int $code = 0, \Throwable $previous = null)
17+
{
18+
parent::__construct($message, $code, $previous);
19+
}
1320
}

src/Config/Schema.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,16 @@ public function getSchema()
351351
StageConfigInterface::STAGE_DEPLOY => [],
352352
],
353353
],
354+
DeployInterface::VAR_ELASTICSUITE_CONFIGURATION => [
355+
self::SCHEMA_TYPE => ['array'],
356+
self::SCHEMA_STAGE => [
357+
StageConfigInterface::STAGE_GLOBAL,
358+
StageConfigInterface::STAGE_DEPLOY
359+
],
360+
self::SCHEMA_DEFAULT_VALUE => [
361+
StageConfigInterface::STAGE_DEPLOY => [],
362+
],
363+
],
354364
DeployInterface::VAR_QUEUE_CONFIGURATION => [
355365
self::SCHEMA_TYPE => ['array'],
356366
self::SCHEMA_STAGE => [

src/Config/Stage/DeployInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface DeployInterface extends StageConfigInterface
1414
{
1515
const VAR_QUEUE_CONFIGURATION = 'QUEUE_CONFIGURATION';
1616
const VAR_SEARCH_CONFIGURATION = 'SEARCH_CONFIGURATION';
17+
const VAR_ELASTICSUITE_CONFIGURATION = 'ELASTICSUITE_CONFIGURATION';
1718
const VAR_CACHE_CONFIGURATION = 'CACHE_CONFIGURATION';
1819
const VAR_SESSION_CONFIGURATION = 'SESSION_CONFIGURATION';
1920
const VAR_DATABASE_CONFIGURATION = 'DATABASE_CONFIGURATION';

src/Config/Validator/Deploy/ElasticSearchUsage.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\MagentoCloud\Config\Validator;
1010
use Magento\MagentoCloud\Config\ValidatorInterface;
1111
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\Config as SearchEngineConfig;
12+
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\ElasticSuite;
1213

1314
/**
1415
* Validates that different search engine configured when elasticsearch service is installed.
@@ -47,7 +48,8 @@ public function __construct(
4748

4849
/**
4950
* Returns success when elasticsearch service not exist.
50-
* Returns success when elasticsearch service exist and search engine configured as elasticsearch.
51+
* Returns success when elasticsearch service exist and search engine
52+
* configured as elasticsearch or elasticsuite.
5153
* Otherwise returns error.
5254
*
5355
* @return Validator\ResultInterface
@@ -60,7 +62,10 @@ public function validate(): Validator\ResultInterface
6062
}
6163

6264
$searchEngine = $this->searchEngineConfig->get()['engine'];
63-
if (strpos($searchEngine, 'elasticsearch') === 0) {
65+
$isElasticSearchInstalled = strpos($searchEngine, 'elasticsearch') === 0
66+
|| $searchEngine === ElasticSuite::ENGINE_NAME;
67+
68+
if ($isElasticSearchInstalled) {
6469
return $this->resultFactory->success();
6570
}
6671

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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\MagentoCloud\Config\Validator\Deploy;
9+
10+
use Magento\MagentoCloud\Config\Stage\DeployInterface;
11+
use Magento\MagentoCloud\Config\Validator;
12+
use Magento\MagentoCloud\Config\ValidatorInterface;
13+
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\ElasticSearch;
14+
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\ElasticSuite;
15+
16+
/**
17+
* Validates different aspects of ElasticSuite's configuration.
18+
*/
19+
class ElasticSuiteIntegrity implements ValidatorInterface
20+
{
21+
/**
22+
* @var ElasticSuite
23+
*/
24+
private $elasticSuite;
25+
26+
/**
27+
* @var ElasticSearch
28+
*/
29+
private $elasticSearch;
30+
31+
/**
32+
* @var Validator\ResultFactory
33+
*/
34+
private $resultFactory;
35+
36+
/**
37+
* @var DeployInterface
38+
*/
39+
private $config;
40+
41+
/**
42+
* @param ElasticSuite $elasticSuite
43+
* @param ElasticSearch $elasticSearch
44+
* @param Validator\ResultFactory $resultFactory
45+
* @param DeployInterface $config
46+
*/
47+
public function __construct(
48+
ElasticSuite $elasticSuite,
49+
ElasticSearch $elasticSearch,
50+
Validator\ResultFactory $resultFactory,
51+
DeployInterface $config
52+
) {
53+
$this->elasticSuite = $elasticSuite;
54+
$this->elasticSearch = $elasticSearch;
55+
$this->resultFactory = $resultFactory;
56+
$this->config = $config;
57+
}
58+
59+
/**
60+
* If ElasticSuite is absent - skip validation.
61+
* If ElasticSuite is present and no ElasticSearch connection - fail validation.
62+
* If search engine is manually set to non-ElasticSuite it will fail after deploy - fail validation.
63+
*
64+
* Otherwise - validation is successful.
65+
*
66+
* @return Validator\ResultInterface
67+
*/
68+
public function validate(): Validator\ResultInterface
69+
{
70+
if (!$this->elasticSuite->isInstalled()) {
71+
return $this->resultFactory->success();
72+
}
73+
74+
if (!$this->elasticSearch->isInstalled()) {
75+
return $this->resultFactory->error('ElasticSuite is installed without available ElasticSearch service.');
76+
}
77+
78+
$engine = $this->config->get(DeployInterface::VAR_SEARCH_CONFIGURATION)['engine'] ?? null;
79+
80+
if ($engine && strtolower($engine) !== ElasticSuite::ENGINE_NAME) {
81+
return $this->resultFactory->error(sprintf(
82+
'ElasticSuite is installed but %s set as search engine.',
83+
$engine
84+
));
85+
}
86+
87+
return $this->resultFactory->success();
88+
}
89+
}

src/Process/Deploy/InstallUpdate/ConfigUpdate/SearchEngine.php

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
*/
66
namespace Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate;
77

8+
use Magento\MagentoCloud\App\GenericException;
89
use Magento\MagentoCloud\Config\Deploy\Writer as EnvWriter;
9-
use Magento\MagentoCloud\Config\Deploy\Reader as EnvReader;
1010
use Magento\MagentoCloud\Config\Shared\Writer as SharedWriter;
11-
use Magento\MagentoCloud\Config\Shared\Reader as SharedReader;
1211
use Magento\MagentoCloud\Package\MagentoVersion;
1312
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\Config as SearchEngineConfig;
13+
use Magento\MagentoCloud\Process\Deploy\InstallUpdate\ConfigUpdate\SearchEngine\ElasticSuite;
14+
use Magento\MagentoCloud\Process\ProcessException;
1415
use Magento\MagentoCloud\Process\ProcessInterface;
1516
use Psr\Log\LoggerInterface;
1617

@@ -29,21 +30,11 @@ class SearchEngine implements ProcessInterface
2930
*/
3031
private $envWriter;
3132

32-
/**
33-
* @var EnvReader;
34-
*/
35-
private $envReader;
36-
3733
/**
3834
* @var SharedWriter
3935
*/
4036
private $sharedWriter;
4137

42-
/**
43-
* @var SharedReader
44-
*/
45-
private $sharedReader;
46-
4738
/**
4839
* @var MagentoVersion
4940
*/
@@ -56,57 +47,69 @@ class SearchEngine implements ProcessInterface
5647
*/
5748
private $searchEngineConfig;
5849

50+
/**
51+
* @var ElasticSuite
52+
*/
53+
private $elasticSuite;
54+
5955
/**
6056
* @param LoggerInterface $logger
6157
* @param EnvWriter $envWriter
62-
* @param EnvReader $envReader
6358
* @param SharedWriter $sharedWriter
64-
* @param SharedReader $sharedReader
6559
* @param MagentoVersion $version
6660
* @param SearchEngineConfig $searchEngineConfig
61+
* @param ElasticSuite $elasticSuite
6762
*/
6863
public function __construct(
6964
LoggerInterface $logger,
7065
EnvWriter $envWriter,
71-
EnvReader $envReader,
7266
SharedWriter $sharedWriter,
73-
SharedReader $sharedReader,
7467
MagentoVersion $version,
75-
SearchEngineConfig $searchEngineConfig
68+
SearchEngineConfig $searchEngineConfig,
69+
ElasticSuite $elasticSuite
7670
) {
7771
$this->logger = $logger;
7872
$this->envWriter = $envWriter;
79-
$this->envReader = $envReader;
8073
$this->sharedWriter = $sharedWriter;
81-
$this->sharedReader = $sharedReader;
8274
$this->magentoVersion = $version;
8375
$this->searchEngineConfig = $searchEngineConfig;
76+
$this->elasticSuite = $elasticSuite;
8477
}
8578

8679
/**
8780
* Executes the process.
8881
*
8982
* @return void
83+
* @throws ProcessException
9084
*/
9185
public function execute()
9286
{
93-
$this->logger->info('Updating search engine configuration.');
94-
9587
$searchConfig = $this->searchEngineConfig->get();
9688

89+
$this->logger->info('Updating search engine configuration.');
9790
$this->logger->info('Set search engine to: ' . $searchConfig['engine']);
9891

99-
// 2.1.x requires search config to be written to the shared config file: MAGECLOUD-1317
100-
if (!$this->magentoVersion->isGreaterOrEqual('2.2')) {
101-
$config = $this->sharedReader->read();
102-
$config['system']['default']['catalog']['search'] = $searchConfig;
103-
$this->sharedWriter->create($config);
92+
$config['system']['default']['catalog']['search'] = $searchConfig;
93+
94+
if ($this->elasticSuite->isAvailable()) {
95+
$this->logger->info('Configuring ElasticSuite');
10496

105-
return;
97+
$config['system']['default']['smile_elasticsuite_core_base_settings'] = $this->elasticSuite->get();
98+
} elseif ($this->elasticSuite->isInstalled()) {
99+
$this->logger->warning('ElasticSuite is installed without ElasticSearch');
106100
}
107101

108-
$config = $this->envReader->read();
109-
$config['system']['default']['catalog']['search'] = $searchConfig;
110-
$this->envWriter->create($config);
102+
try {
103+
$isMagento21 = $this->magentoVersion->satisfies('2.1.*');
104+
105+
// 2.1.x requires search config to be written to the shared config file: MAGECLOUD-1317
106+
if ($isMagento21) {
107+
$this->sharedWriter->update($config);
108+
} else {
109+
$this->envWriter->update($config);
110+
}
111+
} catch (GenericException $exception) {
112+
throw new ProcessException($exception->getMessage(), $exception->getCode(), $exception);
113+
}
111114
}
112115
}

src/Process/Deploy/InstallUpdate/ConfigUpdate/SearchEngine/Config.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,31 @@ class Config
4141
*/
4242
private $configMerger;
4343

44+
/**
45+
* @var ElasticSuite
46+
*/
47+
private $elasticSuite;
48+
4449
/**
4550
* @param Environment $environment
4651
* @param DeployInterface $stageConfig
4752
* @param ElasticSearch $elasticSearch
53+
* @param ElasticSuite $elasticSuite
4854
* @param MagentoVersion $version
4955
* @param ConfigMerger $configMerger
5056
*/
5157
public function __construct(
5258
Environment $environment,
5359
DeployInterface $stageConfig,
5460
ElasticSearch $elasticSearch,
61+
ElasticSuite $elasticSuite,
5562
MagentoVersion $version,
5663
ConfigMerger $configMerger
5764
) {
5865
$this->environment = $environment;
5966
$this->stageConfig = $stageConfig;
6067
$this->elasticSearch = $elasticSearch;
68+
$this->elasticSuite = $elasticSuite;
6169
$this->magentoVersion = $version;
6270
$this->configMerger = $configMerger;
6371
}
@@ -83,7 +91,7 @@ public function get(): array
8391
/**
8492
* @return array
8593
*/
86-
private function getSearchConfig()
94+
private function getSearchConfig(): array
8795
{
8896
$relationships = $this->environment->getRelationships();
8997
$searchConfig = ['engine' => 'mysql'];
@@ -103,7 +111,7 @@ private function getSearchConfig()
103111
* @param array $config Solr connection configuration
104112
* @return array
105113
*/
106-
private function getSolrConfiguration(array $config)
114+
private function getSolrConfiguration(array $config): array
107115
{
108116
return [
109117
'engine' => 'solr',
@@ -120,7 +128,7 @@ private function getSolrConfiguration(array $config)
120128
* @param array $config Elasticsearch connection configuration
121129
* @return array
122130
*/
123-
private function getElasticSearchConfiguration(array $config)
131+
private function getElasticSearchConfiguration(array $config): array
124132
{
125133
$engine = 'elasticsearch';
126134

@@ -139,6 +147,10 @@ private function getElasticSearchConfiguration(array $config)
139147
$elasticSearchConfig["{$engine}_index_prefix"] = $config['query']['index'];
140148
}
141149

150+
if ($this->elasticSuite->isInstalled()) {
151+
$elasticSearchConfig['engine'] = ElasticSuite::ENGINE_NAME;
152+
}
153+
142154
return $elasticSearchConfig;
143155
}
144156

0 commit comments

Comments
 (0)