From 75fa8d5ea2ed56ef52c3a63ee90c1a6127dc37b4 Mon Sep 17 00:00:00 2001 From: Tim Pease Date: Wed, 14 Nov 2012 10:00:11 -0700 Subject: [PATCH] Making the Alias class multi-url capable. --- lib/tire/alias.rb | 44 +++++++++++++++++++++++++++-------- test/unit/index_alias_test.rb | 20 +++++++++++++--- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/lib/tire/alias.rb b/lib/tire/alias.rb index 72c9bd7b..84de26db 100644 --- a/lib/tire/alias.rb +++ b/lib/tire/alias.rb @@ -74,6 +74,7 @@ class Alias def initialize(attributes={}, &block) raise ArgumentError, "Please pass a Hash-like object" unless attributes.respond_to?(:each_pair) + @url = attributes.delete(:url) || Configuration.url @attributes = { :indices => IndexCollection.new([]) } attributes.each_pair do |key, value| @@ -87,34 +88,57 @@ def initialize(attributes={}, &block) block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given? end + attr_accessor :url + # Returns a collection of Tire::Alias objects for all aliases defined in the cluster, or for a specific index. # - def self.all(index=nil) - @response = Configuration.client.get [Configuration.url, index, '_aliases'].compact.join('/') + def self.all(url=nil, index=nil) + if url and url !~ /^https?:\/\//i + index, url = url, Configuration.url + elsif url.nil? + url = Configuration.url + end - aliases = MultiJson.decode(@response.body).inject({}) do |result, (index, value)| + @response = Configuration.client.get [url, index, '_aliases'].compact.join('/') + + aliases = MultiJson.decode(@response.body).inject({}) do |result, (name, value)| # 1] Skip indices without aliases next result if value['aliases'].empty? # 2] Build a reverse map of hashes (alias => indices, config) - value['aliases'].each do |key, value| (result[key] ||= { 'indices' => [] }).update(value)['indices'].push(index) end + value['aliases'].each do |key, v| (result[key] ||= { 'indices' => [] }).update(v)['indices'].push(name) end result end # 3] Build a collection of Alias objects from hashes aliases.map do |key, value| - self.new(value.update('name' => key)) + self.new(value.update('name' => key, :url => url)) end ensure # FIXME: Extract the `logged` method - Alias.new.logged '_aliases', %Q|curl "#{Configuration.url}/_aliases"| + Alias.new.logged '_aliases', %Q|curl "#{url}/_aliases"| end # Returns an alias by name # - def self.find(name, &block) - a = all.select { |a| a.name == name }.first + # Examples + # + # Alias.find( url, name ) + # Alias.find( name ) + # + def self.find(*args, &block) + case args.length + when 2 + url, name = args + when 1 + url = Configuration.url + name = args.first + else + raise ArgumentError, "wrong number of arguments (#{args.length} for 2)" + end + + a = all(url).select { |b| b.name == name }.first block.call(a) if block_given? return a end @@ -159,10 +183,10 @@ def filter(type=nil, *options) # Save the alias in _ElasticSearch_ # def save - @response = Configuration.client.post "#{Configuration.url}/_aliases", to_json + @response = Configuration.client.post "#{url}/_aliases", to_json ensure - logged '_aliases', %Q|curl -X POST "#{Configuration.url}/_aliases" -d '#{to_json}'| + logged '_aliases', %Q|curl -X POST "#{url}/_aliases" -d '#{to_json}'| end # Return a Hash suitable for JSON serialization diff --git a/test/unit/index_alias_test.rb b/test/unit/index_alias_test.rb index 84ca31bb..6d3a124d 100644 --- a/test/unit/index_alias_test.rb +++ b/test/unit/index_alias_test.rb @@ -12,9 +12,15 @@ class IndexAliasTest < Test::Unit::TestCase should "have a name and defaults" do @alias = Alias.new :name => 'dummy' assert_equal 'dummy', @alias.name + assert_equal Configuration.url, @alias.url assert @alias.indices.empty? end + should "have a configurable base URL" do + @alias = Alias.new :url => 'http://example.com:9200' + assert_equal 'http://example.com:9200', @alias.url + end + should "have indices" do @alias = Alias.new :indices => ['index_A', 'index_B'] assert_equal ['index_A', 'index_B'], @alias.indices.to_a @@ -94,7 +100,7 @@ class IndexAliasTest < Test::Unit::TestCase a['add']['alias'] == 'alias_martha' end end.returns(mock_response('{}'), 200) - + a = Alias.find('alias_martha') a.indices.push 'index_A' a.save @@ -109,7 +115,7 @@ class IndexAliasTest < Test::Unit::TestCase a['remove']['alias'] == 'alias_martha' end end.returns(mock_response('{}'), 200) - + a = Alias.find('alias_martha') a.indices.delete 'index_A' a.save @@ -120,7 +126,7 @@ class IndexAliasTest < Test::Unit::TestCase # puts json MultiJson.decode(json)['actions'].all? { |a| a['add']['routing'] == 'martha' } end.returns(mock_response('{}'), 200) - + a = Alias.find('alias_martha') a.routing('martha') a.save @@ -181,6 +187,14 @@ class IndexAliasTest < Test::Unit::TestCase a = Alias.find('alias_martha') assert_instance_of Alias, a assert_equal ['index_B', 'index_C'], a.indices.to_a.sort + + Configuration.client.expects(:get).with do |url, json| + url == "http://example.com:9200/_aliases" + end.returns( mock_response( %q|{"index_A":{"aliases":{}},"index_B":{"aliases":{"alias_john":{"filter":{"term":{"user":"john"}}},"alias_martha":{"filter":{"term":{"user":"martha"}}}}},"index_C":{"aliases":{"alias_martha":{"filter":{"term":{"user":"martha"}}}}}}|), 200 ) + + a = Alias.find('http://example.com:9200', 'alias_martha') + assert_instance_of Alias, a + assert_equal ['index_B', 'index_C'], a.indices.to_a.sort end should "find an alias and configure it with a block" do