From 7f74df3399c7f9dd2d2456b82c1e289d17216a77 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 18 Aug 2014 17:20:21 -0700 Subject: [PATCH 1/5] support 1.x state filtering ES 1.x moves state filtering to path segments from query params. We now detect which version is connected and send the correct path template. It's up to the user to send the correct parameters. 0.90.x: client.cluster.state(:filter_nodes => true) 1.x: client.cluster.state(:metrics => 'nodes') The internal methods that use state filtering support both versions. --- lib/elastomer/client/cluster.rb | 50 +++++++++++++++++++++---------- test/client/cluster_test.rb | 16 ++++++++++ test/middleware/opaque_id_test.rb | 3 ++ 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/lib/elastomer/client/cluster.rb b/lib/elastomer/client/cluster.rb index 32051d87..26f8ee14 100644 --- a/lib/elastomer/client/cluster.rb +++ b/lib/elastomer/client/cluster.rb @@ -37,7 +37,7 @@ def health( params = {} ) # # Returns the response as a Hash def state( params = {} ) - response = client.get '/_cluster/state', params.merge(:action => 'cluster.state') + response = client.get '/_cluster/state{/metrics}{/indices}', params.merge(:action => 'cluster.state') response.body end @@ -168,11 +168,17 @@ def update_aliases( actions, params = {} ) # # Returns the template definitions as a Hash def templates - h = state( - :filter_blocks => true, - :filter_nodes => true, - :filter_routing_table => true - ) + # ES 1.x supports state filtering via a path segment called metrics. + # ES 0.90 uses query parameters instead. + if client.semantic_version >= '1.0.0' + h = state(:metrics => 'metadata') + else + h = state( + :filter_blocks => true, + :filter_nodes => true, + :filter_routing_table => true, + ) + end h['metadata']['templates'] end @@ -181,11 +187,17 @@ def templates # # Returns the indices definitions as a Hash def indices - h = state( - :filter_blocks => true, - :filter_nodes => true, - :filter_routing_table => true - ) + # ES 1.x supports state filtering via a path segment called metrics. + # ES 0.90 uses query parameters instead. + if client.semantic_version >= '1.0.0' + h = state(:metrics => 'metadata') + else + h = state( + :filter_blocks => true, + :filter_nodes => true, + :filter_routing_table => true, + ) + end h['metadata']['indices'] end @@ -195,11 +207,17 @@ def indices # # Returns the nodes definitions as a Hash def nodes - h = state( - :filter_blocks => true, - :filter_metadata => true, - :filter_routing_table => true - ) + # ES 1.x supports state filtering via a path segment called metrics. + # ES 0.90 uses query parameters instead. + if client.semantic_version >= '1.0.0' + h = state(:metrics => 'nodes') + else + h = state( + :filter_blocks => true, + :filter_metadata => true, + :filter_routing_table => true, + ) + end h['nodes'] end diff --git a/test/client/cluster_test.rb b/test/client/cluster_test.rb index 82368ac5..7e07aaae 100644 --- a/test/client/cluster_test.rb +++ b/test/client/cluster_test.rb @@ -24,6 +24,22 @@ assert h.key?('cluster_name'), 'the cluster name is returned' assert h.key?('master_node'), 'the master node is returned' assert_instance_of Hash, h['nodes'], 'the node list is returned' + assert_instance_of Hash, h['metadata'], 'the metadata are returned' + end + + if es_version_1_x? + it 'filters cluster state by metrics' do + h = @cluster.state(:metrics => 'nodes') + refute h.key('metadata'), 'expected only nodes state' + h = @cluster.state(:metrics => 'metadata') + refute h.key('nodes'), 'expected only metadata state' + end + + it 'filters cluster state by indices' do + @index.create({}) unless @index.exists? + h = @cluster.state(:metrics => 'metadata', :indices => @name) + assert [@name], h['metadata']['indices'].keys + end end it 'gets the cluster settings' do diff --git a/test/middleware/opaque_id_test.rb b/test/middleware/opaque_id_test.rb index 4f94109b..ea601f8e 100644 --- a/test/middleware/opaque_id_test.rb +++ b/test/middleware/opaque_id_test.rb @@ -15,6 +15,9 @@ ] } + stub.get('/') { |env| + [ 200, {}, {'version' => {'number' => '1.0.0'}} ] + } stub.get('/_cluster/state') { |env| [ 200, {'X-Opaque-Id' => "00000000-0000-0000-0000-000000000000"}, %q[{"foo":"bar"}] ] } From c7d24724fab0d2f91c6681b4aa26e8002fd0603d Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 18 Aug 2014 17:23:28 -0700 Subject: [PATCH 2/5] add tests for index and template list helpers --- test/client/cluster_test.rb | 6 ++++++ test/client/template_test.rb | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/test/client/cluster_test.rb b/test/client/cluster_test.rb index 7e07aaae..e050f3a7 100644 --- a/test/client/cluster_test.rb +++ b/test/client/cluster_test.rb @@ -71,6 +71,12 @@ assert_equal "60", value end + it 'returns the list of indices in the cluster' do + @index.create({}) unless @index.exists? + indices = @cluster.indices + assert !indices.empty?, 'expected to see an index' + end + it 'returns the list of nodes in the cluster' do nodes = @cluster.nodes assert !nodes.empty?, 'we have to have some nodes' diff --git a/test/client/template_test.rb b/test/client/template_test.rb index a3922117..a4cac448 100644 --- a/test/client/template_test.rb +++ b/test/client/template_test.rb @@ -11,6 +11,12 @@ @template.delete if @template.exists? end + it 'lists templates in the cluster' do + @template.create({:template => 'test-elastomer*'}) + templates = $client.cluster.templates + assert !templates.empty?, "expected to see a template" + end + it 'creates a template' do assert !@template.exists?, 'the template should not exist' From dc40602f2b07697d12edfe73bd37319921b10b13 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 18 Aug 2014 17:31:08 -0700 Subject: [PATCH 3/5] wait for index creation in analyze test --- test/client/index_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/client/index_test.rb b/test/client/index_test.rb index 19dae0a7..c7f0ccc6 100644 --- a/test/client/index_test.rb +++ b/test/client/index_test.rb @@ -154,6 +154,7 @@ } } ) + wait_for_index(@name) tokens = @index.analyze 'Just a few words to analyze.', :analyzer => 'english_standard' tokens = tokens['tokens'].map { |h| h['token'] } From fe5d01f77cf53a0df52596651564d80f793573cc Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 18 Aug 2014 17:37:29 -0700 Subject: [PATCH 4/5] document 1.x state filtering keys --- lib/elastomer/client/cluster.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/elastomer/client/cluster.rb b/lib/elastomer/client/cluster.rb index 26f8ee14..bc97e28b 100644 --- a/lib/elastomer/client/cluster.rb +++ b/lib/elastomer/client/cluster.rb @@ -30,7 +30,9 @@ def health( params = {} ) response.body end - # Comprehensive state information of the whole cluster. + # Comprehensive state information of the whole cluster. For 1.x metric + # and index filtering, use the :metrics and :indices parameter keys. + # # See http://www.elasticsearch.org/guide/reference/api/admin-cluster-state/ # # params - Parameters Hash From f071afae82eba2c0688a00ebb4a11effbb792f77 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 18 Aug 2014 17:45:55 -0700 Subject: [PATCH 5/5] enable 1.x node stats filtering client.nodes.stats(:stats => 'os') will filter the response to only return os stats. In 1.x this is a path segment instead of a query param. --- lib/elastomer/client/nodes.rb | 5 +++-- test/client/nodes_test.rb | 13 +++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/elastomer/client/nodes.rb b/lib/elastomer/client/nodes.rb index 843ee564..835de7f2 100644 --- a/lib/elastomer/client/nodes.rb +++ b/lib/elastomer/client/nodes.rb @@ -37,14 +37,15 @@ def info( params = {} ) response.body end - # Retrieve one or more (or all) of the cluster nodes statistics. + # Retrieve one or more (or all) of the cluster nodes statistics. For 1.x + # stats filtering, use the :stats parameter key. # See http://www.elasticsearch.org/guide/reference/api/admin-cluster-nodes-stats/ # # params - Parameters Hash # # Returns the response as a Hash def stats( params = {} ) - response = client.get '/_nodes{/node_id}/stats', update_params(params, :action => 'nodes.stats') + response = client.get '/_nodes{/node_id}/stats{/stats}', update_params(params, :action => 'nodes.stats') response.body end diff --git a/test/client/nodes_test.rb b/test/client/nodes_test.rb index 38f87cba..f47b5f00 100644 --- a/test/client/nodes_test.rb +++ b/test/client/nodes_test.rb @@ -2,7 +2,7 @@ describe Elastomer::Client::Nodes do - it 'gets info for the ndoe(s)' do + it 'gets info for the node(s)' do h = $client.nodes.info assert h.key?('cluster_name'), 'the cluster name is returned' assert_instance_of Hash, h['nodes'], 'the node list is returned' @@ -16,6 +16,15 @@ assert node.key?('indices'), 'indices stats are returned' end + if es_version_1_x? + it 'filters node stats' do + h = $client.nodes.stats(:stats => 'http') + node = h['nodes'].values.first + assert node.key?('http'), 'expected http stats to be present' + assert !node.key?('indices'), 'expected indices stats to be absent' + end + end + it 'gets the hot threads for the node(s)' do str = $client.nodes.hot_threads :read_timeout => 2 assert_instance_of String, str @@ -27,7 +36,7 @@ assert_empty h['nodes'] end - it 'can be scoped to a multiple nodes' do + it 'can be scoped to multiple nodes' do h = $client.nodes(%w[node1 node2 node3]).info assert_empty h['nodes'] end