gooddata 2.2.0-java → 2.3.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/.gdc-ii-config.yaml +42 -1
  3. data/.github/workflows/build.yml +14 -13
  4. data/.github/workflows/pre-merge.yml +13 -13
  5. data/.pronto.yml +1 -0
  6. data/.rubocop.yml +2 -14
  7. data/CHANGELOG.md +9 -0
  8. data/Dockerfile +13 -7
  9. data/Dockerfile.jruby +5 -5
  10. data/Dockerfile.ruby +5 -7
  11. data/Gemfile +4 -2
  12. data/README.md +5 -4
  13. data/Rakefile +1 -1
  14. data/SDK_VERSION +1 -1
  15. data/VERSION +1 -1
  16. data/bin/run_brick.rb +7 -0
  17. data/ci/mysql/pom.xml +6 -1
  18. data/ci/redshift/pom.xml +3 -4
  19. data/docker-compose.lcm.yml +42 -1
  20. data/docker-compose.yml +42 -0
  21. data/gooddata.gemspec +21 -22
  22. data/lcm.rake +9 -0
  23. data/lib/gooddata/bricks/base_pipeline.rb +26 -0
  24. data/lib/gooddata/bricks/brick.rb +0 -1
  25. data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +3 -3
  26. data/lib/gooddata/bricks/pipeline.rb +2 -14
  27. data/lib/gooddata/cloud_resources/mysql/mysql_client.rb +18 -8
  28. data/lib/gooddata/cloud_resources/redshift/drivers/.gitkeepme +0 -0
  29. data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +0 -2
  30. data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +1 -1
  31. data/lib/gooddata/lcm/actions/base_action.rb +157 -0
  32. data/lib/gooddata/lcm/actions/collect_data_product.rb +2 -1
  33. data/lib/gooddata/lcm/actions/collect_projects_warning_status.rb +53 -0
  34. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +14 -0
  35. data/lib/gooddata/lcm/actions/initialize_continue_on_error_option.rb +87 -0
  36. data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +28 -2
  37. data/lib/gooddata/lcm/actions/provision_clients.rb +34 -5
  38. data/lib/gooddata/lcm/actions/synchronize_cas.rb +24 -4
  39. data/lib/gooddata/lcm/actions/synchronize_clients.rb +56 -4
  40. data/lib/gooddata/lcm/actions/synchronize_dataset_mappings.rb +28 -3
  41. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +48 -11
  42. data/lib/gooddata/lcm/actions/synchronize_kd_dashboard_permission.rb +103 -0
  43. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +60 -15
  44. data/lib/gooddata/lcm/actions/synchronize_ldm_layout.rb +98 -0
  45. data/lib/gooddata/lcm/actions/synchronize_pp_dashboard_permission.rb +108 -0
  46. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +31 -1
  47. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +14 -9
  48. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +30 -4
  49. data/lib/gooddata/lcm/actions/synchronize_users.rb +11 -10
  50. data/lib/gooddata/lcm/actions/update_metric_formats.rb +21 -4
  51. data/lib/gooddata/lcm/exceptions/lcm_execution_warning.rb +15 -0
  52. data/lib/gooddata/lcm/helpers/check_helper.rb +19 -0
  53. data/lib/gooddata/lcm/lcm2.rb +45 -4
  54. data/lib/gooddata/lcm/user_bricks_helper.rb +9 -0
  55. data/lib/gooddata/mixins/inspector.rb +1 -1
  56. data/lib/gooddata/models/ldm_layout.rb +38 -0
  57. data/lib/gooddata/models/project.rb +197 -22
  58. data/lib/gooddata/models/project_creator.rb +83 -6
  59. data/lib/gooddata/models/segment.rb +2 -1
  60. data/lib/gooddata/models/user_filters/user_filter_builder.rb +104 -15
  61. data/lib/gooddata/rest/connection.rb +5 -3
  62. data/lib/gooddata/rest/phmap.rb +1 -0
  63. data/lib/gooddata.rb +1 -0
  64. data/lib/gooddata_brick_base.rb +35 -0
  65. data/sonar-project.properties +6 -0
  66. metadata +60 -55
  67. data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +0 -15
