gooddata 1.0.2-java → 1.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/CONTRIBUTING.md +12 -0
  4. data/README.md +5 -2
  5. data/Rakefile +0 -1
  6. data/dev-gooddata-sso.pub.encrypted +40 -0
  7. data/gooddata.gemspec +3 -3
  8. data/lib/gooddata/connection.rb +23 -13
  9. data/lib/gooddata/helpers/data_helper.rb +0 -1
  10. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +8 -1
  11. data/lib/gooddata/lcm/actions/associate_clients.rb +8 -1
  12. data/lib/gooddata/lcm/actions/base_action.rb +10 -0
  13. data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +7 -1
  14. data/lib/gooddata/lcm/actions/collect_client_projects.rb +3 -0
  15. data/lib/gooddata/lcm/actions/collect_clients.rb +3 -1
  16. data/lib/gooddata/lcm/actions/collect_data_product.rb +10 -2
  17. data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +12 -1
  18. data/lib/gooddata/lcm/actions/collect_ldm_objects.rb +6 -2
  19. data/lib/gooddata/lcm/actions/collect_meta.rb +1 -1
  20. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +8 -1
  21. data/lib/gooddata/lcm/actions/collect_segments.rb +6 -5
  22. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +1 -1
  23. data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +10 -4
  24. data/lib/gooddata/lcm/actions/create_segment_masters.rb +12 -2
  25. data/lib/gooddata/lcm/actions/ensure_data_product.rb +10 -0
  26. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -1
  27. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +3 -0
  28. data/lib/gooddata/lcm/actions/execute_schedules.rb +10 -0
  29. data/lib/gooddata/lcm/actions/import_object_collections.rb +1 -1
  30. data/lib/gooddata/lcm/actions/provision_clients.rb +12 -2
  31. data/lib/gooddata/lcm/actions/purge_clients.rb +2 -0
  32. data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +3 -0
  33. data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +4 -1
  34. data/lib/gooddata/lcm/actions/synchronize_cas.rb +7 -1
  35. data/lib/gooddata/lcm/actions/synchronize_clients.rb +11 -1
  36. data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +7 -1
  37. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +12 -7
  38. data/lib/gooddata/lcm/actions/synchronize_label_types.rb +4 -1
  39. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +18 -7
  40. data/lib/gooddata/lcm/actions/synchronize_meta.rb +9 -0
  41. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +11 -1
  42. data/lib/gooddata/lcm/actions/synchronize_processes.rb +7 -1
  43. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +4 -1
  44. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +6 -0
  45. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +60 -15
  46. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +7 -1
  47. data/lib/gooddata/lcm/actions/synchronize_users.rb +106 -3
  48. data/lib/gooddata/lcm/actions/update_release_table.rb +19 -0
  49. data/lib/gooddata/lcm/helpers/check_helper.rb +21 -6
  50. data/lib/gooddata/lcm/lcm2.rb +35 -22
  51. data/lib/gooddata/lcm/types/class/gd_logger.rb +23 -0
  52. data/lib/gooddata/lcm/types/class/gd_product.rb +23 -0
  53. data/lib/gooddata/lcm/types/class/gd_project.rb +23 -0
  54. data/lib/gooddata/lcm/types/class/smart_hash.rb +23 -0
  55. data/lib/gooddata/lcm/types/complex/segment.rb +1 -1
  56. data/lib/gooddata/lcm/types/scalar/integer.rb +2 -2
  57. data/lib/gooddata/lcm/types/special/any.rb +18 -0
  58. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +1 -1
  59. data/lib/gooddata/models/blueprint/to_manifest.rb +1 -3
  60. data/lib/gooddata/models/blueprint/to_wire.rb +2 -1
  61. data/lib/gooddata/models/from_wire.rb +13 -1
  62. data/lib/gooddata/models/metadata/folder.rb +22 -0
  63. data/lib/gooddata/models/metadata/metric.rb +5 -8
  64. data/lib/gooddata/models/model.rb +1 -1
  65. data/lib/gooddata/models/process.rb +42 -32
  66. data/lib/gooddata/models/project.rb +19 -36
  67. data/lib/gooddata/models/project_creator.rb +3 -1
  68. data/lib/gooddata/models/project_role.rb +3 -4
  69. data/lib/gooddata/models/schedule.rb +0 -2
  70. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +9 -1
  71. data/lib/gooddata/models/user_filters/user_filter.rb +1 -2
  72. data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -6
  73. data/lib/gooddata/rest/client.rb +1 -2
  74. data/lib/gooddata/rest/connection.rb +12 -46
  75. data/lib/gooddata/rest/phmap.rb +101 -56
  76. data/lib/gooddata/version.rb +1 -1
  77. data/rubydev_public.gpg.encrypted +51 -0
  78. data/rubydev_secret_keys.gpg.encrypted +109 -0
  79. data/spec/data/user_filters.csv +2 -0
  80. data/spec/environment/default.rb +2 -2
  81. data/spec/environment/development.rb +1 -1
  82. data/spec/environment/staging.rb +2 -3
  83. data/spec/environment/testing.rb +4 -4
  84. data/spec/integration/connection_spec.rb +37 -0
  85. data/spec/integration/core/connection_spec.rb +1 -1
  86. data/spec/integration/core/logging_spec.rb +8 -6
  87. data/spec/integration/core/project_spec.rb +1 -1
  88. data/spec/integration/mandatory_user_filter_spec.rb +53 -0
  89. data/spec/integration/mixins/id_to_uri_spec.rb +17 -5
  90. data/spec/integration/models/label_spec.rb +9 -0
  91. data/spec/integration/models/metric_spec.rb +24 -0
  92. data/spec/integration/models/process_spec.rb +35 -0
  93. data/spec/integration/models/project_role_spec.rb +1 -1
  94. data/spec/integration/models/schedule_spec.rb +0 -8
  95. data/spec/integration/schedule_spec.rb +4 -6
  96. data/spec/integration/user_filters_spec.rb +20 -16
  97. data/spec/integration/user_group_spec.rb +1 -1
  98. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/can_assign_a_custom_logger.yml +2287 -0
  99. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/client_logs_when_given_custom_message.yml +2287 -0
  100. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/has_the_request_id_logged_when_I_passed_it.yml +2287 -0
  101. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_off/Disables_logging.yml +2287 -0
  102. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_on/Enables_logging.yml +2287 -0
  103. data/spec/integration/vcr_cassettes/GoodData_-_project/_project/Returns_project_assigned.yml +354 -0
  104. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_nil.yml +299 -0
  105. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_directly.yml +354 -0
  106. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_ID.yml +354 -0
  107. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_URL.yml +354 -0
  108. data/spec/integration/vcr_cassettes/GoodData_-_project/_with_project/Uses_project_specified.yml +354 -0
  109. data/spec/integration/vcr_cassettes/GoodData_Metric/all.yml +2065 -0
  110. data/spec/integration/vcr_cassettes/GoodData_Metric/should_be_able_to_update_folders.yml +119 -0
  111. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/all.yml +9812 -0
  112. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_get_json_containing_correct_id.yml +174 -0
  113. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_return_nil_for_unknown_id.yml +58 -0
  114. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_throw_BadRequest_for_-1.yml +63 -0
  115. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_connect/Connects_using_username_and_password.yml +299 -0
  116. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_disconnect/Connects_using_username_and_password.yml +299 -0
  117. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_generate_request_id/Generates_a_non-empty_string.yml +2287 -0
  118. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_/Should_list_user_groups_as_Array.yml +56 -0
  119. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_add_members/Should_add_member.yml +315 -0
  120. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_members/Should_return_members_as_array.yml +54 -0
  121. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_remove_members/Should_remove_existing_members.yml +258 -0
  122. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_save/updates_existing_group.yml +159 -0
  123. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_set_members/Should_set_new_members.yml +158 -0
  124. data/spec/integration/vcr_cassettes/GoodData_UserGroup/all.yml +809 -0
  125. data/spec/spec_helper.rb +46 -2
  126. data/spec/unit/actions/associate_clients_spec.rb +2 -1
  127. data/spec/unit/actions/collect_data_product_spec.rb +3 -1
  128. data/spec/unit/actions/collect_segment_clients_spec.rb +1 -0
  129. data/spec/unit/actions/create_segment_masters_spec.rb +1 -0
  130. data/spec/unit/actions/ensure_data_product_spec.rb +1 -0
  131. data/spec/unit/actions/ensure_technical_users_domain_spec.rb +2 -0
  132. data/spec/unit/actions/ensure_technical_users_project_spec.rb +4 -0
  133. data/spec/unit/actions/provision_clients_spec.rb +2 -1
  134. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +0 -6
  135. data/spec/unit/actions/synchronize_ldm_spec.rb +20 -7
  136. data/spec/unit/actions/synchronize_user_filters_spec.rb +21 -0
  137. data/spec/unit/helpers/check_helper_production_spec.rb +34 -0
  138. data/spec/unit/helpers/check_helper_spec.rb +97 -9
  139. data/spec/unit/lcm/lcm2_spec.rb +67 -3
  140. data/spec/unit/models/blueprint/to_wire_spec.rb +1 -0
  141. data/spec/unit/models/dataset_blueprint.rb +14 -0
  142. data/spec/unit/models/from_wire_spec.rb +20 -0
  143. data/spec/unit/models/model_spec.rb +10 -0
  144. data/spec/unit/models/to_manifest_spec.rb +29 -0
  145. data/spec/unit/models/user_filters/user_filter_builder_spec.rb +44 -6
  146. data/spec/unit/rest/phmap_spec.rb +117 -0
  147. data/spec/vcr_configurer.rb +63 -0
  148. metadata +283 -24
  149. data/lib/gooddata/lcm/actions/ensure_segments.rb +0 -32
