lib/vmc/client.rb in af-0.3.13.beta.5 vs lib/vmc/client.rb in af-0.3.16.1

- old
+ new

@@ -37,11 +37,11 @@ # Initialize new client to the target_uri with optional auth_token def initialize(target_url=VMC::DEFAULT_TARGET, auth_token=nil) target_url = "http://#{target_url}" unless /^https?/ =~ target_url target_url = target_url.gsub(/\/+$/, '') - @target = target_url + @target = target_url @auth_token = auth_token end ###################################################### # Target info @@ -58,15 +58,15 @@ end # Global listing of services that are available on the target system def services_info check_login_status - json_get(VMC::GLOBAL_SERVICES_PATH) + json_get(path(VMC::GLOBAL_SERVICES_PATH)) end def runtimes_info - json_get(VMC::GLOBAL_RUNTIMES_PATH) + json_get(path(VMC::GLOBAL_RUNTIMES_PATH)) end ###################################################### # Apps ###################################################### @@ -84,11 +84,11 @@ json_post(VMC::APPS_PATH, app) end def update_app(name, manifest) check_login_status - json_put("#{VMC::APPS_PATH}/#{name}", manifest) + json_put(path(VMC::APPS_PATH, name), manifest) end def upload_app(name, zipfile, resource_manifest=nil) #FIXME, manifest should be allowed to be null, here for compatability with old cc's resource_manifest ||= [] @@ -101,31 +101,33 @@ file = File.new(zipfile, 'rb') end upload_data[:application] = file end upload_data[:resources] = resource_manifest.to_json if resource_manifest - http_post("#{VMC::APPS_PATH}/#{name}/application", upload_data) + http_post(path(VMC::APPS_PATH, name, "application"), upload_data) + rescue RestClient::ServerBrokeConnection + retry end def delete_app(name) check_login_status - http_delete("#{VMC::APPS_PATH}/#{name}") + http_delete(path(VMC::APPS_PATH, name)) end def app_info(name) check_login_status - json_get("#{VMC::APPS_PATH}/#{name}") + json_get(path(VMC::APPS_PATH, name)) end def app_update_info(name) check_login_status - json_get("#{VMC::APPS_PATH}/#{name}/update") + json_get(path(VMC::APPS_PATH, name, "update")) end def app_stats(name) check_login_status - stats_raw = json_get("#{VMC::APPS_PATH}/#{name}/stats") + stats_raw = json_get(path(VMC::APPS_PATH, name, "stats")) stats = [] stats_raw.each_pair do |k, entry| # Skip entries with no stats next unless entry[:stats] entry[:instance] = k.to_s.to_i @@ -135,24 +137,24 @@ stats.sort { |a,b| a[:instance] - b[:instance] } end def app_instances(name) check_login_status - json_get("#{VMC::APPS_PATH}/#{name}/instances") + json_get(path(VMC::APPS_PATH, name, "instances")) end def app_crashes(name) check_login_status - json_get("#{VMC::APPS_PATH}/#{name}/crashes") + json_get(path(VMC::APPS_PATH, name, "crashes")) end # List the directory or download the actual file indicated by # the path. - def app_files(name, path, instance=0) + def app_files(name, path, instance='0') check_login_status - url = "#{VMC::APPS_PATH}/#{name}/instances/#{instance}/files/#{path}" - url.gsub!('//', '/') + path = path.gsub('//', '/') + url = path(VMC::APPS_PATH, name, "instances", instance, "files", path) _, body, headers = http_get(url) body end ###################################################### @@ -188,19 +190,19 @@ end end raise TargetError, "Service [#{service}] is not a valid service choice" unless service_hash service_hash[:name] = name - json_post(VMC::SERVICES_PATH, service_hash) + json_post(path(VMC::SERVICES_PATH), service_hash) end def delete_service(name) check_login_status svcs = services || [] names = svcs.collect { |s| s[:name] } raise TargetError, "Service [#{name}] not a valid service" unless names.include? name - http_delete("#{VMC::SERVICES_PATH}/#{name}") + http_delete(path(VMC::SERVICES_PATH, name)) end def bind_service(service, appname) check_login_status app = app_info(appname) @@ -266,25 +268,25 @@ # login and return an auth_token # Auth token can be retained and used in creating # new clients, avoiding login. def login(user, password) - status, body, headers = json_post("#{VMC::USERS_PATH}/#{user}/tokens", {:password => password}) + status, body, headers = json_post(path(VMC::USERS_PATH, user, "tokens"), {:password => password}) response_info = json_parse(body) if response_info @user = user @auth_token = response_info[:token] end end # sets the password for the current logged user def change_password(new_password) check_login_status - user_info = json_get("#{VMC::USERS_PATH}/#{@user}") + user_info = json_get(path(VMC::USERS_PATH, @user)) if user_info user_info[:password] = new_password - json_put("#{VMC::USERS_PATH}/#{@user}", user_info) + json_put(path(VMC::USERS_PATH, @user), user_info) end end ###################################################### # System administration @@ -307,17 +309,27 @@ json_post(VMC::USERS_PATH, { :email => user_email, :password => password }) end def delete_user(user_email) check_login_status - http_delete("#{VMC::USERS_PATH}/#{user_email}") + http_delete(path(VMC::USERS_PATH, user_email)) end ###################################################### + def self.path(*path) + path.flatten.collect { |x| + URI.encode x.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") + }.join("/") + end + private + def path(*args, &blk) + self.class.path(*args, &blk) + end + def json_get(url) status, body, headers = http_get(url, 'application/json') json_parse(body) rescue JSON::ParserError raise BadResponse, "Can't parse response into JSON", body @@ -366,10 +378,10 @@ headers['Content-Type'] = content_type headers['Accept'] = content_type end req = { - :method => method, :url => "#{@target}#{path}", + :method => method, :url => "#{@target}/#{path}", :payload => payload, :headers => headers, :multipart => true } status, body, response_headers = perform_http_request(req) if request_failed?(status)