1<?php
2
3namespace Elastica;
4
5use Elastica\Exception\ClientException;
6use Elastica\Exception\ConnectionException;
7use Elastica\Exception\ResponseException;
8use Elasticsearch\Endpoints\Indices\Alias\Get;
9use Elasticsearch\Endpoints\Indices\GetAlias;
10use Elasticsearch\Endpoints\Indices\Stats;
11
12/**
13 * Elastica general status.
14 *
15 * @author Nicolas Ruflin <spam@ruflin.com>
16 *
17 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html
18 */
19class Status
20{
21    /**
22     * Contains all status infos.
23     *
24     * @var Response
25     */
26    protected $_response;
27
28    /**
29     * Data.
30     *
31     * @var array<string, mixed> Data
32     */
33    protected $_data;
34
35    /**
36     * @var Client
37     */
38    protected $_client;
39
40    public function __construct(Client $client)
41    {
42        $this->_client = $client;
43    }
44
45    /**
46     * Returns status data.
47     *
48     * @return array<string, mixed> Status data
49     */
50    public function getData()
51    {
52        if (null === $this->_data) {
53            $this->refresh();
54        }
55
56        return $this->_data;
57    }
58
59    /**
60     * Returns a list of the existing index names.
61     *
62     * @return string[]
63     */
64    public function getIndexNames()
65    {
66        $data = $this->getData();
67
68        return \array_map(static function ($name): string {
69            return (string) $name;
70        }, \array_keys($data['indices']));
71    }
72
73    /**
74     * Checks if the given index exists.
75     *
76     * @return bool True if index exists
77     */
78    public function indexExists(string $name)
79    {
80        return \in_array($name, $this->getIndexNames(), true);
81    }
82
83    /**
84     * Checks if the given alias exists.
85     *
86     * @return bool True if alias exists
87     */
88    public function aliasExists(string $name)
89    {
90        return \count($this->getIndicesWithAlias($name)) > 0;
91    }
92
93    /**
94     * Returns an array with all indices that the given alias name points to.
95     *
96     * @throws ClientException
97     * @throws ConnectionException
98     * @throws ResponseException
99     *
100     * @return Index[]
101     */
102    public function getIndicesWithAlias(string $alias)
103    {
104        // TODO: Use only GetAlias when dropping support for elasticsearch/elasticsearch 7.x
105        $endpoint = \class_exists(GetAlias::class) ? new GetAlias() : new Get();
106        $endpoint->setName($alias);
107
108        $response = null;
109
110        try {
111            $response = $this->_client->requestEndpoint($endpoint);
112        } catch (ResponseException $e) {
113            // 404 means the index alias doesn't exist which means no indexes have it.
114            if (404 === $e->getResponse()->getStatus()) {
115                return [];
116            }
117            // If we don't have a 404 then this is still unexpected so rethrow the exception.
118            throw $e;
119        }
120        $indices = [];
121        foreach ($response->getData() as $name => $unused) {
122            $indices[] = new Index($this->_client, $name);
123        }
124
125        return $indices;
126    }
127
128    /**
129     * Returns response object.
130     *
131     * @return Response Response object
132     */
133    public function getResponse()
134    {
135        if (null === $this->_response) {
136            $this->refresh();
137        }
138
139        return $this->_response;
140    }
141
142    /**
143     * Return shards info.
144     *
145     * @return array<string, mixed> Shards info
146     */
147    public function getShards()
148    {
149        $data = $this->getData();
150
151        return $data['shards'];
152    }
153
154    /**
155     * Refresh status object.
156     *
157     * @throws ClientException
158     * @throws ConnectionException
159     * @throws ResponseException
160     */
161    public function refresh(): void
162    {
163        $this->_response = $this->_client->requestEndpoint(new Stats());
164        $this->_data = $this->getResponse()->getData();
165    }
166}
167