Class: RallyAPI::RallyRestJson

Inherits:
Object
  • Object
show all
Defined in:
lib/rally_api/rally_rest_json.rb

Overview

Main Class to instantiate when using the tool

Constant Summary collapse

DEFAULT_WSAPI_VERSION =
"v2.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ RallyRestJson

Returns a new instance of RallyRestJson.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rally_api/rally_rest_json.rb', line 54

def initialize(args)
  pre_init()

  auth_info = {}

  auth_info[:base_url]  = @rally_url = args[:base_url] || "https://rally1.rallydev.com/slm"
  auth_info[:username]  = args[:username]
  auth_info[:password]  = args[:password]
  auth_info[:api_key]   = args[:api_key]
  @rally_workspace_name = args[:workspace]
  @rally_project_name   = args[:project]
  @wsapi_version        = args[:version]  || DEFAULT_WSAPI_VERSION
  @rally_headers        = args[:headers]  || CustomHttpHeader.new
  @proxy_info           = args[:proxy]
  @skip_sec_key         = args[:skip_sec_key]

  #flag to help RallyRestAPI users to use snake case field names eg Defect.fixed_in_build vs Defect["FixedInBuild"]
  @rally_rest_api_compat  = args[:rally_rest_api_compat] || false

  @low_debug = args[:debug]  || false
  @logger    = args[:logger] || nil    #assumes this is an instance of Logger

  @rally_connection = RallyJsonConnection.new(@rally_headers, @low_debug, @proxy_info)
  #@rally_connection.set_client_user(@rally_url, @rally_user, @rally_password)
  @rally_connection.set_auth(auth_info)
  @rally_connection.logger  = @logger unless @logger.nil?

  if @wsapi_version.to_s.include?("v2.") && !@skip_sec_key && auth_info[:api_key].nil?
    @rally_connection.setup_security_token(security_url)
  end

  if !@rally_workspace_name.nil?
    @rally_default_workspace = find_workspace(@rally_workspace_name)
    raise StandardError, "unable to find default workspace #{@rally_workspace_name}" if @rally_default_workspace.nil?
  end

  if !@rally_project_name.nil?
    @rally_default_project = find_project(@rally_default_workspace, @rally_project_name)
    raise StandardError, "unable to find default project #{@rally_project_name}" if @rally_default_project.nil?
  end

  self
end

Instance Attribute Details

#custom_fields_for_typeObject (readonly)

Returns the value of attribute custom_fields_for_type.



52
53
54
# File 'lib/rally_api/rally_rest_json.rb', line 52

def custom_fields_for_type
  @custom_fields_for_type
end

#loggerObject

Returns the value of attribute logger.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def logger
  @logger
end

#low_debugObject

Returns the value of attribute low_debug.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def low_debug
  @low_debug
end

#proxy_infoObject

Returns the value of attribute proxy_info.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def proxy_info
  @proxy_info
end

#rally_alias_typesObject

Returns the value of attribute rally_alias_types.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_alias_types
  @rally_alias_types
end

#rally_connectionObject (readonly)

Returns the value of attribute rally_connection.



52
53
54
# File 'lib/rally_api/rally_rest_json.rb', line 52

def rally_connection
  @rally_connection
end

#rally_default_projectObject

Returns the value of attribute rally_default_project.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_default_project
  @rally_default_project
end

#rally_default_workspaceObject

Returns the value of attribute rally_default_workspace.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_default_workspace
  @rally_default_workspace
end

#rally_headersObject

Returns the value of attribute rally_headers.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_headers
  @rally_headers
end

#rally_project_nameObject

Returns the value of attribute rally_project_name.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_project_name
  @rally_project_name
end

#rally_rest_api_compatObject

Returns the value of attribute rally_rest_api_compat.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_rest_api_compat
  @rally_rest_api_compat
end

#rally_urlObject

Returns the value of attribute rally_url.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_url
  @rally_url
end

#rally_workspace_nameObject

Returns the value of attribute rally_workspace_name.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def rally_workspace_name
  @rally_workspace_name
end

#wsapi_versionObject

Returns the value of attribute wsapi_version.



49
50
51
# File 'lib/rally_api/rally_rest_json.rb', line 49

def wsapi_version
  @wsapi_version
end

Instance Method Details

#adjust_find_threads(num_threads) ⇒ Object



292
293
294
# File 'lib/rally_api/rally_rest_json.rb', line 292

def adjust_find_threads(num_threads)
  @rally_connection.set_find_threads(num_threads)
end

#allowed_values(type, field, workspace = nil) ⇒ Object

todo - check support for portfolio item fields