@@ -39,6 +39,9 @@ module GoodData
39
39
  opts = { client: GoodData.connection }.merge(opts)
40
40
  dry_run = opts[:dry_run]
41
41
  replacements = opts['maql_replacements'] || opts[:maql_replacements] || {}
42
+ update_preference = opts[:update_preference]
43
+ exist_fallback_to_hard_sync_config = !update_preference.nil? && !update_preference[:fallback_to_hard_sync].nil?
44
+ include_maql_fallback_hard_sync = exist_fallback_to_hard_sync_config && GoodData::Helpers.to_boolean(update_preference[:fallback_to_hard_sync])
42
45
 
43
46
  _, project = GoodData.get_client_and_project(opts)
44
47
 
@@ -48,6 +51,7 @@ module GoodData
48
51
  maql_diff_params = [:includeGrain]
49
52
  maql_diff_params << :excludeFactRule if opts[:exclude_fact_rule]
50
53
  maql_diff_params << :includeDeprecated if opts[:include_deprecated]
54
+ maql_diff_params << :includeMaqlFallbackHardSync if include_maql_fallback_hard_sync
51
55
 
52
56
  maql_diff_time = Benchmark.realtime do
53
57
  response = project.maql_diff(blueprint: bp, params: maql_diff_params)
@@ -62,7 +66,7 @@ module GoodData
62
66
  ca_maql = response['projectModelDiff']['computedAttributesScript'] if response['projectModelDiff']['computedAttributesScript']
63
67
  ca_chunks = ca_maql && ca_maql['maqlDdlChunks']
64
68
 
65
- maqls = pick_correct_chunks(chunks, opts)
69
+ maqls = include_maql_fallback_hard_sync ? pick_correct_chunks_hard_sync(chunks, opts) : pick_correct_chunks(chunks, opts)
66
70
  replaced_maqls = apply_replacements_on_maql(maqls, replacements)
67
71
  apply_maqls(ca_chunks, project, replaced_maqls, opts) unless dry_run
68
72
  [replaced_maqls, ca_maql]
@@ -72,9 +76,11 @@ module GoodData
72
76
  errors = []
73
77
  replaced_maqls.each do |replaced_maql_chunks|
74
78
  begin
79
+ fallback_hard_sync = replaced_maql_chunks['updateScript']['fallbackHardSync'].nil? ? false : replaced_maql_chunks['updateScript']['fallbackHardSync']
75
80
  replaced_maql_chunks['updateScript']['maqlDdlChunks'].each do |chunk|
76
81
  GoodData.logger.debug(chunk)
77
- project.execute_maql(chunk)
82
+ execute_maql_result = project.execute_maql(chunk)
83
+ process_fallback_hard_sync_result(execute_maql_result, project) if fallback_hard_sync
78
84
  end
79
85
  rescue => e
80
86
  GoodData.logger.error("Error occured when executing MAQL, project: \"#{project.title}\" reason: \"#{e.message}\", chunks: #{replaced_maql_chunks.inspect}")
@@ -140,8 +146,8 @@ module GoodData
140
146
  preference = Hash[preference.map { |k, v| [k, GoodData::Helpers.to_boolean(v)] }]
141
147
 
142
148
  # will use new parameters instead of the old ones
143
- if preference.empty? || [:allow_cascade_drops, :keep_data].any? { |k| preference.key?(k) }
144
- if [:cascade_drops, :preserve_data].any? { |k| preference.key?(k) }
149
+ if preference.empty? || %i[allow_cascade_drops keep_data].any? { |k| preference.key?(k) }
150
+ if %i[cascade_drops preserve_data].any? { |k| preference.key?(k) }
145
151
  fail "Please do not mix old parameters (:cascade_drops, :preserve_data) with the new ones (:allow_cascade_drops, :keep_data)."
146
152
  end
147
153
  preference = { allow_cascade_drops: false, keep_data: true }.merge(preference)
