Class: RestBuilder
- Inherits:
-
Object
- Object
- RestBuilder
- Defined in:
- lib/rally_rest_api/rest_builder.rb
Overview
:nodoc:
Direct Known Subclasses
Constant Summary collapse
- COLLECTION_TYPES =
[:tags, :dependents, :dependencies, :defects, :duplicates, :children, :predecessors, :test_cases, :artifacts, :changesets]
Instance Attribute Summary collapse
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
-
#http_headers ⇒ Object
readonly
Returns the value of attribute http_headers.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#password ⇒ Object
readonly
Returns the value of attribute password.
-
#use_cookies ⇒ Object
Returns the value of attribute use_cookies.
-
#username ⇒ Object
readonly
Returns the value of attribute username.
Instance Method Summary collapse
- #add_cookies(req) ⇒ Object
-
#builder_block(args) ⇒ Object
Because we are adapting to the xml builder as such: We say to the RallyRestAPI: slm.create(:feature, :name => “feature name”).
- #camel_case_word(sym) ⇒ Object
- #check_for_errors(response) ⇒ Object
- #collection_type?(type) ⇒ Boolean
-
#convert_arg_for_builder(value) ⇒ Object
Convert the values of the hash passed to the RestApi appropiatly RestObject –> a hash with the ref value nil –> “null” ref values Time –> iso8601 time strings Arrays of RestObjects –> block that has a nested xml value.
- #create_builder ⇒ Object
-
#create_rest(artifact_type, args, username, password) ⇒ Object
create_rest - convert slm builder style: slm.create(:feature, :name => “feature name”).
- #debug(message) ⇒ Object
- #delete_rest(ref_url, username, password) ⇒ Object
- #format_cookie(cookie_jar) ⇒ Object
-
#initialize(base_url, username, password, version = "current", http_headers = CustomHttpHeader.new) ⇒ RestBuilder
constructor
A new instance of RestBuilder.
- #marshal_dump ⇒ Object
- #marshal_load(stuff) ⇒ Object
- #parse_cookies(cookie_str) ⇒ Object
- #post_xml(url, xml, username, password) ⇒ Object
- #read_rest(ref_url, username, password) ⇒ Object
- #send_request(url, req, username, password) ⇒ Object
- #store_cookies(response) ⇒ Object
-
#update_rest(artifact_type, url, args, username, password) ⇒ Object
update_rest - convert slm builder style: feature.update(:name => “feature name”).
Constructor Details
#initialize(base_url, username, password, version = "current", http_headers = CustomHttpHeader.new) ⇒ RestBuilder
Returns a new instance of RestBuilder.
64 65 66 67 |
# File 'lib/rally_rest_api/rest_builder.rb', line 64 def initialize(base_url, username, password, version = "current", http_headers = CustomHttpHeader.new) @base_url, @username, @password, @version, @http_headers = base_url, username, password, version, http_headers @cookie_jar = {} end |
Instance Attribute Details
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
61 62 63 |
# File 'lib/rally_rest_api/rest_builder.rb', line 61 def base_url @base_url end |
#http_headers ⇒ Object (readonly)
Returns the value of attribute http_headers.
61 62 63 |
# File 'lib/rally_rest_api/rest_builder.rb', line 61 def http_headers @http_headers end |
#logger ⇒ Object
Returns the value of attribute logger.
62 63 64 |
# File 'lib/rally_rest_api/rest_builder.rb', line 62 def logger @logger end |
#password ⇒ Object (readonly)
Returns the value of attribute password.
61 62 63 |
# File 'lib/rally_rest_api/rest_builder.rb', line 61 def password @password end |
#use_cookies ⇒ Object
Returns the value of attribute use_cookies.
62 63 64 |
# File 'lib/rally_rest_api/rest_builder.rb', line 62 def @use_cookies end |
#username ⇒ Object (readonly)
Returns the value of attribute username.
61 62 63 |
# File 'lib/rally_rest_api/rest_builder.rb', line 61 def username @username end |
Instance Method Details
#add_cookies(req) ⇒ Object
134 135 136 137 |
# File 'lib/rally_rest_api/rest_builder.rb', line 134 def (req) req.add_field('cookie', (@cookie_jar)) req end |
#builder_block(args) ⇒ Object
Because we are adapting to the xml builder as such:
We say to the RallyRestAPI:
slm.create(:feature, :name => "feature name")
We tell the xml builder:
b.feature {
b.name("feature name")
}
in the case where one element is a collection, RallyRest would look like
slm.create(:feature, :name => "name", :dependancies => [sr1, sr2])
This needs to be converted to
b.feature {
b.name("name")
b.Dependancies {
b.SupplementalRequirement(:ref => "http://....")
b.SupplementalRequirement(:ref => "http://....")
}
}
in this case we need to create a block to handle the nested calls (b.Supp…)
There are also nested/complex values, for example slm.create(:defect, :web_link => => “123”, :description => “foo” )
b.defect {
b.web_link {
b.id "123"
b.description "foo"
}
}
We need to convert the args hash into a block that can be fed to the builder. This will send the keys of the map as “methods” (b.name) and the values of map as the arguments to the method (“feature name”).
Additionally we camel-case the elements (as JDOM can’t handle elements case free). #convert_arg_for_builder will convert the value portion of the hash to the appropiate string, or block for the xml builder
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/rally_rest_api/rest_builder.rb', line 255 def builder_block(args) sort_block = lambda { |a,b| a.to_s <=> b.to_s } # Sort the keys, for testing lambda do |builder| args.sort(&sort_block).each do |(attr, value)| if COLLECTION_TYPES.include? attr # The call to builder with only a type and a block needs to be marked as such # note the '&' builder.__send__(camel_case_word(attr), &convert_arg_for_builder([value].flatten)) elsif value.instance_of? Hash builder.__send__(camel_case_word(attr), &builder_block(value)) else builder.__send__(camel_case_word(attr), convert_arg_for_builder(value)) end end end end |
#camel_case_word(sym) ⇒ Object
210 211 212 |
# File 'lib/rally_rest_api/rest_builder.rb', line 210 def camel_case_word(sym) sym.to_s.split("_").map { |word| word.capitalize }.join end |
#check_for_errors(response) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/rally_rest_api/rest_builder.rb', line 197 def check_for_errors(response) case response when Net::HTTPUnauthorized raise Rally::NotAuthenticatedError.new("Invalid Username or Password.") else #s = response.body s = response.plain_body document = REXML::Document.new s node = REXML::XPath.first document, '//Errors' raise node.to_s if node && node.has_elements? end end |
#collection_type?(type) ⇒ Boolean
300 301 302 |
# File 'lib/rally_rest_api/rest_builder.rb', line 300 def collection_type?(type) COLLECTION_TYPES.include?(type) end |
#convert_arg_for_builder(value) ⇒ Object
Convert the values of the hash passed to the RestApi appropiatly RestObject –> a hash with the ref value nil –> “null” ref values Time –> iso8601 time strings Arrays of RestObjects –> block that has a nested xml value
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/rally_rest_api/rest_builder.rb', line 278 def convert_arg_for_builder(value) case value when RestObject { :ref => value.ref } when NilClass { :ref => "null"} when Time value.iso8601 when Array lambda do |builder| value.each do |rest_object| builder.__send__(rest_object.type, convert_arg_for_builder(rest_object)) end end else value end end |
#create_builder ⇒ Object
191 192 193 194 195 |
# File 'lib/rally_rest_api/rest_builder.rb', line 191 def create_builder b = Builder::XmlMarkup.new b.instruct! b end |
#create_rest(artifact_type, args, username, password) ⇒ Object
create_rest - convert slm builder style:
slm.create(:feature, :name => "feature name")
Into xml builder style:
b.feature {
b.name("feature name")
}
then call create on the REST api
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rally_rest_api/rest_builder.rb', line 85 def create_rest(artifact_type, args, username, password) type = camel_case_word(artifact_type) debug "RestBuilder#create_rest artifact_type = #{type}" b = create_builder xml = b.__send__(type, &builder_block(args)) result = post_xml("#{self.base_url}/webservice/#{@version}/#{type}/create", xml, username, password) doc = REXML::Document.new result doc.root.elements["Object"].to_s end |
#debug(message) ⇒ Object
304 305 306 |
# File 'lib/rally_rest_api/rest_builder.rb', line 304 def debug() @logger.debug if @logger end |
#delete_rest(ref_url, username, password) ⇒ Object
119 120 121 122 123 124 |
# File 'lib/rally_rest_api/rest_builder.rb', line 119 def delete_rest(ref_url, username, password) debug "RestBuilder#delete_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }" url = URI.parse(ref_url) req = Net::HTTP::Delete.new(url.path) send_request(url, req, username, password) end |
#format_cookie(cookie_jar) ⇒ Object
151 152 153 154 155 156 157 158 |
# File 'lib/rally_rest_api/rest_builder.rb', line 151 def () = "" .each do |, | += "; " unless .empty? += "#{}=#{}" end end |
#marshal_dump ⇒ Object
69 70 71 |
# File 'lib/rally_rest_api/rest_builder.rb', line 69 def marshal_dump [@username, @password, @base_url, @version] end |
#marshal_load(stuff) ⇒ Object
73 74 75 |
# File 'lib/rally_rest_api/rest_builder.rb', line 73 def marshal_load(stuff) @username, @password, @base_url, @version = *stuff end |
#parse_cookies(cookie_str) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rally_rest_api/rest_builder.rb', line 139 def () = .split(', ') .collect! { || .split(";")[0] } = {} .each do || c = .split("=") [c[0]] = c[1] || "" end end |
#post_xml(url, xml, username, password) ⇒ Object
126 127 128 129 130 131 132 |
# File 'lib/rally_rest_api/rest_builder.rb', line 126 def post_xml(url, xml, username, password) debug "RestBuilder#post_xml xml = #{xml} as user #{ self.username } pass = #{ self.password }" url = URI.parse(url) req = Net::HTTP::Post.new(url.path) req.body = xml send_request(url, req, username, password) end |
#read_rest(ref_url, username, password) ⇒ Object
112 113 114 115 116 117 |
# File 'lib/rally_rest_api/rest_builder.rb', line 112 def read_rest(ref_url, username, password) debug "RestBuilder#read_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }" url = URI.parse(ref_url) req = Net::HTTP::Get.new(url.path + (url.query ? "?" + url.query : "")) send_request(url, req, username, password) end |
#send_request(url, req, username, password) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/rally_rest_api/rest_builder.rb', line 165 def send_request(url, req, username, password) @http_headers.add_headers(req) req.basic_auth username, password req.content_type = 'text/xml' req.add_field('Accept-Encoding', 'gzip, deflate') (req) if @use_cookies proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new http = Net::HTTP.new(url.host, url.port, proxy.host, proxy.port, proxy.user, proxy.password) http.use_ssl = true if url.scheme == "https" http.verify_mode = OpenSSL::SSL::VERIFY_NONE #http.ssl_version = "SSLv3" http.read_timeout = 300 debug "RestBuilder#send_request req = #{req.inspect} -- #{url}" response = http.start { |http| http.request(req) } #debug "RestBuilder#send_request result = #{response.body}" #check_for_errors(response) #response.body debug "RestBuilder#send_request result = #{response.plain_body}" headerstr = "" response.each_header { |k,v| headerstr << "#{k}--#{v}|" } (response) if @use_cookies debug "RestBuilder#send_request result headers = #{headerstr} and length is #{response.plain_body.length}" check_for_errors(response) response.plain_body end |
#store_cookies(response) ⇒ Object
160 161 162 163 |
# File 'lib/rally_rest_api/rest_builder.rb', line 160 def (response) @cookie_jar.merge!((response.response['set-cookie'])) response end |
#update_rest(artifact_type, url, args, username, password) ⇒ Object
update_rest - convert slm builder style:
feature.update(:name => "feature name")
Into xml builder style:
b.feature(:ref => "http://...") {
b.name("feature name")
}
then call create on the REST api
104 105 106 107 108 109 110 |
# File 'lib/rally_rest_api/rest_builder.rb', line 104 def update_rest(artifact_type, url, args, username, password) debug "RestBuilder#update_rest url = #{url}" b = create_builder # and pass that to the builder xml = b.__send__(artifact_type, :ref => url, &builder_block(args)) post_xml(url, xml, username, password) end |