357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/rally_api/rally_rest_json.rb', line 357

def allowed_values(type, field, workspace = nil)
  rally_workspace_object(workspace)
  
  type_def = get_typedef_for(type, workspace)
  allowed_vals = {}
  type_def["Attributes"].each do |attr|
    next if attr["ElementName"] != field
    attr["AllowedValues"].each do |val_ref|
      val = val_ref["StringValue"]
      val = "Null" if val.nil? || val.empty?
      allowed_vals[val] = true
    end
  end
  allowed_vals
end

#create(type, fields, params = {}) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rally_api/rally_rest_json.rb', line 173

def create(type, fields, params = {})
  type = check_type(type)
  if (fields["Workspace"].nil? && fields["Project"].nil?)
    fields["Workspace"] = rally_workspace_object._ref unless rally_workspace_object.nil?
    fields["Project"] = @rally_default_project._ref unless @rally_default_project.nil?
  end

  ws_ref = fields["Workspace"]
  ws_ref = ws_ref["_ref"] unless ws_ref.class == String || ws_ref.nil?
  params[:workspace] = ws_ref

  fields = RallyAPI::RallyRestJson.fix_case(fields) if @rally_rest_api_compat
  postable_fields = check_fields(fields)
  postable_fields = adjust_for_custom(type, postable_fields) if @wsapi_version =~ /^v2/
  object2create = { type => postable_fields }
  args = { :method => :post, :payload => object2create }
  json_response = send_request(make_create_url(type), args, params)
  #todo - check for warnings
  RallyObject.new(self, json_response["CreateResult"]["Object"], warnings(json_response)).read()
end

#custom_fields_for(type, workspace = rally_workspace_object) ⇒ Object



373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/rally_api/rally_rest_json.rb', line 373

def custom_fields_for(type, workspace = rally_workspace_object)
  @custom_fields_for_type[workspace.ObjectID] = {} if @custom_fields_for_type[workspace.ObjectID].nil?
  if @custom_fields_for_type[workspace.ObjectID][type].nil?
    @custom_fields_for_type[workspace.ObjectID][type] = {}
    type_def = get_typedef_for(type, workspace)
    type_def["Attributes"].each do |attr|
      next if attr["Custom"].to_s == "false"
      elem_name = attr["ElementName"]
      elem_name = elem_name.slice(2..256) unless @wsapi_version.start_with?("1")
      @custom_fields_for_type[workspace.ObjectID][type][elem_name] = attr["ElementName"]
    end
  end
  return @custom_fields_for_type[workspace.ObjectID][type]
end

#debug_logging_offObject



130
131
132
133
# File 'lib/rally_api/rally_rest_json.rb', line 130

def debug_logging_off
  @low_debug = false
  @rally_connection.low_debug = false
end

#debug_logging_onObject



125
126
127
128
# File 'lib/rally_api/rally_rest_json.rb', line 125

def debug_logging_on
  @low_debug = true
  @rally_connection.low_debug = true
end

#delete(ref_to_delete) ⇒ Object



204
205
206
207
208
209
# File 'lib/rally_api/rally_rest_json.rb', line 204

def delete(ref_to_delete)
  args = { :method => :delete }
  #json_response = @rally_connection.delete_object(ref_to_delete, args)
  json_response = send_request(ref_to_delete, args)
  json_response["OperationResult"]
end

#find(query_obj = RallyQuery.new) {|query_obj| ... } ⇒ Object


Querying Rally example test_query = RallyAPI::RallyQuery.new() test_query.type = :defect test_query.fetch = “Name” test_query.workspace = {“_ref” => “rally1.rallydev.com/slm/webservice/v2.0/workspace/12345” } #optional test_query.project = {“_ref” => “rally1.rallydev.com/slm/webservice/v2.0/project/12345” } #optional test_query.page_size = 200 #optional - default is 200 test_query.limit = 1000 #optional - default is 99999 test_query.project_scope_up = false test_query.project_scope_down = true test_query.order = “Name Asc” test_query.query_string = “(Severity = "High")”

results = @rally.find(test_query)

tip - set the fetch string of the query to the fields you need - only resort to the read method if you want your code to be slow results.each do |defect|

puts defect.Name   # or defect["Name"]
defect.read    #read the whole defect from Rally to get all fields (eg Severity)
puts defect.Severity

end query_obj is RallyQuery

Yields:

  • (query_obj)


272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/rally_api/rally_rest_json.rb', line 272

