gooddata 2.1.19-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.
- checksums.yaml +4 -4
- data/.gdc-ii-config.yaml +42 -1
- data/.github/workflows/build.yml +67 -0
- data/.github/workflows/pre-merge.yml +72 -0
- data/.pronto.yml +1 -0
- data/.rubocop.yml +2 -14
- data/CHANGELOG.md +47 -0
- data/Dockerfile +27 -14
- data/Dockerfile.jruby +5 -15
- data/Dockerfile.ruby +5 -7
- data/Gemfile +4 -2
- data/README.md +6 -6
- data/Rakefile +1 -1
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/run_brick.rb +7 -0
- data/ci/mssql/pom.xml +62 -0
- data/ci/mysql/pom.xml +62 -0
- data/ci/redshift/pom.xml +4 -5
- data/docker-compose.lcm.yml +42 -4
- data/docker-compose.yml +42 -0
- data/gooddata.gemspec +21 -21
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/lcm.rake +11 -8
- data/lib/gooddata/bricks/base_pipeline.rb +26 -0
- data/lib/gooddata/bricks/brick.rb +0 -1
- data/lib/gooddata/bricks/middleware/aws_middleware.rb +35 -9
- data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +3 -3
- data/lib/gooddata/bricks/pipeline.rb +2 -14
- data/lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb +98 -0
- data/lib/gooddata/cloud_resources/mssql/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/mssql/mssql_client.rb +122 -0
- data/lib/gooddata/cloud_resources/mysql/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/mysql/mysql_client.rb +121 -0
- data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +0 -1
- data/lib/gooddata/cloud_resources/redshift/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +0 -2
- data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +18 -1
- data/lib/gooddata/helpers/data_helper.rb +9 -4
- data/lib/gooddata/lcm/actions/base_action.rb +157 -0
- data/lib/gooddata/lcm/actions/collect_data_product.rb +2 -1
- data/lib/gooddata/lcm/actions/collect_meta.rb +3 -1
- data/lib/gooddata/lcm/actions/collect_projects_warning_status.rb +53 -0
- data/lib/gooddata/lcm/actions/collect_segment_clients.rb +14 -0
- data/lib/gooddata/lcm/actions/initialize_continue_on_error_option.rb +87 -0
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +31 -4
- data/lib/gooddata/lcm/actions/provision_clients.rb +34 -5
- data/lib/gooddata/lcm/actions/synchronize_cas.rb +24 -4
- data/lib/gooddata/lcm/actions/synchronize_clients.rb +112 -11
- data/lib/gooddata/lcm/actions/synchronize_dataset_mappings.rb +89 -0
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +48 -11
- data/lib/gooddata/lcm/actions/synchronize_kd_dashboard_permission.rb +103 -0
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +79 -23
- data/lib/gooddata/lcm/actions/synchronize_ldm_layout.rb +98 -0
- data/lib/gooddata/lcm/actions/synchronize_pp_dashboard_permission.rb +108 -0
- data/lib/gooddata/lcm/actions/synchronize_schedules.rb +31 -1
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +26 -18
- data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +30 -4
- data/lib/gooddata/lcm/actions/synchronize_users.rb +11 -10
- data/lib/gooddata/lcm/actions/update_metric_formats.rb +202 -0
- data/lib/gooddata/lcm/data/delete_from_lcm_release.sql.erb +5 -0
- data/lib/gooddata/lcm/exceptions/lcm_execution_warning.rb +15 -0
- data/lib/gooddata/lcm/helpers/check_helper.rb +19 -0
- data/lib/gooddata/lcm/helpers/release_table_helper.rb +42 -8
- data/lib/gooddata/lcm/lcm2.rb +50 -4
- data/lib/gooddata/lcm/user_bricks_helper.rb +9 -0
- data/lib/gooddata/mixins/inspector.rb +1 -1
- data/lib/gooddata/mixins/md_object_query.rb +1 -0
- data/lib/gooddata/models/data_source.rb +5 -1
- data/lib/gooddata/models/dataset_mapping.rb +36 -0
- data/lib/gooddata/models/ldm_layout.rb +38 -0
- data/lib/gooddata/models/metadata/label.rb +26 -27
- data/lib/gooddata/models/project.rb +230 -30
- data/lib/gooddata/models/project_creator.rb +83 -6
- data/lib/gooddata/models/schedule.rb +13 -1
- data/lib/gooddata/models/segment.rb +2 -1
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +162 -68
- data/lib/gooddata/rest/connection.rb +5 -3
- data/lib/gooddata/rest/phmap.rb +2 -0
- data/lib/gooddata.rb +1 -0
- data/lib/gooddata_brick_base.rb +35 -0
- data/sonar-project.properties +6 -0
- metadata +96 -65
- data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +0 -37
- data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +0 -15
@@ -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
|
-
|
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
|
-
|
55
|
-
|
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
|
@@ -203,20 +221,30 @@ module GoodData
|
|
203
221
|
# so it precaches the values and still be able to function for larger ones even
|
204
222
|
# though that would mean tons of requests
|
205
223
|
def self.get_small_labels(labels_cache)
|
206
|
-
labels_cache.values.select { |label| label
|
224
|
+
labels_cache.values.select { |label| label &.values_count &. < 100_000 }
|
207
225
|
end
|
208
226
|
|
209
227
|
# Creates a MAQL expression(s) based on the filter defintion.
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
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],
|
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")
|
@@ -421,68 +510,73 @@ module GoodData
|
|
421
510
|
results: create_results + delete_results }
|
422
511
|
end
|
423
512
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
'userFilters'
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
513
|
+
if to_create.empty?
|
514
|
+
create_results = []
|
515
|
+
else
|
516
|
+
create_results = to_create.each_slice(100).flat_map do |batch|
|
517
|
+
batch.pmapcat do |related_uri, group|
|
518
|
+
group.each(&:save)
|
519
|
+
res = client.get("/gdc/md/#{project.pid}/userfilters?users=#{related_uri}")
|
520
|
+
items = res['userFilters']['items'].empty? ? [] : res['userFilters']['items'].first['userFilters']
|
521
|
+
|
522
|
+
payload = {
|
523
|
+
'userFilters' => {
|
524
|
+
'items' => [{
|
525
|
+
'user' => related_uri,
|
526
|
+
'userFilters' => items.concat(group.map(&:uri))
|
527
|
+
}]
|
528
|
+
}
|
436
529
|
}
|
437
|
-
|
438
|
-
res = client.post("/gdc/md/#{project.pid}/userfilters", payload)
|
530
|
+
res = client.post("/gdc/md/#{project.pid}/userfilters", payload)
|
439
531
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
532
|
+
# turn the errors from hashes into array of hashes
|
533
|
+
update_result = res['userFiltersUpdateResult'].flat_map do |k, v|
|
534
|
+
v.map { |r| { status: k.to_sym, user: r, type: :create } }
|
535
|
+
end
|
444
536
|
|
445
|
-
|
446
|
-
|
537
|
+
update_result.map do |result|
|
538
|
+
result[:status] == :failed ? result.merge(GoodData::Helpers.symbolize_keys(result[:user])) : result
|
539
|
+
end
|
447
540
|
end
|
448
541
|
end
|
542
|
+
project_log_formatter.log_user_filter_results(create_results, to_create)
|
543
|
+
create_errors = create_results.select { |r| r[:status] == :failed }
|
544
|
+
fail "Creating MUFs resulted in errors: #{create_errors}" if create_errors.any?
|
449
545
|
end
|
450
546
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
res = client.post("/gdc/md/#{project.pid}/userfilters", payload)
|
473
|
-
results.concat(res['userFiltersUpdateResult']
|
547
|
+
if to_delete.empty?
|
548
|
+
delete_results = []
|
549
|
+
elsif !options[:do_not_touch_filters_that_are_not_mentioned]
|
550
|
+
delete_results = to_delete.each_slice(100).flat_map do |batch|
|
551
|
+
batch.flat_map do |related_uri, group|
|
552
|
+
results = []
|
553
|
+
if related_uri
|
554
|
+
res = client.get("/gdc/md/#{project.pid}/userfilters?users=#{related_uri}")
|
555
|
+
items = res['userFilters']['items'].empty? ? [] : res['userFilters']['items'].first['userFilters']
|
556
|
+
payload = {
|
557
|
+
'userFilters' => {
|
558
|
+
'items' => [
|
559
|
+
{
|
560
|
+
'user' => related_uri,
|
561
|
+
'userFilters' => items - group.map(&:uri)
|
562
|
+
}
|
563
|
+
]
|
564
|
+
}
|
565
|
+
}
|
566
|
+
res = client.post("/gdc/md/#{project.pid}/userfilters", payload)
|
567
|
+
results.concat(res['userFiltersUpdateResult']
|
474
568
|
.flat_map { |k, v| v.map { |r| { status: k.to_sym, user: r, type: :delete } } }
|
475
569
|
.map { |result| result[:status] == :failed ? result.merge(GoodData::Helpers.symbolize_keys(result[:user])) : result })
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
end
|
481
|
-
end
|
570
|
+
end
|
571
|
+
group.peach(&:delete)
|
572
|
+
results
|
573
|
+
end
|
482
574
|
|
483
|
-
|
484
|
-
|
485
|
-
|
575
|
+
project_log_formatter.log_user_filter_results(delete_results, to_delete)
|
576
|
+
delete_errors = delete_results.select { |r| r[:status] == :failed } if delete_results
|
577
|
+
fail "Deleting MUFs resulted in errors: #{delete_errors}" if delete_errors&.any?
|
578
|
+
end
|
579
|
+
end
|
486
580
|
|
487
581
|
{ created: to_create, deleted: to_delete, results: create_results + (delete_results || []) }
|
488
582
|
end
|
@@ -494,7 +588,7 @@ module GoodData
|
|
494
588
|
# @param file [String | Array] File or array of values to be parsed for filters
|
495
589
|
# @param options [Hash] Filter definitions
|
496
590
|
# @return [Array<Hash>]
|
497
|
-
def self.get_values(file, options)
|
591
|
+
def self.get_values(file, options = {})
|
498
592
|
file.is_a?(Array) ? read_array(file, options) : read_file(file, options)
|
499
593
|
end
|
500
594
|
|
@@ -579,12 +673,12 @@ module GoodData
|
|
579
673
|
# Removes MUFs from to_delete unless in user is in users_brick_input
|
580
674
|
# if this does not happen, users that are about to be deleted by users_brick
|
581
675
|
# would have all their filters removed now, which is not desirable
|
582
|
-
def self.sanitize_filters_to_delete(to_delete, users_brick_input,
|
676
|
+
def self.sanitize_filters_to_delete(to_delete, users_brick_input, user_profile_mapping)
|
583
677
|
return [] unless users_brick_input && users_brick_input.any?
|
584
678
|
user_profiles = users_brick_input.map do |user|
|
585
|
-
result =
|
679
|
+
result = user_profile_mapping[user.with_indifferent_access['login']]
|
586
680
|
next unless result
|
587
|
-
result
|
681
|
+
result
|
588
682
|
end.compact
|
589
683
|
return [] unless user_profiles.any?
|
590
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::
|
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
|
data/lib/gooddata/rest/phmap.rb
CHANGED
@@ -82,6 +82,8 @@ module GoodData
|
|
82
82
|
|
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
|
+
['/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}],
|
85
87
|
['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[^\/]+/variables/item/[\d]+}],
|
86
88
|
['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[^\/]+/validate/task/[^\/]+}],
|
87
89
|
['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+/[\d]+}],
|
data/lib/gooddata.rb
CHANGED
@@ -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'
|