diff --git a/src/module-elasticsuite-core/Api/Client/ClientConfigurationInterface.php b/src/module-elasticsuite-core/Api/Client/ClientConfigurationInterface.php index c6e2af3c8..31ab081ad 100644 --- a/src/module-elasticsuite-core/Api/Client/ClientConfigurationInterface.php +++ b/src/module-elasticsuite-core/Api/Client/ClientConfigurationInterface.php @@ -71,4 +71,11 @@ public function getHttpAuthUser(); * @return string */ public function getHttpAuthPassword(); + + /** + * Client config options. + * + * @return array + */ + public function getOptions(); } diff --git a/src/module-elasticsuite-core/Client/Client.php b/src/module-elasticsuite-core/Client/Client.php index 82d173f06..0c6d2f802 100644 --- a/src/module-elasticsuite-core/Client/Client.php +++ b/src/module-elasticsuite-core/Client/Client.php @@ -14,10 +14,8 @@ namespace Smile\ElasticsuiteCore\Client; -use Smile\ElasticsuiteCore\Api\Client\ClientInterface; use Smile\ElasticsuiteCore\Api\Client\ClientConfigurationInterface; -use Elasticsearch\ClientBuilder; -use Psr\Log\LoggerInterface; +use Smile\ElasticsuiteCore\Api\Client\ClientInterface; /** * ElasticSearch client implementation. @@ -38,19 +36,12 @@ class Client implements ClientInterface /** * Constructor. * - * @param ClientConfigurationInterfaceFactory $clientConfigurationFactory Client configuration factory. - * @param ClientBuilder $clientBuilder ES client builder. - * @param LoggerInterface $logger Logger. - * @param array $options Client options. + * @param ClientConfigurationInterface $clientConfiguration Client configuration factory. + * @param ClientBuilder $clientBuilder ES client builder. */ - public function __construct( - \Smile\ElasticsuiteCore\Client\ClientConfigurationFactory $clientConfigurationFactory, - ClientBuilder $clientBuilder, - LoggerInterface $logger, - $options = [] - ) { - $clientConfiguration = $clientConfigurationFactory->create(['options' => $options]); - $this->esClient = $this->createClient($clientConfiguration, $clientBuilder, $logger); + public function __construct(ClientConfigurationInterface $clientConfiguration, ClientBuilder $clientBuilder) + { + $this->esClient = $clientBuilder->build($clientConfiguration->getOptions()); } /** @@ -187,63 +178,4 @@ public function termvectors($params) { return $this->esClient->termvectors($params); } - - /** - * Create an ES Client form configuration. - * - * @param ClientConfigurationInterface $clientConfiguration Client configuration. - * @param ClientBuilder $clientBuilder ES client builder. - * @param LoggerInterface $logger Logger - * - * @return \Elasticsearch\Client - */ - private function createClient( - ClientConfigurationInterface $clientConfiguration, - ClientBuilder $clientBuilder, - LoggerInterface $logger - ) { - $hosts = $this->getHosts($clientConfiguration); - - if (!empty($hosts)) { - $clientBuilder->setHosts($hosts); - } - - if ($clientConfiguration->isDebugModeEnabled()) { - $clientBuilder->setLogger($logger); - } - - return $clientBuilder->build(); - } - - /** - * Return hosts config used to connect to the cluster. - * - * @param ClientConfigurationInterface $clientConfiguration Client configuration. - * - * @return array - */ - private function getHosts(ClientConfigurationInterface $clientConfiguration) - { - $hosts = []; - - foreach ($clientConfiguration->getServerList() as $host) { - if (!empty($host)) { - list($hostname, $port) = array_pad(explode(':', $host, 2), 2, 9200); - $currentHostConfig = [ - 'host' => $hostname, - 'port' => $port, - 'scheme' => $clientConfiguration->getScheme(), - ]; - - if ($clientConfiguration->isHttpAuthEnabled()) { - $currentHostConfig['user'] = $clientConfiguration->getHttpAuthUser(); - $currentHostConfig['pass'] = $clientConfiguration->getHttpAuthPassword(); - } - - $hosts[] = $currentHostConfig; - } - } - - return $hosts; - } } diff --git a/src/module-elasticsuite-core/Client/ClientBuilder.php b/src/module-elasticsuite-core/Client/ClientBuilder.php new file mode 100644 index 000000000..153a5be04 --- /dev/null +++ b/src/module-elasticsuite-core/Client/ClientBuilder.php @@ -0,0 +1,120 @@ + + * @copyright 2016 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteCore\Client; + +/** + * ElasticSearch client builder. + * + * @category Smile + * @package Smile\ElasticsuiteCore + * @author Aurelien FOUCRET + */ +class ClientBuilder +{ + /** + * @var \Elasticsearch\ClientBuilder + */ + private $clientBuilder; + + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + /** + * @var array + */ + private $defaultOptions = [ + 'servers' => 'localhost:9200', + 'enable_http_auth' => false, + 'http_auth_user' => null, + 'http_auth_pwd' => null, + 'is_debug_mode_enabled' => false, + ]; + + /** + * Constructor. + * + * @param \Elasticsearch\ClientBuilder $clientBuilder Client builder. + * @param \Psr\Log\LoggerInterface $logger Logger. + */ + public function __construct(\Elasticsearch\ClientBuilder $clientBuilder, \Psr\Log\LoggerInterface $logger) + { + $this->clientBuilder = $clientBuilder; + $this->logger = $logger; + } + + /** + * Build an ES client from options. + * + * @param array $options Client options. See self::defaultOptions for available options. + * + * @return \Elasticsearch\Client + */ + public function build($options = []) + { + $options = array_merge($this->defaultOptions, $options); + + $clientBuilder = $this->clientBuilder->create(); + + $hosts = $this->getHosts($options); + + if (!empty($hosts)) { + $clientBuilder->setHosts($hosts); + } + + if ($options['is_debug_mode_enabled']) { + $clientBuilder->setLogger($this->logger); + } + + return $clientBuilder->build(); + } + + /** + * Return hosts config used to connect to the cluster. + * + * @param array $options Client options. See self::defaultOptions for available options. + * + * @return array + */ + private function getHosts($options) + { + $hosts = []; + + if (is_string($options['servers'])) { + $options['servers'] = explode(',', $options['servers']); + } + + foreach ($options['servers'] as $host) { + if (!empty($host)) { + list($hostname, $port) = array_pad(explode(':', trim($host), 2), 2, 9200); + $currentHostConfig = [ + 'host' => $hostname, + 'port' => $port, + 'scheme' => isset($options['enable_https_mode']) ? 'https' : $options['scheme'] ?? 'http', + ]; + + if ($options['enable_http_auth']) { + $currentHostConfig['user'] = $options['http_auth_user']; + $currentHostConfig['pass'] = $options['http_auth_pwd']; + } + + $hosts[] = $currentHostConfig; + } + } + + return $hosts; + } +} diff --git a/src/module-elasticsuite-core/Client/ClientConfiguration.php b/src/module-elasticsuite-core/Client/ClientConfiguration.php index 455b9c7c9..8dc5babb6 100644 --- a/src/module-elasticsuite-core/Client/ClientConfiguration.php +++ b/src/module-elasticsuite-core/Client/ClientConfiguration.php @@ -32,11 +32,6 @@ class ClientConfiguration implements ClientConfigurationInterface */ const ES_CLIENT_CONFIG_XML_PREFIX = 'smile_elasticsuite_core_base_settings/es_client'; - /** - * @var array - */ - private $options; - /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ @@ -45,14 +40,10 @@ class ClientConfiguration implements ClientConfigurationInterface /** * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig Config. - * @param array $options Custom options. */ - public function __construct( - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - $options = [] - ) { + public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) + { $this->scopeConfig = $scopeConfig; - $this->options = $options; } /** @@ -113,6 +104,23 @@ public function getHttpAuthPassword() return (string) $this->getElasticsearchClientConfigParam('http_auth_pwd'); } + /** + * {@inheritDoc} + */ + public function getOptions() + { + $options = [ + 'servers' => $this->getServerList(), + 'scheme' => $this->getScheme(), + 'enable_http_auth' => $this->isHttpAuthEnabled(), + 'http_auth_user' => $this->getHttpAuthUser(), + 'http_auth_pwd' => $this->getHttpAuthPassword(), + 'is_debug_mode_enabled' => $this->isDebugModeEnabled(), + ]; + + return $options; + } + /** * Read config under the path smile_elasticsuite_core_base_settings/es_client. * @@ -124,6 +132,6 @@ private function getElasticsearchClientConfigParam($configField) { $path = self::ES_CLIENT_CONFIG_XML_PREFIX . '/' . $configField; - return $this->options[$configField] ?? $this->scopeConfig->getValue($path); + return $this->scopeConfig->getValue($path); } } diff --git a/src/module-elasticsuite-core/Setup/ConfigOptionsList.php b/src/module-elasticsuite-core/Setup/ConfigOptionsList.php index 563869056..485c407f7 100644 --- a/src/module-elasticsuite-core/Setup/ConfigOptionsList.php +++ b/src/module-elasticsuite-core/Setup/ConfigOptionsList.php @@ -50,18 +50,18 @@ class ConfigOptionsList implements ConfigOptionsListInterface const CONFIG_PATH_ES_PASS = self::CONF_PREFIX . '/http_auth_pwd'; /** - * @var ClientFactoryInterface + * @var \Smile\ElasticsuiteCore\Client\ClientBuilder */ - private $clientFactory; + private $clientBuilder; /** * Constructor. * - * @param \Smile\ElasticsuiteCore\Client\ClientFactory $clientFactory ES Client factory. + * @param \Smile\ElasticsuiteCore\Client\ClientBuilder $clientBuilder ES client builder. */ - public function __construct(\Smile\ElasticsuiteCore\Client\ClientFactory $clientFactory) + public function __construct(\Smile\ElasticsuiteCore\Client\ClientBuilder $clientBuilder) { - $this->clientFactory = $clientFactory; + $this->clientBuilder = $clientBuilder; } /** @@ -119,8 +119,8 @@ public function validate(array $options, DeploymentConfig $deploymentConfig) $errors = []; try { - $clientsOptions = array_filter($this->getClientOptions($options, $deploymentConfig)); - $this->clientFactory->create(['options' => $clientsOptions])->info(); + $options = array_filter($this->getClientOptions($options, $deploymentConfig)); + $this->clientBuilder->build($options)->info(); } catch (\Exception $e) { $errors[] = "Unable to connect ElasticSearch server : {$e->getMessage()}"; } @@ -129,6 +129,7 @@ public function validate(array $options, DeploymentConfig $deploymentConfig) } /** + * Read client options from CLI / env file. * * @param array $options Input options. * @param DeploymentConfig $deploymentConfig Deployment config.