def find(query_obj = RallyQuery.new)
  yield query_obj if block_given?

  if query_obj.workspace.nil?
    query_obj.workspace = rally_workspace_object unless rally_workspace_object.nil?
  end

  errs = query_obj.validate()
  if errs.length > 0
    raise StandardError, "Errors making Rally Query: #{errs.to_s}"
  end

  query_url = make_query_url(@rally_url, @wsapi_version, check_type(query_obj.type.to_s))
  query_url += '.js' if @wsapi_version !~ /^v2/
  query_params = query_obj.make_query_params
  args =  {:method => :get}
  json_response = @rally_connection.get_all_json_results(query_url, args, query_params, query_obj.limit)
  RallyQueryResult.new(self, json_response, warnings(json_response))
end

#find_project(workspace_object, project_name) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/rally_api/rally_rest_json.rb', line 149

def find_project(workspace_object, project_name)
  if workspace_object.nil?
    raise StandardError, "A workspace must be provided to find a project"
  end

  query = RallyQuery.new()
  query.type          = :project
  query.query_string  = "((Name = \"#{project_name}\") AND (State = \"Open\"))"
  query.limit         = 20
  query.fetch         = true
  query.workspace     = workspace_object

  results = find(query)
  return results.first if results.length > 0
  nil
end

#find_workspace(workspace_name, matcher_ref = 'Name') ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rally_api/rally_rest_json.rb', line 135

def find_workspace(workspace_name, matcher_ref = 'Name')
  # use matcher_ref to search for 'Name' or '_ref'
  sub = self.user["Subscription"].read({:fetch => "Workspaces,Name,State"})
  workspace = nil
  sub.Workspaces.each do |ws|
    #ws.read
    if (ws[matcher_ref] == workspace_name) && (ws["State"] == "Open")
      workspace = ws
      break  #doing a break for performance some customers have 100+ workspaces - no need to do the others
    end
  end
  workspace
end

#get_fields_for(type, workspace = rally_workspace_object) ⇒ Object



345
346
347
348
349
350
351
352
353
354
# File 'lib/rally_api/rally_rest_json.rb', line 345

def get_fields_for(type, workspace = rally_workspace_object)
  type_def = get_typedef_for(type, workspace)
  return nil if type_def.nil?
  fields = {}
  type_def["Attributes"].each do |attr|
    field_name = attr["ElementName"]
    fields[field_name] = attr
  end
  fields
end

#get_typedef_for(type, workspace = rally_workspace_object) ⇒ Object



333
334
335
336
337
338
339
340
341
342
343
# File 'lib/rally_api/rally_rest_json.rb', line 333

def get_typedef_for(type, workspace = rally_workspace_object)
  type = type.to_s if type.class == Symbol
  type = check_type(type)
  type_def_query             = RallyQuery.new()
  type_def_query.type        = "typedefinition"
  type_def_query.workspace   = workspace
  type_def_query.fetch       = true
  type_def_query.query_string= "(TypePath = \"#{type}\")"
  type_def = find(type_def_query)
  type_def.first
end

#rally_workspace_object(new_wksp = nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rally_api/rally_rest_json.rb', line 111

def rally_workspace_object(new_wksp = nil)
  return @rally_default_workspace if new_wksp.nil?
  if new_wksp.instance_of?(String)
    if new_wksp.match(/rallydev.com/)
      @rally_default_workspace = find_workspace(new_wksp, '_ref')
    else
      @rally_default_workspace = find_workspace(new_wksp, 'Name')  
    end
  else
    @rally_default_workspace = new_wksp
  end
  return @rally_default_workspace
end

#rank_above(ref_to_rank, relative_ref) ⇒ Object

rankAbove=%2Fhierarchicalrequirement%2F4624552599 href="https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/4616818613">rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/4616818613”}



298
299
300
301
302
303
304
305
306
307
308
# File 'lib/rally_api/rally_rest_json.rb', line 298

def rank_above(ref_to_rank, relative_ref)
  ref = ref_to_rank
  params = {}
  params[:rankAbove] = short_ref(relative_ref)
  params[:fetch] = "true"
  json_update = { get_type_from_ref(ref_to_rank) => {"_ref" => ref_to_rank} }
  args = { :method => :put, :payload => json_update }
  #update = @rally_connection.put_object(ref, args, params, json_update)
  json_response = send_request(ref, args, params)
  RallyObject.new(self, json_response["OperationResult"]["Object"], warnings(json_response))
end

#rank_below(ref_to_rank, relative_ref) ⇒ Object

ref to object.js? rankBelow=%2Fhierarchicalrequirement%2F4624552599



311
312
313
314
315
316
317
318
319
320
# File 'lib/rally_api/rally_rest_json.rb', line 311