@@ -174,8 +180,8 @@ module GoodData
174
180
  results_from_api = GoodData::Helpers.join(
175
181
  rules,
176
182
  stuff,
177
- [:cascade_drops, :preserve_data],
178
- [:cascade_drops, :preserve_data],
183
+ %i[cascade_drops preserve_data],
184
+ %i[cascade_drops preserve_data],
179
185
  inner: true
180
186
  ).sort_by { |l| l[:priority] } || []
181
187
 
@@ -204,6 +210,53 @@ module GoodData
204
210
  end
205
211
  end
206
212
 
213
+ def pick_correct_chunks_hard_sync(chunks, opts = {})
214
+ preference = GoodData::Helpers.symbolize_keys(opts[:update_preference] || {})
215
+ preference = Hash[preference.map { |k, v| [k, GoodData::Helpers.to_boolean(v)] }]
216
+
217
+ # Old configure using cascade_drops and preserve_data parameters. New configure using allow_cascade_drops and
218
+ # keep_data parameters. Need translate from new configure to old configure before processing
219
+ if preference.empty? || %i[allow_cascade_drops keep_data].any? { |k| preference.key?(k) }
220
+ if %i[cascade_drops preserve_data].any? { |k| preference.key?(k) }
221
+ fail "Please do not mix old parameters (:cascade_drops, :preserve_data) with the new ones (:allow_cascade_drops, :keep_data)."
222
+ end
223
+
224
+ # Default allow_cascade_drops=false and keep_data=true
225
+ preference = { allow_cascade_drops: false, keep_data: true }.merge(preference)
226
+
227
+ new_preference = {}
228
+ new_preference[:cascade_drops] = preference[:allow_cascade_drops]
229
+ new_preference[:preserve_data] = preference[:keep_data]
230
+ preference = new_preference
231
+ end
232
+ preference[:fallback_to_hard_sync] = true
233
+
234
+ # Filter chunk with fallbackHardSync = true
235
+ result = chunks.select do |chunk|
236
+ chunk['updateScript']['maqlDdlChunks'] && !chunk['updateScript']['fallbackHardSync'].nil? && chunk['updateScript']['fallbackHardSync']
237
+ end
238
+
239
+ # The API model/diff only returns one result for MAQL fallback hard synchronize
240
+ result = pick_chunks_hard_sync(result[0], preference) if !result.nil? && !result.empty?
241
+
242
+ if result.nil? || result.empty?
243
+ available_chunks = chunks
244
+ .map do |chunk|
245
+ {
246
+ cascade_drops: chunk['updateScript']['cascadeDrops'],
247
+ preserve_data: chunk['updateScript']['preserveData'],
248
+ fallback_hard_sync: chunk['updateScript']['fallbackHardSync'].nil? ? false : chunk['updateScript']['fallbackHardSync']
249
+ }
250
+ end
251
+ .map(&:to_s)
252
+ .join(', ')
253
+
254
+ fail "Synchronize LDM cannot proceed. Adjust your update_preferences and try again. Available chunks with preference: #{available_chunks}"
255
+ end
256
+
257
+ result
258
+ end
259
+
207
260
  private
208
261
 
209
262
  def apply_replacements_on_maql(maqls, replacements = {})
@@ -215,6 +268,30 @@ module GoodData
215
268
  end
216
269
  end
217
270
  end
271
+
272
+ # Fallback hard synchronize although execute result success but some cases there are errors during executing.
273
+ # In this cases, then export the errors to execution log as warning
274
+ def process_fallback_hard_sync_result(result, project)
275
+ messages = result['wTaskStatus']['messages']
276
+ if !messages.nil? && messages.size.positive?
277
+ warning_message = GoodData::Helpers.interpolate_error_messages(messages)
278
+ log_message = "Project #{project.pid} failed to preserve data, truncated data of some datasets. MAQL diff execution messages: \"#{warning_message}\""
279
+ GoodData.logger.warn(log_message)
280
+ end
281
+ end
282
+
283
+ # In case fallback hard synchronize, then the API model/diff only returns one result with preserve_data is always false and
284
+ # cascade_drops is true or false. So pick chunk for fallback hard synchronize, we will ignore the preserve_data parameter
285
+ # and only check the cascade_drops parameter in preference.
286
+ def pick_chunks_hard_sync(chunk, preference)
287
+ # Make sure default values for cascade_drops
288
+ working_preference = { cascade_drops: false }.merge(preference)
289
+ if working_preference[:cascade_drops] || chunk['updateScript']['cascadeDrops'] == working_preference[:cascade_drops]
290
+ [chunk]
291
+ else
292
+ []
293
+ end
294
+ end
218
295
  end
