diff --git a/changes.txt b/changes.txt index 826dfc1408..17ad8f1ff0 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,11 @@ CHANGES +2012-11-10 +- Added Elastica_Cluster_Health, Elastica_Cluster_Health_Index and Elastica_Cluster_Health_Shard which wrap the _cluster/health endpoint. +- Added Elastica_Document::setId() +- Added options parameter to Elastica_Type::getDocument() +- Added Elastica_Query_Filtered::getFilter() + 2012-10-30 - Elastica_Search implement Elastica_Searchable interface diff --git a/lib/Elastica/Cluster.php b/lib/Elastica/Cluster.php index c7caf35a80..d414884189 100755 --- a/lib/Elastica/Cluster.php +++ b/lib/Elastica/Cluster.php @@ -16,6 +16,20 @@ class Elastica_Cluster */ protected $_client = null; + /** + * Cluster state response. + * + * @var Elastica_Response + */ + protected $_response; + + /** + * Cluster state data. + * + * @var array + */ + protected $_data; + /** * Creates a cluster object * @@ -126,12 +140,12 @@ public function getInfo(array $args) /** * Return Cluster health * - * @param array $args OPTIONAL - * @link http://www.elasticsearch.com/docs/elasticsearch/rest_api/admin/cluster/health/ + * @return Elastica_Cluster_Health + * @link http://www.elasticsearch.org/guide/reference/api/admin-cluster-health.html */ - public function getHealth($args = array()) + public function getHealth() { - throw new Exception('not implemented yet'); + return new Elastica_Cluster_Health($this->getClient()); } /** diff --git a/lib/Elastica/Cluster/Health.php b/lib/Elastica/Cluster/Health.php new file mode 100644 index 0000000000..0af14bc06c --- /dev/null +++ b/lib/Elastica/Cluster/Health.php @@ -0,0 +1,183 @@ + + * @link http://www.elasticsearch.org/guide/reference/api/admin-cluster-health.html + */ +class Elastica_Cluster_Health +{ + /** + * Elastica client. + * + * @var Elastica_Client Client object + */ + protected $_client = null; + + /** + * The cluster health data. + * + * @var array + */ + protected $_data = null; + + /** + * @param Elastica_Client $client The Elastica client. + */ + public function __construct(Elastica_Client $client) + { + $this->_client = $client; + $this->refresh(); + } + + /** + * Retrieves the health data from the cluster. + * + * @return array + */ + protected function _retrieveHealthData() + { + $path = '_cluster/health?level=shards'; + $response = $this->_client->request($path, Elastica_Request::GET); + return $response->getData(); + } + + /** + * Gets the health data. + * + * @return array + */ + public function getData() + { + return $this->_data; + } + + /** + * Refreshes the health data for the cluster. + * + * @return Elastica_Cluster_Health + */ + public function refresh() + { + $this->_data = $this->_retrieveHealthData(); + return $this; + } + + /** + * Gets the name of the cluster. + * + * @return string + */ + public function getClusterName() + { + return $this->_data['cluster_name']; + } + + /** + * Gets the status of the cluster. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * TODO determine the purpose of this. + * + * @return bool + */ + public function getTimedOut() + { + return $this->_data['timed_out']; + } + + /** + * Gets the number of nodes in the cluster. + * + * @return int + */ + public function getNumberOfNodes() + { + return $this->_data['number_of_nodes']; + } + + /** + * Gets the number of data nodes in the cluster. + * + * @return int + */ + public function getNumberOfDataNodes() + { + return $this->_data['number_of_data_nodes']; + } + + /** + * Gets the number of active primary shards. + * + * @return int + */ + public function getActivePrimaryShards() + { + return $this->_data['active_primary_shards']; + } + + /** + * Gets the number of active shards. + * + * @return int + */ + public function getActiveShards() + { + return $this->_data['active_shards']; + } + + /** + * Gets the number of relocating shards. + * + * @return int + */ + public function getRelocatingShards() + { + return $this->_data['relocating_shards']; + } + + /** + * Gets the number of initializing shards. + * + * @return int + */ + public function getInitializingShards() + { + return $this->_data['initializing_shards']; + } + + /** + * Gets the number of unassigned shards. + * + * @return int + */ + public function getUnassignedShards() + { + return $this->_data['unassigned_shards']; + } + + /** + * Gets the status of the indices. + * + * @return array Array of Elastica_Cluster_Health_Index objects. + */ + public function getIndices() + { + $indices = array(); + foreach ($this->_data['indices'] as $indexName => $index) { + $indices[] = new Elastica_Cluster_Health_Index($indexName, $index); + } + + return $indices; + } +} + diff --git a/lib/Elastica/Cluster/Health/Index.php b/lib/Elastica/Cluster/Health/Index.php new file mode 100644 index 0000000000..c1237b2c91 --- /dev/null +++ b/lib/Elastica/Cluster/Health/Index.php @@ -0,0 +1,140 @@ + + * @link http://www.elasticsearch.org/guide/reference/api/admin-cluster-health.html + */ +class Elastica_Cluster_Health_Index +{ + /** + * The name of the index. + * + * @var string + */ + protected $_name; + + /** + * The index health data. + * + * @var array + */ + protected $_data; + + /** + * @param string $name The name of the index. + * @param array $data The index health data. + */ + public function __construct($name, $data) + { + $this->_name = $name; + $this->_data = $data; + } + + /** + * Gets the name of the index. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Gets the status of the index. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * Gets the number of nodes in the index. + * + * @return int + */ + public function getNumberOfShards() + { + return $this->_data['number_of_shards']; + } + + /** + * Gets the number of data nodes in the index. + * + * @return int + */ + public function getNumberOfReplicas() + { + return $this->_data['number_of_replicas']; + } + + /** + * Gets the number of active primary shards. + * + * @return int + */ + public function getActivePrimaryShards() + { + return $this->_data['active_primary_shards']; + } + + /** + * Gets the number of active shards. + * + * @return int + */ + public function getActiveShards() + { + return $this->_data['active_shards']; + } + + /** + * Gets the number of relocating shards. + * + * @return int + */ + public function getRelocatingShards() + { + return $this->_data['relocating_shards']; + } + + /** + * Gets the number of initializing shards. + * + * @return int + */ + public function getInitializingShards() + { + return $this->_data['initializing_shards']; + } + + /** + * Gets the number of unassigned shards. + * + * @return int + */ + public function getUnassignedShards() + { + return $this->_data['unassigned_shards']; + } + + /** + * Gets the health of the shards in this index. + * + * @return array Array of Elastica_Cluster_Health_Shard objects. + */ + public function getShards() + { + $shards = array(); + foreach ($this->_data['shards'] as $shardNumber => $shard) { + $shards[] = new Elastica_Cluster_Health_Shard($shardNumber, $shard); + } + + return $shards; + } +} diff --git a/lib/Elastica/Cluster/Health/Shard.php b/lib/Elastica/Cluster/Health/Shard.php new file mode 100644 index 0000000000..7b8cec1a22 --- /dev/null +++ b/lib/Elastica/Cluster/Health/Shard.php @@ -0,0 +1,105 @@ + + * @link http://www.elasticsearch.org/guide/reference/api/admin-cluster-health.html + */ +class Elastica_Cluster_Health_Shard +{ + /** + * The shard index/number. + * + * @var int + */ + protected $_shardNumber; + + /** + * The shard health data. + * + * @var array + */ + protected $_data; + + /** + * @param int $shardNumber The shard index/number. + * @param array $data The shard health data. + */ + public function __construct($shardNumber, $data) + { + $this->_shardNumber = $shardNumber; + $this->_data = $data; + } + + /** + * Gets the index/number of this shard. + * + * @return int + */ + public function getShardNumber() + { + return $this->_shardNumber; + } + + /** + * Gets the status of this shard. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * Is the primary active? + * + * @return bool + */ + public function isPrimaryActive() + { + return $this->_data['primary_active']; + } + + /** + * Is this shard active? + * + * @return bool + */ + public function isActive() + { + return $this->_data['active_shards'] == 1; + } + + /** + * Is this shard relocating? + * + * @return bool + */ + public function isRelocating() + { + return $this->_data['relocating_shards'] == 1; + } + + /** + * Is this shard initialized? + * + * @return bool + */ + public function isInitialized() + { + return $this->_data['initializing_shards'] == 1; + } + + /** + * Is this shard unassigned? + * + * @return bool + */ + public function isUnassigned() + { + return $this->_data['unassigned_shards'] == 1; + } +} diff --git a/test/lib/Elastica/Cluster/Health/IndexTest.php b/test/lib/Elastica/Cluster/Health/IndexTest.php new file mode 100644 index 0000000000..54eb58b826 --- /dev/null +++ b/test/lib/Elastica/Cluster/Health/IndexTest.php @@ -0,0 +1,109 @@ + "yellow", + "number_of_shards" => 1, + "number_of_replicas" => 2, + "active_primary_shards" => 3, + "active_shards" => 4, + "relocating_shards" => 5, + "initializing_shards" => 6, + "unassigned_shards" => 7, + "shards" => array( + "0" => array( + "status" => "yellow", + "primary_active" => false, + "active_shards" => 0, + "relocating_shards" => 1, + "initializing_shards" => 0, + "unassigned_shards" => 1 + ), + "1" => array( + "status" => "yellow", + "primary_active" => true, + "active_shards" => 1, + "relocating_shards" => 0, + "initializing_shards" => 0, + "unassigned_shards" => 1 + ), + "2" => array( + "status" => "green", + "primary_active" => true, + "active_shards" => 1, + "relocating_shards" => 0, + "initializing_shards" => 0, + "unassigned_shards" => 0, + ), + ) + ); + + $this->_index = new Elastica_Cluster_Health_Index('test', $data); + } + + public function testGetName() + { + $this->assertEquals('test', $this->_index->getName()); + } + + public function testGetStatus() + { + $this->assertEquals('yellow', $this->_index->getStatus()); + } + + public function testGetNumberOfShards() + { + $this->assertEquals(1, $this->_index->getNumberOfShards()); + } + + public function testGetNumberOfReplicas() + { + $this->assertEquals(2, $this->_index->getNumberOfReplicas()); + } + + public function testGetActivePrimaryShards() + { + $this->assertEquals(3, $this->_index->getActivePrimaryShards()); + } + + public function testGetActiveShards() + { + $this->assertEquals(4, $this->_index->getActiveShards()); + } + + public function testGetRelocatingShards() + { + $this->assertEquals(5, $this->_index->getRelocatingShards()); + } + + public function testGetInitializingShards() + { + $this->assertEquals(6, $this->_index->getInitializingShards()); + } + + public function testGetUnassignedShards() + { + $this->assertEquals(7, $this->_index->getUnassignedShards()); + } + + public function testGetShards() + { + $shards = $this->_index->getShards(); + + $this->assertInternalType('array', $shards); + $this->assertEquals(3, count($shards)); + + foreach ($shards as $shard) { + $this->assertInstanceOf('Elastica_Cluster_Health_Shard', $shard); + } + } +} diff --git a/test/lib/Elastica/Cluster/Health/ShardTest.php b/test/lib/Elastica/Cluster/Health/ShardTest.php new file mode 100644 index 0000000000..2641c0f6f1 --- /dev/null +++ b/test/lib/Elastica/Cluster/Health/ShardTest.php @@ -0,0 +1,60 @@ + 'red', + 'primary_active' => true, + 'active_shards' => 1, + 'relocating_shards' => 0, + 'initializing_shards' => 0, + 'unassigned_shards' => 1, + ); + + $this->_shard = new Elastica_Cluster_Health_Shard(2, $shardData); + } + + public function testGetShardNumber() + { + $this->assertEquals(2, $this->_shard->getShardNumber()); + } + + public function testGetStatus() + { + $this->assertEquals('red', $this->_shard->getStatus()); + } + + public function testisPrimaryActive() + { + $this->assertTrue($this->_shard->isPrimaryActive()); + } + + public function testIsActive() + { + $this->assertTrue($this->_shard->isActive()); + } + + public function testIsRelocating() + { + $this->assertFalse($this->_shard->isRelocating()); + } + + public function testIsInitialized() + { + $this->assertFalse($this->_shard->isInitialized()); + } + + public function testIsUnassigned() + { + $this->assertTrue($this->_shard->isUnassigned()); + } +} diff --git a/test/lib/Elastica/Cluster/HealthTest.php b/test/lib/Elastica/Cluster/HealthTest.php new file mode 100644 index 0000000000..681adf405e --- /dev/null +++ b/test/lib/Elastica/Cluster/HealthTest.php @@ -0,0 +1,110 @@ + 'test_cluster', + 'status' => 'green', + 'timed_out' => false, + 'number_of_nodes' => 10, + 'number_of_data_nodes' => 8, + 'active_primary_shards' => 3, + 'active_shards' => 4, + 'relocating_shards' => 2, + 'initializing_shards' => 7, + 'unassigned_shards' => 5, + 'indices' => array( + 'index_one' => array( + ), + 'index_two' => array( + ), + ), + ); + + $health = $this + ->getMockBuilder('Elastica_Cluster_Health') + ->setConstructorArgs(array(new Elastica_Client)) + ->setMethods(array('_retrieveHealthData')) + ->getMock(); + + $health + ->expects($this->any()) + ->method('_retrieveHealthData') + ->will($this->returnValue($data)); + + // need to explicitly refresh because the mocking won't refresh the data in the constructor + $health->refresh(); + + $this->_health = $health; + } + + public function testGetClusterName() + { + $this->assertEquals('test_cluster', $this->_health->getClusterName()); + } + + public function testGetStatus() + { + $this->assertEquals('green', $this->_health->getStatus()); + } + + public function testGetTimedOut() + { + $this->assertFalse($this->_health->getTimedOut()); + } + + public function testGetNumberOfNodes() + { + $this->assertEquals(10, $this->_health->getNumberOfNodes()); + } + + public function testGetNumberOfDataNodes() + { + $this->assertEquals(8, $this->_health->getNumberOfDataNodes()); + } + + public function testGetActivePrimaryShards() + { + $this->assertEquals(3, $this->_health->getActivePrimaryShards()); + } + + public function testGetActiveShards() + { + $this->assertEquals(4, $this->_health->getActiveShards()); + } + + public function testGetRelocatingShards() + { + $this->assertEquals(2, $this->_health->getRelocatingShards()); + } + + public function testGetInitializingShards() + { + $this->assertEquals(7, $this->_health->getInitializingShards()); + } + + public function testGetUnassignedShards() + { + $this->assertEquals(5, $this->_health->getUnassignedShards()); + } + + public function testGetIndices() + { + $indices = $this->_health->getIndices(); + + $this->assertInternalType('array', $indices); + $this->assertEquals(2, count($indices)); + + foreach ($indices as $index) { + $this->assertInstanceOf('Elastica_Cluster_Health_Index', $index); + } + } +} diff --git a/test/lib/Elastica/ClusterTest.php b/test/lib/Elastica/ClusterTest.php index 304e6dad5f..1d4fef9ea1 100644 --- a/test/lib/Elastica/ClusterTest.php +++ b/test/lib/Elastica/ClusterTest.php @@ -77,4 +77,10 @@ public function testGetIndexNames() $indexNames = $cluster->getIndexNames(); $this->assertContains($index->getname(), $indexNames); } + + public function testGetHealth() + { + $client = new Elastica_Client(); + $this->assertInstanceOf('Elastica_Cluster_Health', $client->getCluster()->getHealth()); + } }