1<?php
2
3namespace Elastica\Node;
4
5use Elastica\Node as BaseNode;
6use Elastica\Response;
7
8/**
9 * Elastica cluster node object.
10 *
11 * @author Nicolas Ruflin <spam@ruflin.com>
12 *
13 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html
14 */
15class Info
16{
17    /**
18     * Response.
19     *
20     * @var Response Response object
21     */
22    protected $_response;
23
24    /**
25     * Stats data.
26     *
27     * @var array stats data
28     */
29    protected $_data = [];
30
31    /**
32     * Node.
33     *
34     * @var BaseNode Node object
35     */
36    protected $_node;
37
38    /**
39     * Query parameters.
40     *
41     * @var array
42     */
43    protected $_params = [];
44
45    /**
46     * Unique node id.
47     *
48     * @var string
49     */
50    protected $_id;
51
52    /**
53     * Create new info object for node.
54     *
55     * @param BaseNode $node   Node object
56     * @param array    $params List of params to return. Can be: settings, os, process, jvm, thread_pool, network, transport, http
57     */
58    public function __construct(BaseNode $node, array $params = [])
59    {
60        $this->_node = $node;
61        $this->refresh($params);
62    }
63
64    /**
65     * Returns the entry in the data array based on the params.
66     * Several params possible.
67     *
68     * Example 1: get('os', 'mem', 'total') returns total memory of the system the
69     * node is running on
70     * Example 2: get('os', 'mem') returns an array with all mem infos
71     *
72     * @return mixed Data array entry or null if not found
73     */
74    public function get()
75    {
76        $data = $this->getData();
77
78        foreach (\func_get_args() as $arg) {
79            if (isset($data[$arg])) {
80                $data = $data[$arg];
81            } else {
82                return null;
83            }
84        }
85
86        return $data;
87    }
88
89    /**
90     * Return port of the node.
91     *
92     * @return string Returns Node port
93     */
94    public function getPort(): string
95    {
96        // Returns string in format: inet[/192.168.1.115:9201]
97        $data = $this->get('http_address');
98        $data = \substr($data, 6, \strlen($data) - 7);
99        $data = \explode(':', $data);
100
101        return $data[1];
102    }
103
104    /**
105     * Return IP of the node.
106     *
107     * @return string Returns Node ip address
108     */
109    public function getIp(): string
110    {
111        // Returns string in format: inet[/192.168.1.115:9201]
112        $data = $this->get('http_address');
113        $data = \substr($data, 6, \strlen($data) - 7);
114        $data = \explode(':', $data);
115
116        return $data[0];
117    }
118
119    /**
120     * Return data regarding plugins installed on this node.
121     *
122     * @return array plugin data
123     *
124     * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html
125     */
126    public function getPlugins(): array
127    {
128        if (!\in_array('plugins', $this->_params, true)) {
129            //Plugin data was not retrieved when refresh() was called last. Get it now.
130            $this->_params[] = 'plugins';
131            $this->refresh($this->_params);
132        }
133
134        return $this->get('plugins');
135    }
136
137    /**
138     * Check if the given plugin is installed on this node.
139     *
140     * @param string $name plugin name
141     *
142     * @return bool true if the plugin is installed, false otherwise
143     */
144    public function hasPlugin($name): bool
145    {
146        foreach ($this->getPlugins() as $plugin) {
147            if ($plugin['name'] === $name) {
148                return true;
149            }
150        }
151
152        return false;
153    }
154
155    /**
156     * Return all info data.
157     *
158     * @return array Data array
159     */
160    public function getData(): array
161    {
162        return $this->_data;
163    }
164
165    /**
166     * Return node object.
167     *
168     * @return BaseNode Node object
169     */
170    public function getNode(): BaseNode
171    {
172        return $this->_node;
173    }
174
175    /**
176     * @return string Unique node id
177     */
178    public function getId(): string
179    {
180        return $this->_id;
181    }
182
183    /**
184     * @return string Node name
185     */
186    public function getName(): string
187    {
188        return $this->_data['name'];
189    }
190
191    /**
192     * Returns response object.
193     *
194     * @return Response Response object
195     */
196    public function getResponse(): Response
197    {
198        return $this->_response;
199    }
200
201    /**
202     * Reloads all nodes information. Has to be called if informations changed.
203     *
204     * @param array $params Params to return (default none). Possible options: settings, os, process, jvm, thread_pool, network, transport, http, plugin
205     *
206     * @return Response Response object
207     */
208    public function refresh(array $params = []): Response
209    {
210        $this->_params = $params;
211
212        $endpoint = new \Elasticsearch\Endpoints\Cluster\Nodes\Info();
213        $endpoint->setNodeID($this->getNode()->getId());
214
215        if (!empty($params)) {
216            $endpoint->setMetric($params);
217        }
218
219        $this->_response = $this->getNode()->getClient()->requestEndpoint($endpoint);
220        $data = $this->getResponse()->getData();
221
222        $this->_data = \reset($data['nodes']);
223        $this->_id = \key($data['nodes']);
224        $this->getNode()->setId($this->getId());
225
226        return $this->_response;
227    }
228}
229