219
296
  end
220
297
  end
@@ -257,7 +257,8 @@ module GoodData
257
257
  res = client.poll_on_code(res['asyncTask']['links']['poll'])
258
258
  failed_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult failed count), 0)
259
259
  created_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult created count), 0)
260
- return Enumerator.new([]) if (failed_count + created_count).zero?
260
+ return [].to_enum if (failed_count + created_count).zero?
261
+
261
262
  Enumerator.new do |y|
262
263
  uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult links details))
263
264
  loop do
@@ -19,6 +19,9 @@ using NilExtensions
19
19
 
20
20
  module GoodData
21
21
  module UserFilterBuilder
22
+ @all_domain_users = {}
23
+ @mutex = Mutex.new
24
+
22
25
  # Main Entry function. Gets values and processes them to get filters
23
26
  # that are suitable for other function to process.
24
27
  # Values can be read from file or provided inline as an array.
@@ -48,11 +51,26 @@ module GoodData
48
51
  end
49
52
 
50
53
  def self.read_file(file, options = {})
51
- memo = {}
52
- params = row_based?(options) ? { headers: false } : { headers: true }
54
+ memo = Hash[]
55
+ if row_based?(options)
56
+ read_data_without_header(file, memo, options)
57
+ else
58
+ read_data_with_header(file, memo, options)
59
+ end
60
+ memo
61
+ end
53
62
 
54
- CSV.foreach(file, params.merge(return_headers: false)) do |e|
55
- key, data = process_line(e, options)
63
+ def self.read_data_without_header(file, memo, options)
64
+ CSV.foreach(file, headers: false, return_headers: false) do |row|
65
+ key, data = process_line(row, options)
66
+ memo[key] = [] unless memo.key?(key)
67
+ memo[key].concat(data)
68
+ end
69
+ end
70
+
71
+ def self.read_data_with_header(file, memo, options)
72
+ CSV.foreach(file, headers: true, return_headers: false) do |row|
73
+ key, data = process_line(row, options)
56
74
  memo[key] = [] unless memo.key?(key)
57
75
  memo[key].concat(data)
58
76
  end
@@ -210,13 +228,23 @@ module GoodData
210
228
  # Takes the filter definition looks up any necessary values and provides API executable MAQL
211
229
  # @param labels_cache e.g. { 'label_uri': label_object }
212
230
  # @param lookups_cache e.g. { 'label_uri': { "jirka@gooddata.com": 'value_uri' }}
213
- def self.create_expression(filter, labels_cache, lookups_cache, attr_cache, options = {})
231
+ # rubocop:disable Metrics/ParameterLists
232
+ def self.create_expression(filter, labels_cache, lookups_cache, attr_cache, options = {}, login)
214
233
  values = filter[:values]
215
234
  # Do not create MUF for label when all its values is NULL (https://jira.intgdc.com/browse/TMA-1361)
216
235
  non_null_values = values.select { |value| !value.nil? && value.downcase != 'null' }
217
236
  return ['TRUE', []] if non_null_values.empty?
218
237
 
219
238
  label = labels_cache[filter[:label]]
239
+ if label.nil?
240
+ err_message = "Unable to apply filter values: #{values} since the project: #{options[:project].pid} doesn't have label: #{filter[:label]} for login: #{login}"
241
+ if options[:ignore_missing_values]
242
+ GoodData.logger.warn(err_message)
243
+ return ['TRUE', []]
244
+ else
245
+ fail err_message
246
+ end
247
+ end
220
248
  errors = []
221
249
 