def rank_below(ref_to_rank, relative_ref)
  ref = ref_to_rank
  params = {}
  params[:rankBelow] = short_ref(relative_ref)
  params[:fetch] = "true"
  json_update = { get_type_from_ref(ref_to_rank) => {"_ref" => ref_to_rank} }
  args = { :method => :put, :payload => json_update }
  json_response = send_request(ref, args, params)
  RallyObject.new(self, json_response["OperationResult"]["Object"], warnings(json_response))
end

#rank_to(ref_to_rank, location = "TOP") ⇒ Object



322
323
324
325
326
327
328
329
330
331
# File 'lib/rally_api/rally_rest_json.rb', line 322

def rank_to(ref_to_rank, location = "TOP")
  ref = ref_to_rank
  params = {}
  params[:rankTo] = location
  params[:fetch]  = "true"
  json_update = { get_type_from_ref(ref_to_rank) => {"_ref" => ref_to_rank} }
  args = { :method => :put, :payload => json_update }
  json_response = send_request(ref, args, params)
  RallyObject.new(self, json_response["OperationResult"]["Object"], warnings(json_response))
end

#read(type, obj_id, params = {}) ⇒ Object



194
195
196
197
198
199
200
201
202
# File 'lib/rally_api/rally_rest_json.rb', line 194

def read(type, obj_id, params = {})
  type = check_type(type)
  ref = check_id(type.to_s, obj_id)
  params[:workspace] = rally_workspace_object.ref if params[:workspace].nil?
  args = { :method => :get }
  json_response = send_request(ref, args, params)
  rally_type = json_response.keys[0]
  RallyObject.new(self, json_response[rally_type], warnings(json_response))
end

#read_collection(collection_hash, params = {}) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
# File 'lib/rally_api/rally_rest_json.rb', line 222

def read_collection(collection_hash, params = {})
  collection_count = collection_hash['Count']
  start = 1
  pagesize = params[:pagesize] || 200
  full_collection = []
  start.step(collection_count, pagesize).each do |page_start|
    page = reread(collection_hash, {:pagesize => 200, :start => page_start})
    full_collection.concat(page["Results"])
  end
  {"Results" => full_collection}
end

#reread(json_object, params = {}) ⇒ Object



211
212
213
214
215
216
217
218
219
220
# File 'lib/rally_api/rally_rest_json.rb', line 211

def reread(json_object, params = {})
  args = { :method => :get }
  if params[:workspace].nil? && (json_object["Workspace"] && json_object["Workspace"]["_ref"])
    params[:workspace] = json_object['Workspace']['_ref']
  end
  #json_response = @rally_connection.read_object(json_object["_ref"], args, params)
  json_response = send_request(json_object["_ref"], args, params)
  rally_type = json_response.keys[0]
  json_response[rally_type]
end

#send_request(url = nil, args = nil, params = {}) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rally_api/rally_rest_json.rb', line 98

def send_request(url = nil, args = nil, params = {})
  url += '.js' if @wsapi_version !~ /^v2/ && url !~ /\.js$/  # append ".js" if it is needed
  if params[:workspace].nil? && rally_workspace_object
    params[:workspace] = rally_workspace_object['_ref']
  end
  if params[:workspace]
    wksp_id = params[:workspace].match(/workspace\/(\d*)/)[1]
    url += "?workspace=workspace/#{wksp_id}"
  end
  @rally_connection.send_request(url, args, params)
end

#update(type, obj_id, fields, params = {}) ⇒ Object Also known as: update_ref



234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/rally_api/rally_rest_json.rb', line 234

def update(type, obj_id, fields, params = {})
  type = check_type(type)
  ref = check_id(type.to_s, obj_id)
  fields = RallyAPI::RallyRestJson.fix_case(fields) if @rally_rest_api_compat
  update_fields = check_fields(fields)
  update_fields = adjust_for_custom(type.to_s, update_fields) if @wsapi_version =~ /^v2/
  json_update = {type.to_s => update_fields}
  args = {:method => :post, :payload => json_update}
  json_response = send_request(ref, args, params)
  #todo check for warnings on json_response["OperationResult"]
  RallyObject.new(self, reread({"_ref" => ref}), warnings(json_response))
end

#user(params = {}) ⇒ Object



166
167
168
169
170
171
# File 'lib/rally_api/rally_rest_json.rb', line 166

def user(params = {})
  args = { :method => :get }
  json_response = send_request(make_get_url("user"), args, params)
  rally_type = json_response.keys[0]
  RallyObject.new(self, json_response[rally_type], warnings(json_response))
end