diff --git a/src/module-elasticsuite-core/Model/System/Message/GenericWarningAboutClusterMisconfig.php b/src/module-elasticsuite-core/Model/System/Message/GenericWarningAboutClusterMisconfig.php
index b3d9bbc7f..a164d456c 100644
--- a/src/module-elasticsuite-core/Model/System/Message/GenericWarningAboutClusterMisconfig.php
+++ b/src/module-elasticsuite-core/Model/System/Message/GenericWarningAboutClusterMisconfig.php
@@ -1 +1,123 @@
+ * @copyright 2024 Smile
+ * @license Open Software License ("OSL") v. 3.0
+ */
+
+namespace Smile\ElasticsuiteCore\Model\System\Message;
+
+use Magento\Framework\UrlInterface;
+use Magento\Framework\Notification\MessageInterface;
+use Smile\ElasticsuiteCore\Healthcheck\HealthcheckList;
+
+/**
+ * Class GenericWarningAboutClusterMisconfig
+ */
+class GenericWarningAboutClusterMisconfig implements MessageInterface
+{
+ /**
+ * Route to Elasticsuite -> Healthcheck page.
+ */
+ private const ROUTE_ELASTICSUITE_HEALTHCHECK = 'smile_elasticsuite/healthcheck/index';
+
+ /**
+ * @var HealthcheckList
+ */
+ private $healthcheckList;
+
+ /**
+ * @var UrlInterface
+ */
+ private $urlBuilder;
+
+ public const WARNING_STATUS = 'warning';
+
+ /**
+ * Constructor.
+ *
+ * @param HealthcheckList $healthcheckList Health check list object.
+ * @param UrlInterface $urlBuilder URL builder.
+ */
+ public function __construct(
+ HealthcheckList $healthcheckList,
+ UrlInterface $urlBuilder
+ ) {
+ $this->healthcheckList = $healthcheckList;
+ $this->urlBuilder = $urlBuilder;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDisplayed()
+ {
+ return $this->getIssueCount() > 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIdentity()
+ {
+ return hash('sha256', 'ELASTICSUITE_GENERIC_WARNING');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSeverity()
+ {
+ return self::SEVERITY_MAJOR;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getText()
+ {
+ $issuesCount = $this->getIssueCount();
+
+ return __(
+ 'You have %1 health checks in a warning state. '
+ . 'Please head to the Elasticsuite Healthcheck page to get more details and see how to fix them.',
+ $issuesCount,
+ $this->getElasticsuiteHealthcheckUrl()
+ );
+ }
+
+ /**
+ * Counts the number of health check issues in an error state.
+ *
+ * @return int
+ */
+ private function getIssueCount(): int
+ {
+ $issuesCount = 0;
+
+ foreach ($this->healthcheckList->getChecks() as $check) {
+ if ($check->getStatus() === self::WARNING_STATUS) {
+ $issuesCount++;
+ }
+ }
+
+ return $issuesCount;
+ }
+
+ /**
+ * Retrieve a URL to the Elasticsuite Healthcheck page for more information.
+ *
+ * @return string
+ */
+ private function getElasticsuiteHealthcheckUrl(): string
+ {
+ return $this->urlBuilder->getUrl(self::ROUTE_ELASTICSUITE_HEALTHCHECK);
+ }
+}
diff --git a/src/module-elasticsuite-core/Model/System/Message/WarningAboutClusterReplicasMisconfig.php b/src/module-elasticsuite-core/Model/System/Message/WarningAboutClusterReplicasMisconfig.php
deleted file mode 100644
index d4510a9cb..000000000
--- a/src/module-elasticsuite-core/Model/System/Message/WarningAboutClusterReplicasMisconfig.php
+++ /dev/null
@@ -1,158 +0,0 @@
-
- * @copyright 2022 Smile
- * @license Open Software License ("OSL") v. 3.0
- */
-
-namespace Smile\ElasticsuiteCore\Model\System\Message;
-
-use Magento\Framework\Notification\MessageInterface;
-use Magento\Framework\UrlInterface;
-use Smile\ElasticsuiteCore\Helper\IndexSettings as IndexSettingsHelper;
-use Smile\ElasticsuiteCore\Client\Client;
-
-/**
- * ElasticSuite Warning about Cluster mis-configuration for replicas
- *
- * @category Smile
- * @package Smile\ElasticsuiteCore
- * @author Vadym Honcharuk
- */
-class WarningAboutClusterReplicasMisconfig implements MessageInterface
-{
- /**
- * Route to Stores -> Configuration section
- */
- private const ROUTE_SYSTEM_CONFIG = 'adminhtml/system_config/edit';
-
- /**
- * Anchor for Stores -> Configuration -> ELASTICSUITE -> Base Settings -> Indices Settings
- */
- private const ANCHOR_ES_INDICES_SETTINGS_PATH = 'smile_elasticsuite_core_base_settings_indices_settings-link';
-
- /**
- * URL for Elasticsuite Indices Settings wiki page
- */
- private const ES_INDICES_SETTINGS_WIKI_PAGE = 'https://github.com/Smile-SA/elasticsuite/wiki/ModuleInstall#indices-settings';
-
- /**
- * @var IndexSettingsHelper
- */
- protected $helper;
-
- /**
- * @var Client
- */
- protected $client;
-
- /**
- * @var UrlInterface
- */
- private $urlBuilder;
-
- /**
- * @param IndexSettingsHelper $indexSettingHelper Index settings helper
- * @param Client $client ElasticSearch client
- * @param UrlInterface $urlBuilder Url builder
- */
- public function __construct(
- IndexSettingsHelper $indexSettingHelper,
- Client $client,
- UrlInterface $urlBuilder
- ) {
- $this->helper = $indexSettingHelper;
- $this->client = $client;
- $this->urlBuilder = $urlBuilder;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isDisplayed()
- {
- if ($this->helper->getNumberOfReplicas() > 1) {
- /* numberOfReplicas should be <= numberOfNodes - 1 */
- if ($this->helper->getNumberOfReplicas() <= $this->getNumberOfNodes() - 1) {
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIdentity()
- {
- return hash('sha256', 'ELASTICSUITE_REPLICAS_WARNING');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSeverity()
- {
- return self::SEVERITY_MAJOR;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getText()
- {
- $messageDetails = '';
-
- // @codingStandardsIgnoreStart
- $messageDetails .= __(
- 'The number of replicas configured for Elasticsuite is incorrect. You cannot use %1 replicas since there is only %2 nodes in your Elasticsearch cluster.',
- $this->helper->getNumberOfReplicas(),
- $this->getNumberOfNodes()
- ) . '
';
- $messageDetails .= __(
- 'Click here to go to the Elasticsuite Config page and change your Number of Replicas per Index parameter according to our wiki page.',
- $this->getElasticsuiteConfigUrl(),
- self::ES_INDICES_SETTINGS_WIKI_PAGE
- );
- // @codingStandardsIgnoreEnd
-
- return $messageDetails;
- }
-
- /**
- * Get number of nodes from ElasticSearch client
- *
- * @return int
- */
- public function getNumberOfNodes()
- {
- if (is_array($this->client->nodes()->info()['_nodes'])
- && array_key_exists('total', $this->client->nodes()->info()['_nodes'])) {
- return (int) $this->client->nodes()->info()['_nodes']['total'];
- }
-
- return 0;
- }
-
- /**
- * Get URL to the admin Elasticsuite Configuration page
- *
- * @return string
- */
- private function getElasticsuiteConfigUrl()
- {
- return $this->urlBuilder->getUrl(
- self::ROUTE_SYSTEM_CONFIG,
- ['section' => 'smile_elasticsuite_core_base_settings', '_fragment' => self::ANCHOR_ES_INDICES_SETTINGS_PATH]
- );
- }
-}
diff --git a/src/module-elasticsuite-core/etc/adminhtml/di.xml b/src/module-elasticsuite-core/etc/adminhtml/di.xml
index 39d308f7e..3d28f5a80 100644
--- a/src/module-elasticsuite-core/etc/adminhtml/di.xml
+++ b/src/module-elasticsuite-core/etc/adminhtml/di.xml
@@ -22,7 +22,19 @@
- Smile\ElasticsuiteCore\Model\System\Message\NotificationAboutVersions
- - Smile\ElasticsuiteCore\Model\System\Message\WarningAboutClusterReplicasMisconfig
+
+ - Smile\ElasticsuiteCore\Model\System\Message\GenericWarningAboutClusterMisconfig
+
+
+
+
+
+
+
+
+ - Smile\ElasticsuiteCore\Healthcheck\GhostIndicesCheck
+ - Smile\ElasticsuiteCore\Healthcheck\ShardsConfigCheck
+ - Smile\ElasticsuiteCore\Healthcheck\ReplicasConfigCheck
diff --git a/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterGhostIndices.php b/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterGhostIndices.php
deleted file mode 100644
index 27de23dc7..000000000
--- a/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterGhostIndices.php
+++ /dev/null
@@ -1,150 +0,0 @@
-
- * @copyright 2022 Smile
- * @license Open Software License ("OSL") v. 3.0
- */
-
-namespace Smile\ElasticsuiteIndices\Model\System\Message;
-
-use Magento\Framework\Notification\MessageInterface;
-use Magento\Framework\UrlInterface;
-use Smile\ElasticsuiteIndices\Model\IndexStatsProvider;
-
-/**
- * ElasticSuite Warning about too much ghost indices in the cluster
- *
- * @category Smile
- * @package Smile\ElasticsuiteIndices
- * @author Vadym Honcharuk
- */
-class WarningAboutClusterGhostIndices implements MessageInterface
-{
- /**
- * Route to Elasticsuite -> Indices page
- */
- private const ROUTE_ELASTICSUITE_INDICES = 'smile_elasticsuite_indices';
-
- public const GHOST_STATUS = 'ghost';
-
- /**
- * @var IndexStatsProvider
- */
- protected $indexStatsProvider;
-
- /**
- * @var UrlInterface
- */
- private $urlBuilder;
-
- /**
- * @param IndexStatsProvider $indexStatsProvider Index stats provider
- * @param UrlInterface $urlBuilder Url builder
- */
- public function __construct(
- IndexStatsProvider $indexStatsProvider,
- UrlInterface $urlBuilder
- ) {
- $this->indexStatsProvider = $indexStatsProvider;
- $this->urlBuilder = $urlBuilder;
- }
-
- /**
- * {@inheritdoc}
- * @throws \Exception
- */
- public function isDisplayed()
- {
- if ($this->getNumberOfGhostIndices() && $this->getNumberOfGhostIndices() > 1) {
- return true;
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIdentity()
- {
- return hash('sha256', 'ELASTICSUITE_GHOST_INDICES_WARNING');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSeverity()
- {
- return self::SEVERITY_MAJOR;
- }
-
- /**
- * {@inheritdoc}
- * @throws \Exception
- */
- public function getText()
- {
- $messageDetails = '';
-
- // @codingStandardsIgnoreStart
- $messageDetails .= __(
- 'You have %1 ghost indices. Ghost indices have a footprint on your Elasticsearch cluster health. You should consider removing them.',
- $this->getNumberOfGhostIndices()
- ) . '
';
- $messageDetails .= __(
- 'Click here to go to the Elasticsuite Indices page to take appropriate actions.',
- $this->getElasticsuiteIndicesUrl()
- );
- // @codingStandardsIgnoreEnd
-
- return $messageDetails;
- }
-
- /**
- * Get number of the Ghost Elasticsuite Indices
- *
- * @return mixed
- * @throws \Exception
- */
- private function getNumberOfGhostIndices()
- {
- if ($this->indexStatsProvider->getElasticSuiteIndices() !== null) {
- $elasticsuiteIndices = $this->indexStatsProvider->getElasticSuiteIndices();
- $ghostIndices = [];
-
- foreach ($elasticsuiteIndices as $indexName => $indexAlias) {
- $indexData = $this->indexStatsProvider->indexStats($indexName, $indexAlias);
-
- if (array_key_exists('index_status', $indexData)
- && $indexData['index_status'] === self::GHOST_STATUS) {
- $ghostIndices[] = [
- 'index_name' => $indexData['index_name'],
- 'index_status' => $indexData['index_status'],
- ];
- }
- }
-
- if (!empty($ghostIndices)) {
- return count($ghostIndices);
- }
- }
-
- return false;
- }
-
- /**
- * Get URL to the admin Elasticsuite Indices Status page
- *
- * @return string
- */
- private function getElasticsuiteIndicesUrl()
- {
- return $this->urlBuilder->getUrl(self::ROUTE_ELASTICSUITE_INDICES);
- }
-}
diff --git a/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterShardsMisconfig.php b/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterShardsMisconfig.php
deleted file mode 100644
index 6ddefbc4b..000000000
--- a/src/module-elasticsuite-indices/Model/System/Message/WarningAboutClusterShardsMisconfig.php
+++ /dev/null
@@ -1,184 +0,0 @@
-
- * @copyright 2022 Smile
- * @license Open Software License ("OSL") v. 3.0
- */
-
-namespace Smile\ElasticsuiteIndices\Model\System\Message;
-
-use Magento\Framework\Notification\MessageInterface;
-use Magento\Framework\UrlInterface;
-use Smile\ElasticsuiteCore\Helper\IndexSettings as IndexSettingsHelper;
-use Smile\ElasticsuiteIndices\Model\IndexStatsProvider;
-
-/**
- * ElasticSuite Warning about Cluster mis-configuration for shards
- *
- * @category Smile
- * @package Smile\ElasticsuiteIndices
- * @author Vadym Honcharuk
- *
- * @SuppressWarnings(PHPMD.LongVariable)
- */
-class WarningAboutClusterShardsMisconfig implements MessageInterface
-{
- /**
- * Route to Stores -> Configuration section
- */
- private const ROUTE_SYSTEM_CONFIG = 'adminhtml/system_config/edit';
-
- /**
- * Anchor for Stores -> Configuration -> ELASTICSUITE -> Base Settings -> Indices Settings
- */
- private const ANCHOR_ES_INDICES_SETTINGS_PATH = 'smile_elasticsuite_core_base_settings_indices_settings-link';
-
- /**
- * URL for Elasticsuite Indices Settings wiki page
- */
- private const ES_INDICES_SETTINGS_WIKI_PAGE = 'https://github.com/Smile-SA/elasticsuite/wiki/ModuleInstall#indices-settings';
-
- public const UNDEFINED_SIZE = 'undefined';
-
- /**
- * @var IndexSettingsHelper
- */
- protected $helper;
-
- /**
- * @var IndexStatsProvider
- */
- protected $indexStatsProvider;
-
- /**
- * @var UrlInterface
- */
- private $urlBuilder;
-
- /**
- * @param IndexSettingsHelper $indexSettingHelper Index settings helper
- * @param IndexStatsProvider $indexStatsProvider Index stats provider
- * @param UrlInterface $urlBuilder Url builder
- */
- public function __construct(
- IndexSettingsHelper $indexSettingHelper,
- IndexStatsProvider $indexStatsProvider,
- UrlInterface $urlBuilder
- ) {
- $this->helper = $indexSettingHelper;
- $this->indexStatsProvider = $indexStatsProvider;
- $this->urlBuilder = $urlBuilder;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isDisplayed()
- {
- $numberOfShards = $this->helper->getNumberOfShards();
-
- if ($numberOfShards > 1) {
- if ($this->getElasticsuiteIndexMaxSize()) {
- $indexMaxSize = $this->getElasticsuiteIndexMaxSize()['size_in_bytes'];
-
- /* 10 Gb => 10737418240 bytes (in binary) */
- if ($indexMaxSize < '10737418240') {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIdentity()
- {
- return hash('sha256', 'ELASTICSUITE_SHARDS_WARNING');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSeverity()
- {
- return self::SEVERITY_MAJOR;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getText()
- {
- $messageDetails = '';
-
- // @codingStandardsIgnoreStart
- $messageDetails .= __('The number of shards configured for Elasticsuite is incorrect.') . ' ';
- $messageDetails .= __(
- 'You do not need to use %1 shards since your biggest Elasticsuite index is only %2.',
- $this->helper->getNumberOfShards(),
- $this->getElasticsuiteIndexMaxSize()['human_size']
- ) . '
';
- $messageDetails .= __(
- 'Click here to go to the Elasticsuite Config page and change your Number of Shards per Index parameter according to our wiki page.',
- $this->getElasticsuiteConfigUrl(),
- self::ES_INDICES_SETTINGS_WIKI_PAGE
- );
- // @codingStandardsIgnoreEnd
-
- return $messageDetails;
- }
-
- /**
- * Get size of the biggest Elasticsuite Indices
- *
- * @return mixed
- * @throws \Exception
- */
- private function getElasticsuiteIndexMaxSize()
- {
- if ($this->indexStatsProvider->getElasticSuiteIndices() !== null) {
- $elasticsuiteIndices = $this->indexStatsProvider->getElasticSuiteIndices();
- $indexSizes = [];
-
- foreach ($elasticsuiteIndices as $indexName => $indexAlias) {
- $indexData = $this->indexStatsProvider->indexStats($indexName, $indexAlias);
-
- if (array_key_exists('size', $indexData) && array_key_exists('size_in_bytes', $indexData)
- && $indexData['size_in_bytes'] !== self::UNDEFINED_SIZE) {
- $indexSizes[] = ['human_size' => $indexData['size'], 'size_in_bytes' => $indexData['size_in_bytes']];
- }
- }
-
- if (!empty($indexSizes)) {
- $indexSizesInBytes = array_column($indexSizes, "size_in_bytes");
- array_multisort($indexSizesInBytes, SORT_DESC, $indexSizes);
-
- return current($indexSizes);
- }
- }
-
- return false;
- }
-
- /**
- * Get URL to the admin Elasticsuite Configuration page
- *
- * @return string
- */
- private function getElasticsuiteConfigUrl()
- {
- return $this->urlBuilder->getUrl(
- self::ROUTE_SYSTEM_CONFIG,
- ['section' => 'smile_elasticsuite_core_base_settings', '_fragment' => self::ANCHOR_ES_INDICES_SETTINGS_PATH]
- );
- }
-}
diff --git a/src/module-elasticsuite-indices/etc/adminhtml/di.xml b/src/module-elasticsuite-indices/etc/adminhtml/di.xml
deleted file mode 100644
index 50ff740a8..000000000
--- a/src/module-elasticsuite-indices/etc/adminhtml/di.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
- - Smile\ElasticsuiteIndices\Model\System\Message\WarningAboutClusterShardsMisconfig
- - Smile\ElasticsuiteIndices\Model\System\Message\WarningAboutClusterGhostIndices
-
-
-
-
-