@@ -264,6 +264,9 @@ module GoodData
264
264
  to_process = if process.path
265
265
  to_process.delete if to_process
266
266
  GoodData::Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project)
267
+ elsif process.component
268
+ to_process.delete if to_process
269
+ GoodData::Process.deploy_component(GoodData::Helpers.symbolize_keys(process.to_hash), project: to_project, client: to_project.client)
267
270
  else
268
271
  Dir.mktmpdir('etl_transfer') do |dir|
269
272
  dir = Pathname(dir)
@@ -1172,22 +1175,15 @@ module GoodData
1172
1175
  # @return [String] Returns token that you can use as input for object_import
1173
1176
  def objects_export(objs, options = {})
1174
1177
  fail 'Nothing to migrate. You have to pass list of objects, ids or uris that you would like to migrate' if objs.nil?
1175
- objs = Array(objs)
1178
+ objs = Array(objs).map { |o| o.respond_to?(:uri) ? o.uri : o }
1176
1179
  if objs.empty?
1177
1180
  GoodData.logger.warn 'Nothing to migrate.'
1178
1181
  return
1179
1182
  end
1180
1183
 
1181
- objs = objs.pmap { |obj| [obj, objects(obj)] }
1182
- if objs.any? { |_, obj| obj.nil? }
1183
- object = objs.select { |_, obj| obj.nil? }.map { |o, _| o }.join(', ')
1184
- error_message = "Exporting objects failed with messages. " \
1185
- "Object #{object} could not be found."
1186
- fail ObjectsExportError, error_message
1187
- end
1188
1184
  export_payload = {
1189
1185
  :partialMDExport => {
1190
- :uris => objs.map { |_, obj| obj.uri },
1186
+ :uris => objs,
1191
1187
  :exportAttributeProperties => '1',
1192
1188
  :crossDataCenterExport => '1'
1193
1189
  }
@@ -1259,32 +1255,21 @@ module GoodData
1259
1255
  if projects.is_a?(Array)
1260
1256
  projects.each_slice(batch_size).flat_map do |batch|
1261
1257
  batch.pmap do |proj|
1262
- begin
1263
- target_project = client.projects(proj)
1264
- target_project.objects_import(token, options)
1265
- {
1266
- project: target_project,
1267
- result: true
1268
- }
1269
- rescue RestClient::Exception => e
1270
- {
1271
- project: proj,
1272
- exception: e,
1273
- result: false,
1274
- reason: GoodData::Helpers.interpolate_error_message(MultiJson.load(e.response))
1275
- }
1276
- rescue GoodData::ObjectsImportError => e
1277
- {
1278
- project: target_project,
1279
- result: false,
1280
- reason: e.message
1281
- }
1282
- end
1258
+ target_project = client.projects(proj)
1259
+ target_project.objects_import(token, options)
1260
+ {
1261
+ project: target_project,
1262
+ result: true
1263
+ }
1283
1264
  end
1284
1265
  end
1285
1266
  else
1286
1267
  target_project = client.projects(projects)
1287
1268
  target_project.objects_import(token, options)
1269
+ [{
1270
+ project: target_project,
1271
+ result: true
1272
+ }]
1288
1273
  end
1289
1274
  end
1290
1275
 
@@ -1464,12 +1449,10 @@ module GoodData
1464
1449
  #
1465
1450
  # @return [Array<GoodData::ProjectRole>] List of roles
1466
1451
  def roles
1467
- url = "/gdc/projects/#{pid}/roles"
1468
-
1469
- tmp = client.get(url)
1470
- tmp['projectRoles']['roles'].pmap do |role_url|
1471
- json = client.get role_url
1472
- client.create(GoodData::ProjectRole, json, project: self)
1452
+ url = "/gdc/internal/projects/#{pid}/roles"
1453
+ res = client.get url
1454
+ res['internalProjectRoles']['roles'].map do |r|
1455
+ client.create(GoodData::ProjectRole, r, project: self)
1473
1456
  end
1474
1457
  end
1475
1458
 
@@ -42,7 +42,9 @@ module GoodData
42
42
  _, project = GoodData.get_client_and_project(opts)
43
43
 
44
44
  bp = ProjectBlueprint.new(spec)
45
- response = project.maql_diff(blueprint: bp, params: [:includeGrain])
45
+ maql_diff_params = [:includeGrain]
46
+ maql_diff_params << :excludeFactRule if opts[:exclude_fact_rule]
47
+ response = project.maql_diff(blueprint: bp, params: maql_diff_params)
46
48
 
47
49
  GoodData.logger.debug("projectModelDiff") { response.pretty_inspect }
48
50
  chunks = response['projectModelDiff']['updateScripts']
@@ -33,6 +33,7 @@ module GoodData
33
33
  d[:updated] = data[:updated] || d[:created] || Time.now
34
34
  d[:title] = data[:title]
35
35
  d[:summary] = data[:summary]
36
+ d[:uri] = data[:uri]
36
37
  end
37
38
  new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
38
39
  d['projectRole']['links']['self'] = data[:uri] if data[:uri]
@@ -54,7 +55,7 @@ module GoodData
54
55
  #
55
56
  # @return [Array<GoodData::Profile>] List of users
56
57
  def users
57
- url = data['links']['roleUsers']
58
+ url = uri + '/users'
58
59
  tmp = client.get url
59
60
  tmp['associatedUsers']['users'].pmap do |user_url|
60
61
  url = user_url
@@ -67,9 +68,7 @@ module GoodData
67
68
  #
68
69
  # @return [string] URI of this project role
69
70
  def uri
70
- return @json['projectRole']['links']['self'] if @json['projectRole']['links']['self']
71
- return nil unless @json['projectRole']['links']['roleUsers']
72
- @json['projectRole']['links']['roleUsers'].split('/')[0...-1].join('/')
71
+ @json['projectRole']['meta']['uri']
73
72
  end
74
73
 
75
74
  def ==(other)
@@ -77,7 +77,6 @@ module GoodData
77
77
  else
78
78
  fail 'Executable has to be provided' if executable.blank?
79
79
  end
80
- fail 'Trigger schedule has to be provided' if trigger.blank?
81
80
 
82
81
  schedule = c.create(GoodData::Schedule, GoodData::Helpers.stringify_keys(GoodData::Helpers.deep_dup(SCHEDULE_TEMPLATE)), client: c, project: project)
83
82
 
@@ -403,7 +402,6 @@ module GoodData
403
402
  #
404
403
  # @return [Boolean] True if saved
405
404
  def save
406
- fail 'trigger schedule has to be provided' if cron.blank? && trigger_id.blank?
407
405
  fail 'A timezone has to be provided' if timezone.blank?
408
406
  fail 'Schedule type has to be provided' if schedule_type.blank?
409
407
  rewrite_deprecated_params
@@ -28,7 +28,7 @@ module GoodData
28
28
  result = c.get("/gdc/md/#{project.pid}/userfilters?count=#{count}&offset=#{offset}")
29
29
  result['userFilters']['items'].each do |item|
30
30
  item['userFilters'].each do |f|
31
- user_lookup[f] = item['user']
31
+ user_lookup[f] = user_lookup[f] ? Array(user_lookup[f]).concat([item['user']]) : item['user']
32
32
  end
33
33
  end
34
34
  break if result['userFilters']['length'] < offset
@@ -72,5 +72,13 @@ module GoodData
72
72
  res = client.post(project.md['obj'], data)
73
73
  @json[:uri] = res['uri']
74
74
  end
75
+
76
+ def related
77
+ if related_uri.is_a? Array
78
+ related_uri.map { |u| super u }
79
+ else
80
+ super
81
+ end
82
+ end
75
83
  end
76
84
  end
@@ -30,8 +30,7 @@ module GoodData
30
30
  # Returns the the object of this filter is related to. It can be either project or a user
31
31
  #
32
32
  # @return [GoodData::Project | GoodData::Profile] Related object
33
- def related
34
- uri = related_uri
33
+ def related(uri = related_uri)
35
34
  return unless uri
36
35
  level == :project ? client.projects(uri) : client.create(GoodData::Profile, client.get(uri))
37
36
  end
@@ -5,6 +5,7 @@
5
5
  # LICENSE file in the root directory of this source tree.
6
6
 
7
7
  require_relative '../project_log_formatter'
8
+ require 'active_support/core_ext/hash/indifferent_access'
8
9
 
9
10
  module GoodData
10
11
  module UserFilterBuilder
@@ -270,10 +271,10 @@ module GoodData
270
271
  attrs_cache = create_attrs_cache(filters, options)
271
272
  create_filter_proc = proc do |login, f|
272
273
  expression, errors = create_expression(f, labels_cache, lookups_cache, attrs_cache, options)
274
+ safe_login = login.downcase
273
275
  profiles_uri = if options[:type] == :muf
274
276
  project_user = project_users.find { |u| u.login == login }
275
-
276
- project_user.nil? ? ('/gdc/account/profile/' + login) : project_user.profile_url
277
+ project_user.nil? ? ('/gdc/account/profile/' + safe_login) : project_user.profile_url
277
278
  elsif options[:type] == :variable
278
279
  (users_cache[login] && users_cache[login].uri)
279
280
  else
@@ -384,7 +385,14 @@ module GoodData
384
385
  else
385
386
  GoodData.logger.warn("Data permissions computed: #{to_create.count} to create and #{to_delete.count} to delete")
386
387
  end
387
- return { created: to_create, deleted: to_delete } if dry_run
388
+
389
+ if dry_run
390
+ create_results = to_create.map { |x| { status: 'dry_run', user: x.first, type: 'create' } }
391
+ delete_results = to_delete.map { |x| { status: 'dry_run', user: x.first, type: 'delete' } }
392
+ return { created: {},
393
+ deleted: {},
394
+ results: create_results + delete_results }
395
+ end
388
396
 
389
397
  create_results = to_create.each_slice(100).flat_map do |batch|
390
398
  batch.pmapcat do |related_uri, group|
@@ -414,6 +422,8 @@ module GoodData
414
422
  end
415
423
 
416
424
  project_log_formatter.log_user_filter_results(create_results, to_create)
425
+ create_errors = create_results.select { |r| r[:status] == :failed }
426
+ fail "Creating MUFs resulted in errors: #{create_errors}" if create_errors.any?
417
427
 
418
428
  delete_results = unless options[:do_not_touch_filters_that_are_not_mentioned]
419
429
  to_delete.each_slice(100).flat_map do |batch|
@@ -444,6 +454,8 @@ module GoodData
444
454
  end
445
455
 
446
456
  project_log_formatter.log_user_filter_results(delete_results, to_delete)
457
+ delete_errors = delete_results.select { |r| r[:status] == :failed } if delete_results
458
+ fail "Deleting MUFs resulted in errors: #{delete_errors}" if delete_errors && delete_errors.any?
447
459
 
448
460
  { created: to_create, deleted: to_delete, results: create_results + (delete_results || []) }
449
461
  end
@@ -541,13 +553,13 @@ module GoodData
541
553
  # if this does not happen, users that are about to be deleted by users_brick
542
554
  # would have all their filters removed now, which is not desirable
543
555
  def self.sanitize_filters_to_delete(to_delete, users_brick_input, project_users)
544
- return to_delete unless users_brick_input && users_brick_input.any?
556
+ return [] unless users_brick_input && users_brick_input.any?
545
557
  user_profiles = users_brick_input.map do |user|
546
- result = project_users.find { |u| u.login == user['login'] }
558
+ result = project_users.find { |u| u.login == user.with_indifferent_access['login'] }
547
559
  next unless result
548
560
  result.profile_url
549
561
  end.compact
550
- return to_delete unless user_profiles.any?
562
+ return [] unless user_profiles.any?
551
563
  to_delete.reject do |_, value|
552
564
  user_profiles.none? { |profile| profile == value.first.json[:related] }
553
565
  end
@@ -111,8 +111,7 @@ module GoodData
111
111
  end
112
112
 
113
113
  def connect_sso(sso)
114
- client = Client.new(sso)
115
- client
114
+ @@instance = Client.new(sso) # rubocop:disable ClassVars
116
115
  end
117
116
 
118
117
  def disconnect
@@ -17,48 +17,6 @@ require_relative '../helpers/global_helpers'
17
17
 
18
18
  require_relative 'phmap'
19
19
 
20
- module RestClient
21
- module AbstractResponse
22
- alias_method :old_follow_redirection, :follow_redirection
23
- def follow_redirection(request = nil, result = nil, &block)
24
- if RestClient::VERSION != '1.8.0'
25
- fail 'Using monkey patched version of RestClient::AbstractResponse#' \
26
- 'follow_redirection which is guaranteed to be compatible only ' \
27
- 'with RestClient 1.8.0'
28
- end
29
-
30
- new_args = @args.dup
31
-
32
- url = headers[:location]
33
- url = URI.parse(request.url).merge(url).to_s if url !~ /^http/
34
-
35
- new_args[:url] = url
36
- if request
37
- fail MaxRedirectsReached if request.max_redirects.zero?
38
- new_args[:password] = request.password
39
- new_args[:user] = request.user
40
- new_args[:headers] = request.headers
41
- new_args[:max_redirects] = request.max_redirects - 1
42
-
43
- # TODO: figure out what to do with original :cookie, :cookies values
44
- new_args[:cookies] = get_redirection_cookies(request, result, new_args)
45
- end
46
-
47
- Request.execute(new_args, &block)
48
- end
49
-
50
- # Returns cookies which should be passed when following redirect
51
- #
52
- # @param request [RestClient::Request] Original request
53
- # @param result [Net::HTTPResponse] Response
54
- # @param args [Hash] Original arguments
55
- # @return [Hash] Cookies to be passsed when following redirect
56
- def get_redirection_cookies(request, _result, _args)
57
- request.cookies
58
- end
59
- end
60
- end
61
-
62
20
  module GoodData
63
21
  module Rest
64
22
  class RestRetryError < StandardError
@@ -210,13 +168,23 @@ module GoodData
210
168
 
211
169
  # Reset old cookies first
212
170
  if options[:sst_token]
213
- merge_headers!(:x_gdc_authsst => options[:sst_token])
171
+ headers = {
172
+ :x_gdc_authsst => options[:sst_token],
173
+ :x_gdc_authtt => options[:tt_token]
174
+ }
175
+ merge_headers!(headers)
214
176
  get('/gdc/account/token', @request_params)
215
177
 
216
178
  @user = get(get('/gdc/app/account/bootstrap')['bootstrapResource']['accountSetting']['links']['self'])
217
179
  GoodData.logger.info("Connected using SST to server #{@server.url} to profile \"#{@user['accountSetting']['login']}\"")
218
180
  @auth = {}
219
181
  refresh_token :dont_reauth => true
182
+ elsif options[:headers][:x_gdc_authsst]
183
+ @request_params = options[:headers]
184
+ @user = get('/gdc/app/account/bootstrap')['bootstrapResource']
185
+ GoodData.logger.info("Connected using SST to server #{@server.url} to profile \"#{@user['accountSetting']['login']}\"")
186
+ @auth = {}
187
+ refresh_token :dont_reauth => true
220
188
  else
221
189
  GoodData.logger.info("Connected using username \"#{username}\" to server #{@server.url}")
222
190
  credentials = Connection.construct_login_payload(username, password)
@@ -656,9 +624,7 @@ ERR
656
624
  placeholders = true
657
625
 
658
626
  if placeholders
659
- PH_MAP.each do |pm|
660
- break if title.gsub!(pm[1], pm[0])
661
- end
627
+ title = self.class.map_placeholders(title)
662
628
  end
663
629
 
664
630
  stat = stats[title]
@@ -7,74 +7,119 @@
7
7
  module GoodData
8
8
  module Rest
9
9
  class Connection
10
+ def self.map_placeholders(title)
11
+ PH_MAP.each do |pm|
12
+ break if title.gsub!(pm[1], pm[0])
13
+ end
14
+ title
15
+ end
16
+
10
17
  # PH_MAP for wildcarding of URLs in reports
11
18
  PH_MAP = [
12
- ['/gdc/account/profile/{id}', %r{/gdc/account/profile/[\w]+}],
13
- ['/gdc/account/login/{id}', %r{/gdc/account/login/[\w]+}],
14
- ['/gdc/account/domains/{id}/users?login={login}', %r{/gdc/account/domains/[\w\d-]+/users\?login=[^&$]+}],
15
- ['/gdc/account/domains/{id}', %r{/gdc/account/domains/[\w\d-]+}],
19
+ ['/gdc/projects/{id}/execute', %r{/gdc/projects/[^\/]+/execute}],
20
+
21
+ ['/gdc/dataload/projects/{id}/outputStage', %r{/gdc/dataload/projects/[^\/]+/outputStage}],
22
+
23
+ ['/gdc/datawarehouse/instances/{id}', %r{/gdc/datawarehouse/instances/[^\/]+}],
24
+ ['/gdc/datawarehouse/executions/{id}', %r{/gdc/datawarehouse/executions/[^\/]+}],
16
25
 
17
- ['/gdc/projects/{id}/execute', %r{/gdc/projects/[\w]+/execute}],
26
+ # domain dataproducts' clients
27
+ ['/gdc/domains/{id}/dataproducts/{data_product}/clients?segment={segment}',
28
+ %r{\/gdc\/domains\/[^\/]+\/dataproducts\/[^\/]+\/clients\?.*segment=[^\/]+}],
29
+ ['/gdc/domains/{id}/dataproducts/{data_product}/clients/{client}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/clients/[^\/]+}],
30
+ ['/gdc/domains/{id}/dataproducts/{data_product}/clients', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/clients}],
18
31
 
19
- ['/gdc/datawarehouse/instances/{id}', %r{/gdc/datawarehouse/instances/[\w]+}],
20
- ['/gdc/datawarehouse/executions/{id}', %r{/gdc/datawarehouse/executions/[\w]+}],
32
+ # domain dataproducts' segments
33
+ ['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
34
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
35
+ ['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}/synchronizeClients/results/{result}',
36
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+}],
37
+ ['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+}],
38
+ ['/gdc/domains/{id}/dataproducts/{data_product}/segments', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments}],
21
39
 
40
+ # domain dataproducts' provision & update
41
+ ['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects/results/{result}/details?offset={offset}&limit={limit}',
42
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
43
+ ['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects/results/{result}',
44
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects/results/[^\/]+}],
45
+ ['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects',
46
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects}],
47
+ ['/gdc/domains/{id}/dataproducts/{data_product}/updateClients?deleteExtraInSegments={segments}',
48
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/updateClients\?deleteExtraInSegments=[^\/]+}],
49
+ ['/gdc/domains/{id}/dataproducts/{data_product}/updateClients',
50
+ %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/updateClients}],
51
+
52
+ # domain dataproduct
53
+ ['/gdc/domains/{id}/dataproducts/{data_product}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+}],
54
+ ['/gdc/domains/{id}/dataproducts', %r{/gdc/domains/[^\/]+/dataproducts}],
55
+
56
+ # domain segments
22
57
  ['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
23
- %r{/gdc/domains/[\w-]+/segments/[\w-]+/synchronizeClients/results/[\w]+/details/\?offset=[\d]+&limit=[\d]+}],
58
+ %r{/gdc/domains/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
24
59
  ['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}',
25
- %r{/gdc/domains/[\w-]+/segments/[\w-]+/synchronizeClients/results/[\w]+}],
26
- ['/gdc/domains/{id}/segments/{segment}/', %r{/gdc/domains/[\w-]+/segments/[\w-]+/}],
27
- ['/gdc/domains/{id}/segments/{segment}', %r{/gdc/domains/[\w-]+/segments/[\w-]+}],
28
- ['/gdc/domains/{id}/clients?segment={segment}', %r{/gdc/domains/[\w-]+/clients\?segment=[\w-]+}],
29
- ['/gdc/domains/{id}/clients/{client_id}/settings/lcm.title', %r{/gdc/domains/[\w-]+/clients/[\w-]+/settings/lcm.title}],
30
- ['/gdc/domains/{id}/clients/{client_id}/settings/lcm.token', %r{/gdc/domains/[\w-]+/clients/[\w-]+/settings/lcm.token}],
31
- ['/gdc/domains/{id}/clients/{client_id}', %r{/gdc/domains/[\w-]+/clients/[\w-]+}],
60
+ %r{/gdc/domains/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+}],
61
+ ['/gdc/domains/{id}/segments/{segment}/', %r{/gdc/domains/[^\/]+/segments/[^\/]+/}],
62
+ ['/gdc/domains/{id}/segments/{segment}', %r{/gdc/domains/[^\/]+/segments/[^\/]+}],
63
+
64
+ # domain clients
65
+ ['/gdc/domains/{id}/clients?segment={segment}', %r{/gdc/domains/[^\/]+/clients\?segment=[^\/]+}],
66
+ ['/gdc/domains/{id}/clients/{client_id}/settings/lcm.title', %r{/gdc/domains/[^\/]+/clients/[^\/]+/settings/lcm.title}],
67
+ ['/gdc/domains/{id}/clients/{client_id}/settings/lcm.token', %r{/gdc/domains/[^\/]+/clients/[^\/]+/settings/lcm.token}],
68
+ ['/gdc/domains/{id}/clients/{client_id}', %r{/gdc/domains/[^\/]+/clients/[^\/]+}],
32
69
  ['/gdc/domains/{id}/provisionClientProjects/results/{result}/details?offset={offset}&limit={limit}',
33
- %r{/gdc/domains/[\w-]+/provisionClientProjects/results/[\w]+/details/\?offset=[\d]+&limit=[\d]+}],
34
- ['/gdc/domains/{id}/provisionClientProjects/results/{result}', %r{/gdc/domains/[\w-]+/provisionClientProjects/results/[\w]+}],
35
- ['/gdc/domains/{id}/provisionClientProjects', %r{/gdc/domains/[\w-]+/provisionClientProjects}],
36
- ['/gdc/domains/{id}/updateClients', %r{/gdc/domains/[\w-]+/updateClients}],
37
- ['/gdc/domains/{id}/', %r{/gdc/domains/[\w-]+/}],
70
+ %r{/gdc/domains/[^\/]+/provisionClientProjects/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
71
+ ['/gdc/domains/{id}/provisionClientProjects/results/{result}', %r{/gdc/domains/[^\/]+/provisionClientProjects/results/[^\/]+}],
72
+ ['/gdc/domains/{id}/provisionClientProjects', %r{/gdc/domains/[^\/]+/provisionClientProjects}],
73
+ ['/gdc/domains/{id}/updateClients', %r{/gdc/domains/[^\/]+/updateClients}],
74
+ ['/gdc/domains/{id}/', %r{/gdc/domains/[^\/]+/}],
38
75
 
39
- ['/gdc/exporter/result/{id}/{id}', %r{/gdc/exporter/result/[\w]+/[\w]+}],
76
+ ['/gdc/exporter/result/{id}/{id}', %r{/gdc/exporter/result/[^\/]+/[^\/]+}],
40
77
 
41
78
  ['/gdc/internal/lcm/domains/{id}/dataproducts/{data_product}/segments/{segment}/syncProcesses/{process}',
42
- %r{/gdc/internal/lcm/domains/[\w-]+/dataproducts/[\w-]+/segments/[\w-]+/syncProcesses/[\w]+}],
79
+ %r{/gdc/internal/lcm/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/syncProcesses/[^\/]+}],
43
80
  ['/gdc/internal/lcm/domains/{id}/dataproducts/{data_product}/segments/{segment}/syncProcesses',
44
- %r{/gdc/internal/lcm/domains/[\w-]+/dataproducts/[\w-]+/segments/[\w-]+/syncProcesses}],
45
-
46
- ['/gdc/internal/projects/{id}/objects/setPermissions', %r{/gdc/internal/projects/[\w]+/objects/setPermissions}],
47
-
48
- ['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[\w]+/variables/item/[\d]+}],
49
- ['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[\w]+/validate/task/[\w]+}],
50
- ['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[\w]+/using2/[\d]+/[\d]+}],
51
- ['/gdc/md/{id}/using2/{id}', %r{/gdc/md/[\w]+/using2/[\d]+}],
52
- ['/gdc/md/{id}/userfilters?users={users}', %r{/gdc/md/[\w]+/userfilters\?users=[/\w]+}],
53
- ['/gdc/md/{id}/userfilters?count={count}&offset={offset}', %r{/gdc/md/[\w]+/userfilters\?count=[\d]+&offset=[\d]+}],
54
- ['/gdc/md/{id}/usedby2/{id}/{id}', %r{/gdc/md/[\w]+/usedby2/[\d]+/[\d]+}],
55
- ['/gdc/md/{id}/usedby2/{id}', %r{/gdc/md/[\w]+/usedby2/[\d]+}],
56
- ['/gdc/md/{id}/tasks/{id}/status', %r{/gdc/md/[\w]+/tasks/[\w]+/status}],
57
- ['/gdc/md/{id}/obj/{id}/validElements', %r{/gdc/md/[\w]+/obj/[\d]+/validElements(/)?(\?.*)?}],
58
- ['/gdc/md/{id}/obj/{id}/elements', %r{/gdc/md/[\w]+/obj/[\d]+/elements(/)?(\?.*)?}],
59
- ['/gdc/md/{id}/obj/{id}', %r{/gdc/md/[\w]+/obj/[\d]+}],
60
- ['/gdc/md/{id}/etltask/{id}', %r{/gdc/md/[\w]+/etltask/[\w]+}],
61
- ['/gdc/md/{id}/dataResult/{id}', %r{/gdc/md/[\w]+/dataResult/[\d]+}],
62
- ['/gdc/md/{id}', %r{/gdc/md/[\w]+}],
63
-
64
- ['/gdc/projects/{id}/users/{id}/roles', %r{/gdc/projects/[\w]+/users/[\w]+/roles}],
65
- ['/gdc/projects/{id}/users/{id}/permissions', %r{/gdc/projects/[\w]+/users/[\w]+/permissions}],
66
- ['/gdc/projects/{id}/users', %r{/gdc/projects/[\w]+/users}],
67
- ['/gdc/projects/{id}/schedules/{id}/executions/{id}', %r{/gdc/projects/[\w]+/schedules/[\w]+/executions/[\w]+}],
68
- ['/gdc/projects/{id}/schedules/{id}', %r{/gdc/projects/[\w]+/schedules/[\w]+}],
69
- ['/gdc/projects/{id}/roles/{id}', %r{/gdc/projects/[\w]+/roles/[\d]+}],
70
- ['/gdc/projects/{id}/model/view/{id}', %r{/gdc/projects/[\w]+/model/view/[\w]+}],
71
- ['/gdc/projects/{id}/model/view', %r{/gdc/projects/[\w]+/model/view}],
72
- ['/gdc/projects/{id}/model/diff/{id}', %r{/gdc/projects/[\w]+/model/diff/[\w]+}],
73
- ['/gdc/projects/{id}/model/diff', %r{/gdc/projects/[\w]+/model/diff}],
74
- ['/gdc/projects/{id}/dataload/processes/{id}/executions/{id}', %r{/gdc/projects/[\w]+/dataload/processes/[\w-]+/executions/[\w-]+}],
75
- ['/gdc/projects/{id}/dataload/processes/{id}', %r{/gdc/projects/[\w]+/dataload/processes/[\w-]+}],
76
- ['/gdc/projects/{id}/', %r{/gdc/projects/[\w]+/}],
77
- ['/gdc/projects/{id}', %r{/gdc/projects/[\w]+}]
81
+ %r{/gdc/internal/lcm/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/syncProcesses}],
82
+
83
+ ['/gdc/internal/projects/{id}/objects/setPermissions', %r{/gdc/internal/projects/[^\/]+/objects/setPermissions}],
84
+
85
+ ['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[^\/]+/variables/item/[\d]+}],
86
+ ['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[^\/]+/validate/task/[^\/]+}],
87
+ ['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+/[\d]+}],
88
+ ['/gdc/md/{id}/using2/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+}],
89
+ ['/gdc/md/{id}/userfilters?users={users}', %r{\/gdc\/md\/[^\/]+\/userfilters\?users=[\/\w+@.]+}],
90
+ ['/gdc/md/{id}/userfilters?count={count}&offset={offset}', %r{/gdc/md/[^\/]+/userfilters\?count=[\d]+&offset=[\d]+}],
91
+ ['/gdc/md/{id}/usedby2/{id}/{id}', %r{/gdc/md/[^\/]+/usedby2/[\d]+/[\d]+}],
92
+ ['/gdc/md/{id}/usedby2/{id}', %r{/gdc/md/[^\/]+/usedby2/[\d]+}],
93
+ ['/gdc/md/{id}/tasks/{id}/status', %r{/gdc/md/[^\/]+/tasks/[^\/]+/status}],
94
+ ['/gdc/md/{id}/obj/{id}/validElements', %r{/gdc/md/[^\/]+/obj/[\d]+/validElements(/)?(\?.*)?}],
95
+ ['/gdc/md/{id}/obj/{id}/elements', %r{/gdc/md/[^\/]+/obj/[\d]+/elements(/)?(\?.*)?}],
96
+ ['/gdc/md/{id}/obj/{id}', %r{/gdc/md/[^\/]+/obj/[\d]+}],
97
+ ['/gdc/md/{id}/etltask/{id}', %r{/gdc/md/[^\/]+/etltask/[^\/]+}],
98
+ ['/gdc/md/{id}/dataResult/{id}', %r{/gdc/md/[^\/]+/dataResult/[\d]+}],
99
+ ['/gdc/md/{id}', %r{/gdc/md/[^\/]+}],
100
+
101
+ ['/gdc/projects/{id}/users/{id}/roles', %r{/gdc/projects/[^\/]+/users/[^\/]+/roles}],
102
+ ['/gdc/projects/{id}/users/{id}/permissions', %r{/gdc/projects/[^\/]+/users/[^\/]+/permissions}],
103
+ ['/gdc/projects/{id}/users', %r{/gdc/projects/[^\/]+/users}],
104
+ ['/gdc/projects/{id}/schedules/{id}/executions/{id}', %r{/gdc/projects/[^\/]+/schedules/[^\/]+/executions/[^\/]+}],
105
+ ['/gdc/projects/{id}/schedules/{id}', %r{/gdc/projects/[^\/]+/schedules/[^\/]+}],
106
+ ['/gdc/projects/{id}/roles/{id}', %r{/gdc/projects/[^\/]+/roles/[\d]+}],
107
+ ['/gdc/projects/{id}/model/view/{id}', %r{/gdc/projects/[^\/]+/model/view/[^\/]+}],
108
+ ['/gdc/projects/{id}/model/view', %r{/gdc/projects/[^\/]+/model/view}],
109
+ ['/gdc/projects/{id}/model/diff/{id}', %r{/gdc/projects/[^\/]+/model/diff/[^\/]+}],
110
+ ['/gdc/projects/{id}/model/diff', %r{/gdc/projects/[^\/]+/model/diff}],
111
+ ['/gdc/projects/{id}/dataload/metadata/{project}', %r{/gdc/projects/[^\/]+/dataload/metadata/[^\/]+}],
112
+ ['/gdc/projects/{id}/dataload/processes/{id}/executions/{id}', %r{/gdc/projects/[^\/]+/dataload/processes/[^\/]+/executions/[^\/]+}],
113
+ ['/gdc/projects/{id}/dataload/processes/{id}', %r{/gdc/projects/[^\/]+/dataload/processes/[^\/]+}],
114
+ ['/gdc/projects/{id}/', %r{/gdc/projects/[^\/]+/}],
115
+ ['/gdc/projects/{id}', %r{/gdc/projects/[^\/]+}],
116
+
117
+ ['/gdc/userGroups/{id}', %r{/gdc/userGroups/[^\/]+}],
118
+
119
+ ['/gdc/account/profile/{id}', %r{/gdc/account/profile/[^\/]+}],
120
+ ['/gdc/account/login/{id}', %r{/gdc/account/login/[^\/]+}],
121
+ ['/gdc/account/domains/{id}/users?login={login}', %r{/gdc/account/domains/[^\/]+/users\?login=[^&$]+}],
122
+ ['/gdc/account/domains/{id}', %r{/gdc/account/domains/[^\/]+}]
78
123
  ]
79
124
  end
80
125
  end