222
250
  element_uris_by_values = Hash[values.map do |v|
@@ -262,6 +290,7 @@ module GoodData
262
290
  end
263
291
  [expression, errors]
264
292
  end
293
+ # rubocop:enable Metrics/ParameterLists
265
294
 
266
295
  # Encapuslates the creation of filter
267
296
  def self.create_user_filter(expression, related)
@@ -273,6 +302,66 @@ module GoodData
273
302
  }
274
303
  end
275
304
 
305
+ def self.create_user_profile_mapping(filters, project_users, options = {})
306
+ domain = options[:domain]
307
+ found_list = {}
308
+ missing_list = []
309
+
310
+ # Get the list of user login from filters
311
+ login_list = filters.flat_map do |filter|
312
+ filter[:login]
313
+ end
314
+
315
+ # Then find user login in the users_brick_input
316
+ users_brick_input = options[:users_brick_input]
317
+ if users_brick_input&.any?
318
+ users_brick_input.map do |user|
319
+ login_list << user.with_indifferent_access['login']
320
+ end
321
+ end
322
+
323
+ login_list.uniq.flat_map do |login|
324
+ user = project_users.find { |u| u.login == login }
325
+ if user
326
+ found_list[login] = user.profile_url
327
+ else
328
+ missing_list << login
329
+ end
330
+ end
331
+ # rubocop:disable Metrics/BlockNesting
332
+ unless missing_list.empty? || domain.nil?
333
+ if missing_list.size < 100
334
+ missing_list.each do |login|
335
+ user = domain.find_user_by_login(login)
336
+ found_list[login] = user.links['self'] if user
337
+ end
338
+ else
339
+ if @all_domain_users[domain.name].nil?
340
+ @mutex.lock
341
+ if @all_domain_users[domain.name].nil?
342
+ domain_users = domain.users
343
+ @all_domain_users[domain.name] = domain_users
344
+ GoodData.logger.info("action=lcm_get_domain_users domain=#{domain.name} number_users=#{domain_users.size} number_missing_users=#{missing_list.size} use_cache=false")
345
+ else
346
+ domain_users = @all_domain_users[domain.name]
347
+ GoodData.logger.info("action=lcm_get_domain_users domain=##{domain.name} number_users=#{domain_users.size} number_missing_users=#{missing_list.size} use_cache=true")
348
+ end
349
+ @mutex.unlock
350
+ else
351
+ domain_users = @all_domain_users[domain.name]
352
+ GoodData.logger.info("action=lcm_get_domain_users domain=##{domain.name} number_users=#{domain_users.size} number_missing_users=#{missing_list.size} use_cache=true")
353
+ end
354
+
355
+ missing_list.each do |login|
356
+ user = domain_users.find { |u| u.login == login }
357
+ found_list[login] = user.links['self'] if user
358
+ end
359
+ end
360
+ end
361
+ # rubocop:enable Metrics/BlockNesting
362
+ found_list
363
+ end
364
+
276
365
  # Resolves and creates maql statements from filter definitions.
277
366
  # This method does not perform any modifications on API but
278
367
  # collects all the information that is needed to do so.
@@ -283,7 +372,7 @@ module GoodData
283
372
  #
284
373
  # @param filters [Array<Hash>] Filters definition
285
374
  # @return [Array] first is list of MAQL statements
286
- def self.maqlify_filters(filters, project_users, options = {})
375
+ def self.maqlify_filters(filters, user_profile_mapping, options = {})
287
376
  fail_early = options[:fail_early] == false ? false : true
288
377
  users_cache = options[:users_cache]
289
378
  labels_cache = create_label_cache(filters, options)
@@ -291,11 +380,10 @@ module GoodData
291
380
  lookups_cache = create_lookups_cache(small_labels)
292
381
  attrs_cache = create_attrs_cache(filters, options)
293
382
  create_filter_proc = proc do |login, f|
294
- expression, errors = create_expression(f, labels_cache, lookups_cache, attrs_cache, options)
383
+ expression, errors = create_expression(f, labels_cache, lookups_cache, attrs_cache, options, login)
295
384
  safe_login = login.downcase
296
385
  profiles_uri = if options[:type] == :muf
