class StudioApi::GenericRequest

Class which use itself direct connection to studio for tasks where ActiveResource is not enough. For consistent api is all network exceptions mapped to ones used in ActiveResource.

@example

rq = StudioApi::GenericRequest.new @connection
rq.get "/appliances"
rq.post "/file", :file => "/etc/config"

Public Class Methods

new(connection) click to toggle source

Creates new instance of request for given connection @param (StudioApi::Connection) connection information about connection

   # File lib/studio_api/generic_request.rb
43 def initialize(connection)
44   @connection = connection
45   if connection.proxy
46     proxy = connection.proxy
47     @http = Net::HTTP.new(connection.uri.host, connection.uri.port,
48         proxy.host, proxy.port, proxy.user, proxy.password)
49   else
50     @http = Net::HTTP.new(connection.uri.host, connection.uri.port)
51   end
52   @http.read_timeout = connection.timeout
53   if connection.uri.scheme == "https"
54     @http.use_ssl = true
55     Connection::SSL_ATTRIBUTES.each do |attr|
56       @http.send :"#{attr}=", connection.ssl[attr.to_sym] if connection.ssl[attr.to_sym]
57     end
58   end
59 end

Public Instance Methods

delete(path) click to toggle source

sends delete request @param (String) path relative path from api root @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection

   # File lib/studio_api/generic_request.rb
82 def delete(path)
83   #Even it is not dry I want to avoid meta programming with dynamic code evaluation so code is clear
84   do_request(Net::HTTP::Delete.new(Util.join_relative_url(@connection.uri.request_uri,path)))
85 end
get(path) click to toggle source

sends get request @param (String) path relative path from api root @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection

   # File lib/studio_api/generic_request.rb
65 def get(path)
66   do_request(Net::HTTP::Get.new(Util.join_relative_url(@connection.uri.request_uri,path)))
67 end
get_file(path, &block) click to toggle source

sends get request to suse studio @return (nil) as response @raise [ActiveResource::ConnectionError] when problem occur during connection

   # File lib/studio_api/generic_request.rb
72 def get_file(path, &block)
73   do_file_request(Net::HTTP::Get.new(
74     Util.join_relative_url(@connection.uri.request_uri,path)),
75     &block)
76 end
post(path,data={}) click to toggle source

sends post request @param (String) path relative path from api root @param (Hash<#to_s,#to_s>,Hash<#to_s,#path>) data hash containing data to attach to body @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection

   # File lib/studio_api/generic_request.rb
92 def post(path,data={})
93   request = Net::HTTP::Post.new(Util.join_relative_url(@connection.uri.request_uri,path))
94   set_data(request,data) unless data.empty?
95   do_request request
96 end
put(path,data={}) click to toggle source

sends post request @param (String) path relative path from api root @param (Hash<#to_s,#to_s>,Hash<#to_s,#path>) data hash containing data to attach to body @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection

    # File lib/studio_api/generic_request.rb
103 def put(path,data={})
104   request = Net::HTTP::Put.new(Util.join_relative_url(@connection.uri.request_uri,path))
105   set_data(request,data) unless data.empty?
106   do_request request
107 end

Private Instance Methods

do_file_request(request) { |body| ... } click to toggle source
    # File lib/studio_api/generic_request.rb
119 def do_file_request request, &block
120   request.basic_auth @connection.user, @connection.password
121   @http.start do |http|
122     http.request request do |response|
123       handle_active_resource_exception response
124       response.read_body {|body| yield body }
125     end
126   end
127 end
do_request(request) click to toggle source
    # File lib/studio_api/generic_request.rb
110 def do_request(request)
111   request.basic_auth @connection.user, @connection.password
112   @http.start() do
113     response = @http.request request
114     handle_active_resource_exception response
115     response.body
116   end
117 end
error_message(response) click to toggle source
    # File lib/studio_api/generic_request.rb
138 def error_message response
139   xml_parsed = XmlSimple.xml_in(response.body, {'KeepRoot' => true})
140   raise "Unknown error response from Studio: #{response.body}" unless xml_parsed['error']
141   msg = ""
142   xml_parsed['error'].each() {|error| msg << error['message'][0]+"\n" }
143   return msg
144 rescue RuntimeError
145   return response.message+"\n"+response.body
146 end
handle_active_resource_exception(response) click to toggle source

XXX not so nice to use internal method, but better to be DRY and proper test if it works with supported rails

    # File lib/studio_api/generic_request.rb
130 def handle_active_resource_exception response
131   unless response.kind_of? Net::HTTPSuccess
132     msg = error_message response
133     response.instance_variable_set "@message",msg
134     ActiveResource::Connection.new('').send :handle_response, response
135   end
136 end
mime_type(file) click to toggle source
    # File lib/studio_api/generic_request.rb
174 def mime_type(file)
175   case
176     when file =~ /\.jpe?g\z/i then 'image/jpg'
177     when file =~ /\.gif\z/i then 'image/gif'
178     when file =~ /\.png\z/i then 'image/png'
179     else 'application/octet-stream'
180   end
181 end
set_data(request,data) click to toggle source
    # File lib/studio_api/generic_request.rb
148 def set_data(request,data)
149   if data[:__raw]
150     request.body = data[:__raw]
151   else
152     boundary = Time.now.to_i.to_s(16)
153     request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
154     body = ""
155     data.each do |key,value|
156       esc_key = CGI.escape(key.to_s)
157       body << "--#{boundary}\r\n"
158       if value.respond_to?(:read) && value.respond_to?(:path)
159         # ::File is needed to use "Ruby" file instead this one
160         body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{::File.basename(value.path)}\"\r\n"
161         body << "Content-Type: #{mime_type(value.path)}\r\n\r\n"
162         body << value.read
163       else
164         body << "Content-Disposition: form-data; name=\"#{esc_key}\"\r\n\r\n#{value}"
165       end
166       body << "\r\n"
167     end
168     body << "--#{boundary}--\r\n\r\n"
169     request.body = body
170     request["Content-Length"] = request.body.size
171   end
172 end