lib/etcd/client.rb in etcd-0.0.2 vs lib/etcd/client.rb in etcd-0.0.4

- old
+ new

@@ -1,18 +1,37 @@ require 'net/http' require 'json' -require 'hashie' require 'etcd/log' +require 'etcd/mixins/helpers' +require 'etcd/mixins/lockable' +require 'ostruct' + module Etcd + ## + # This is the central ruby class for Etcd. It provides methods for all Etcd api calls. + # It also provides few additional methods beyond the core Etcd api, like Etcd::Client#lock + # and Etcd::Client#eternal_watch, they are defined in separate modules and included in this + # class class Client + include Etcd::Helpers + include Etcd::Lockable + attr_reader :host, :port, :http, :allow_redirect + ## + # Creates a new instance of Etcd::Client. It accepts a hash +opts+ as argument + # + # @param [Hash] opts The options for new Etcd::Client object + # @opts [String] :host IP address of the etcd server (default is '127.0.0.1') + # @opts [Fixnum] :port Port number of the etcd server (default is 4001) + def initialize(opts={}) @host = opts[:host] || '127.0.0.1' @port = opts[:port] || 4001 + @read_timeout = opts[:read_timeout] || 60 if opts.has_key?(:allow_redirect) @allow_redirect = opts[:allow_redirect] else @allow_redirect = true end @@ -21,15 +40,15 @@ def version_prefix '/v1' end def machines - api_execute('/machines', :get).split(",") + api_execute( version_prefix + '/machines', :get).split(",") end def leader - api_execute('/leader', :get) + api_execute( version_prefix + '/leader', :get) end def key_endpoint version_prefix + '/keys' end @@ -41,43 +60,39 @@ def test_and_set(key, value, prevValue, ttl = nil) path = key_endpoint + key payload = {'value' => value, 'prevValue' => prevValue } payload['ttl'] = ttl unless ttl.nil? response = api_execute(path, :post, payload) - Hashie::Mash.new(JSON.parse(response)) + json2obj(response) end def set(key, value, ttl=nil) path = key_endpoint + key - payload = {'value' => value} + payload = {'value' => value} payload['ttl'] = ttl unless ttl.nil? response = api_execute(path, :post, payload) - Hashie::Mash.new(JSON.parse(response)) + json2obj(response) end + def delete(key) response = api_execute(key_endpoint + key, :delete) - Hashie::Mash.new(JSON.parse(response)) + json2obj(response) end def get(key) response = api_execute(key_endpoint + key, :get) - obj = JSON.parse(response) - if obj.is_a?(Array) - obj.map{|e| Hashie::Mash.new(e)} - else - Hashie::Mash.new(obj) - end + json2obj(response) end def watch(key, index=nil) response = if index.nil? api_execute(watch_endpoint + key, :get) else api_execute(watch_endpoint + key, :post, {'index' => index}) end - Hashie::Mash.new(JSON.parse(response)) + json2obj(response) end def api_execute(path, method, params=nil) http = if path=~/^http/ @@ -85,13 +100,14 @@ path = uri.path Net::HTTP.new(uri.host, uri.port) else Net::HTTP.new(host, port) end + http.read_timeout = @read_timeout case method - when :get + when :get unless params.nil? encoded_params = URI.encode_www_form(params) path+= "?" + encoded_params end req = Net::HTTP::Get.new(path) @@ -109,11 +125,11 @@ end Log.debug("Invoking: '#{req.class}' against '#{path}") res = http.request(req) Log.debug("Response code: #{res.code}") - if res.is_a?(Net::HTTPSuccess) + if res.is_a?(Net::HTTPSuccess) Log.debug("Http success") res.body elsif redirect?(res.code.to_i) and allow_redirect Log.debug("Http redirect, following") api_execute(res['location'], method, params) @@ -125,8 +141,17 @@ end private def redirect?(code) (code >= 300) and (code < 400) + end + + def json2obj(json) + obj = JSON.parse(json) + if obj.is_a?(Array) + obj.map{|e| OpenStruct.new(e)} + else + OpenStruct.new(obj) + end end end end