297
- project_user = project_users.find { |u| u.login == safe_login }
298
- project_user.nil? ? ('/gdc/account/profile/' + safe_login) : project_user.profile_url
386
+ user_profile_mapping[safe_login].nil? ? ('/gdc/account/profile/' + safe_login) : user_profile_mapping[safe_login]
299
387
  elsif options[:type] == :variable
300
388
  (users_cache[login] && users_cache[login].uri)
301
389
  else
@@ -393,7 +481,8 @@ module GoodData
393
481
 
394
482
  project_users = project.users
395
483
  filters = normalize_filters(user_filters)
396
- user_filters, errors = maqlify_filters(filters, project_users, options.merge(users_must_exist: users_must_exist, type: :muf))
484
+ user_profile_mapping = create_user_profile_mapping(filters, project_users, options)
485
+ user_filters, errors = maqlify_filters(filters, user_profile_mapping, options.merge(users_must_exist: users_must_exist, type: :muf))
397
486
  if !ignore_missing_values && !errors.empty?
398
487
  errors = errors.map do |e|
399
488
  e.merge(pid: project.pid)
@@ -404,7 +493,7 @@ module GoodData
404
493
  filters = user_filters.map { |data| client.create(MandatoryUserFilter, data, project: project) }
405
494
  to_create, to_delete = resolve_user_filters(filters, project.data_permissions)
406
495
 
407
- to_delete = sanitize_filters_to_delete(to_delete, options[:users_brick_input], project_users) unless options[:no_sanitize]
496
+ to_delete = sanitize_filters_to_delete(to_delete, options[:users_brick_input], user_profile_mapping) unless options[:no_sanitize]
408
497
 
409
498
  if options[:do_not_touch_filters_that_are_not_mentioned]
410
499
  GoodData.logger.warn("Data permissions computed: #{to_create.count} to create")
@@ -499,7 +588,7 @@ module GoodData
499
588
  # @param file [String | Array] File or array of values to be parsed for filters
500
589
  # @param options [Hash] Filter definitions
501
590
  # @return [Array<Hash>]
502
- def self.get_values(file, options)
591
+ def self.get_values(file, options = {})
503
592
  file.is_a?(Array) ? read_array(file, options) : read_file(file, options)
504
593
  end
505
594
 
@@ -584,12 +673,12 @@ module GoodData
584
673
  # Removes MUFs from to_delete unless in user is in users_brick_input
585
674
  # if this does not happen, users that are about to be deleted by users_brick
586
675
  # would have all their filters removed now, which is not desirable
587
- def self.sanitize_filters_to_delete(to_delete, users_brick_input, project_users)
676
+ def self.sanitize_filters_to_delete(to_delete, users_brick_input, user_profile_mapping)
588
677
  return [] unless users_brick_input && users_brick_input.any?
589
678
  user_profiles = users_brick_input.map do |user|
590
- result = project_users.find { |u| u.login == user.with_indifferent_access['login'] }
679
+ result = user_profile_mapping[user.with_indifferent_access['login']]
591
680
  next unless result
592
- result.profile_url
681
+ result
593
682
  end.compact
594
683
  return [] unless user_profiles.any?
595
684
  to_delete.reject do |_, value|
@@ -68,6 +68,8 @@ module GoodData
68
68
  RETRY_TIME_COEFFICIENT = 1.5
69
69
  RETRYABLE_ERRORS << Net::ReadTimeout if Net.const_defined?(:ReadTimeout)
70
70
 
71
+ RETRYABLE_ERRORS << OpenSSL::SSL::SSLErrorWaitReadable if OpenSSL::SSL.const_defined?(:SSLErrorWaitReadable)
72
+
71
73
  class << self
72
74
  def construct_login_payload(username, password)
73
75
  res = {
@@ -304,12 +306,12 @@ module GoodData
304
306
  end
305
307
 
306
308
  def refresh_token(_options = {})
307
- begin # rubocop:disable RedundantBegin
309
+ begin # rubocop:disable Style/RedundantBegin
308
310
  # avoid infinite loop GET fails with 401
309
311
  response = get(TOKEN_PATH, :x_gdc_authsst => sst_token, :dont_reauth => true)
310
312
  # Remove when TT sent in headers. Currently we need to parse from body
311
313
  merge_headers!(:x_gdc_authtt => GoodData::Helpers.get_path(response, %w(userToken token)))
312
- rescue Exception => e # rubocop:disable RescueException
314
+ rescue Exception => e # rubocop:disable Style/RescueException
313
315
  raise e
314
316
  end
315
317
  end
@@ -688,7 +690,7 @@ ERR
688
690
  execution_id = request_id
689
691
 
690
692
  GoodData.gd_logger.update_store(domain, method, duration, endpoint)
691
- GoodData.gd_logger.add Logger::INFO, { endpoint: endpoint, duration: duration, domain: domain,
693
+ GoodData.gd_logger.add Logger::DEBUG, { endpoint: endpoint, duration: duration, domain: domain,
692
694
  execution_id: execution_id, time_stamp: time_stamp }, "rest_call"
693
695
  end
694
696
  end
@@ -83,6 +83,7 @@ module GoodData
83
83
  ['/gdc/internal/projects/{id}/objects/setPermissions', %r{/gdc/internal/projects/[^\/]+/objects/setPermissions}],
84
84
  ['/gdc/internal/projects/{id}/roles', %r{/gdc/internal/projects/[^\/]+/roles}],
85
85
  ['/gdc/dataload/projects/{id}/modelMapping/datasets/bulk/upsert', %r{/gdc/dataload/projects/[^\/]+/modelMapping/datasets/bulk/upsert}],
86
+ ['/gdc/dataload/internal/projects/{id}/ldmLayout', %r{/gdc/dataload/internal/projects/[^\/]+/ldmLayout}],
86
87
  ['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[^\/]+/variables/item/[\d]+}],
87
88
  ['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[^\/]+/validate/task/[^\/]+}],
88
89
  ['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+/[\d]+}],
data/lib/gooddata.rb CHANGED
@@ -37,5 +37,6 @@ require 'backports/2.1.0/array/to_h'
37
37
 
38
38
  # Helpers
39
39
  require 'gooddata/helpers/global_helpers'
40
+ require 'gooddata/lcm/helpers/check_helper'
40
41
 
41
42
  require 'active_support/core_ext/hash/compact' unless RUBY_VERSION >= '2.5'
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Copyright (c) 2010-2022 GoodData Corporation. All rights reserved.
5
+ # This source code is licensed under the BSD-style license found in the
6
+ # LICENSE file in the root directory of this source tree.
7
+
8
+ require 'pmap'
9
+ $pmap_default_thread_count = 20 # rubocop:disable GlobalVars
10
+
11
+ # GoodData Module
12
+ module GoodData
13
+ end
14
+
15
+ # Modules
16
+ require_relative 'gooddata/core/core'
17
+ require_relative 'gooddata/models/models'
18
+ require_relative 'gooddata/exceptions/exceptions'
19
+ require_relative 'gooddata/helpers/helpers'
20
+
21
+ # Files
22
+ require_relative 'gooddata/bricks/utils'
23
+ require_relative 'gooddata/bricks/brick'
24
+ require_relative 'gooddata/bricks/base_pipeline'
25
+ require_relative 'gooddata/bricks/middleware/base_middleware'
26
+ require_relative 'gooddata/bricks/middleware/bench_middleware'
27
+ require_relative 'gooddata/bricks/middleware/logger_middleware'
28
+ require_relative 'gooddata/bricks/middleware/decode_params_middleware'
29
+ require_relative 'gooddata/bricks/middleware/aws_middleware'
30
+ require_relative 'gooddata/bricks/middleware/dwh_middleware'
31
+ require_relative 'gooddata/bricks/middleware/bench_middleware'
32
+
33
+ # CSV Downloader
34
+ require_relative 'gooddata/core/logging'
35
+ require_relative 'gooddata/connection'
@@ -0,0 +1,6 @@
1
+ sonar.projectKey=gooddata-ruby
2
+ sonar.organization=gooddata-github
3
+ # Config scan necessary files/folder only
4
+ sonar.sources=bin,lib
5
+ sonar.tests=spec
6
+ sonar.exclusions=**/lib/templates/project/*.erb