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
data/lib/gooddata/lcm/lcm2.rb
CHANGED
@@ -17,6 +17,7 @@ require_relative 'actions/actions'
|
|
17
17
|
require_relative 'dsl/dsl'
|
18
18
|
require_relative 'helpers/helpers'
|
19
19
|
require_relative 'exceptions/lcm_execution_error'
|
20
|
+
require_relative 'exceptions/lcm_execution_warning'
|
20
21
|
|
21
22
|
using TrueExtensions
|
22
23
|
using FalseExtensions
|
@@ -96,10 +97,14 @@ module GoodData
|
|
96
97
|
CollectComputedAttributeMetrics,
|
97
98
|
ImportObjectCollections,
|
98
99
|
SynchronizeComputedAttributes,
|
100
|
+
SynchronizeDataSetMapping,
|
101
|
+
SynchronizeLdmLayout,
|
99
102
|
SynchronizeProcesses,
|
100
103
|
SynchronizeSchedules,
|
101
104
|
SynchronizeColorPalette,
|
102
105
|
SynchronizeUserGroups,
|
106
|
+
SynchronizePPDashboardPermissions,
|
107
|
+
SynchronizeKDDashboardPermissions,
|
103
108
|
SynchronizeNewSegments,
|
104
109
|
UpdateReleaseTable
|
105
110
|
],
|
@@ -121,11 +126,19 @@ module GoodData
|
|
121
126
|
CollectClients,
|
122
127
|
AssociateClients,
|
123
128
|
RenameExistingClientProjects,
|
129
|
+
InitializeContinueOnErrorOption,
|
124
130
|
ProvisionClients,
|
131
|
+
UpdateMetricFormats,
|
125
132
|
EnsureTechnicalUsersDomain,
|
126
133
|
EnsureTechnicalUsersProject,
|
127
134
|
CollectDymanicScheduleParams,
|
128
|
-
|
135
|
+
SynchronizeDataSetMapping,
|
136
|
+
SynchronizeLdmLayout,
|
137
|
+
SynchronizeUserGroups,
|
138
|
+
SynchronizePPDashboardPermissions,
|
139
|
+
SynchronizeKDDashboardPermissions,
|
140
|
+
SynchronizeETLsInSegment,
|
141
|
+
CollectProjectsWarningStatus
|
129
142
|
],
|
130
143
|
|
131
144
|
rollout: [
|
@@ -135,12 +148,20 @@ module GoodData
|
|
135
148
|
CollectSegmentClients,
|
136
149
|
EnsureTechnicalUsersDomain,
|
137
150
|
EnsureTechnicalUsersProject,
|
151
|
+
InitializeContinueOnErrorOption,
|
138
152
|
SynchronizeLdm,
|
153
|
+
SynchronizeDataSetMapping,
|
154
|
+
SynchronizeLdmLayout,
|
139
155
|
MigrateGdcDateDimension,
|
140
156
|
SynchronizeClients,
|
157
|
+
SynchronizeUserGroups,
|
158
|
+
SynchronizePPDashboardPermissions,
|
159
|
+
SynchronizeKDDashboardPermissions,
|
160
|
+
UpdateMetricFormats,
|
141
161
|
SynchronizeComputedAttributes,
|
142
162
|
CollectDymanicScheduleParams,
|
143
|
-
SynchronizeETLsInSegment
|
163
|
+
SynchronizeETLsInSegment,
|
164
|
+
CollectProjectsWarningStatus
|
144
165
|
],
|
145
166
|
|
146
167
|
users: [
|
@@ -335,7 +356,7 @@ module GoodData
|
|
335
356
|
# Invoke action
|
336
357
|
begin
|
337
358
|
out = run_action action, params
|
338
|
-
rescue Exception => e # rubocop:disable RescueException
|
359
|
+
rescue Exception => e # rubocop:disable Style/RescueException
|
339
360
|
errors << {
|
340
361
|
action: action,
|
341
362
|
err: e,
|
@@ -357,7 +378,7 @@ module GoodData
|
|
357
378
|
params.merge!(new_params)
|
358
379
|
|
359
380
|
# Print action result
|
360
|
-
print_action_result(action, res)
|
381
|
+
print_action_result(action, res) if action.send(:print_result, params)
|
361
382
|
|
362
383
|
# Store result for final summary
|
363
384
|
results << res
|
@@ -384,9 +405,28 @@ module GoodData
|
|
384
405
|
end
|
385
406
|
end
|
386
407
|
|
408
|
+
process_sync_failed_projects(params) if GoodData::LCM2::Helpers.collect_synced_status(params) && strict_mode
|
409
|
+
|
387
410
|
result
|
388
411
|
end
|
389
412
|
|
413
|
+
def process_sync_failed_projects(params)
|
414
|
+
sync_failed_list = params[:sync_failed_list]
|
415
|
+
sync_project_list = sync_failed_list[:project_client_mappings]
|
416
|
+
sync_failed_project_list = sync_failed_list[:failed_detailed_projects]
|
417
|
+
|
418
|
+
if sync_project_list && sync_failed_project_list && sync_project_list.size.positive? && sync_failed_project_list.size.positive?
|
419
|
+
failed_project = sync_failed_project_list[0]
|
420
|
+
summary_message = "Existing errors during execution. See log for details"
|
421
|
+
error_message = failed_project[:message]
|
422
|
+
if sync_project_list.size == sync_failed_project_list.size
|
423
|
+
raise GoodData::LcmExecutionError.new(summary_message, error_message)
|
424
|
+
else
|
425
|
+
raise GoodData::LcmExecutionWarning.new(summary_message, error_message)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
390
430
|
def run_action(action, params)
|
391
431
|
begin
|
392
432
|
GoodData.gd_logger.start_action action, GoodData.gd_logger
|
@@ -396,6 +436,12 @@ module GoodData
|
|
396
436
|
BaseAction.check_params(action.const_get('PARAMS'), params)
|
397
437
|
params.setup_filters(action.const_get('PARAMS'))
|
398
438
|
out = action.send(:call, params)
|
439
|
+
rescue Exception => e # rubocop:disable Style/RescueException
|
440
|
+
# Log to splunk
|
441
|
+
GoodData.gd_logger.error("action=#{action} status=failed message=#{e} exception=#{e.backtrace}")
|
442
|
+
# Log to execution log
|
443
|
+
GoodData.logger.error("Execution #{action} failed. Error: #{e}. Detail:#{e.backtrace}")
|
444
|
+
raise e
|
399
445
|
ensure
|
400
446
|
params.clear_filters
|
401
447
|
GoodData.gd_logger.end_action GoodData.gd_logger
|
@@ -26,6 +26,15 @@ module GoodData
|
|
26
26
|
|
27
27
|
goodot_id.empty? ? client.id : goodot_id
|
28
28
|
end
|
29
|
+
|
30
|
+
def non_working_clients(domain_clients, working_client_ids)
|
31
|
+
non_working_clients = []
|
32
|
+
domain_clients.each do |c|
|
33
|
+
non_working_clients << c unless working_client_ids.include?(c.client_id.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
non_working_clients
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
end
|
@@ -10,7 +10,7 @@ module GoodData
|
|
10
10
|
module Mixin
|
11
11
|
# When an RSpec test like this fails,
|
12
12
|
#
|
13
|
-
# @my_array.
|
13
|
+
# expect(@my_array).to == [@some_model, @some_model2]
|
14
14
|
#
|
15
15
|
# RSpec will call inspect on each of the objects to "help" you figure out
|
16
16
|
# what went wrong. Well, inspect will usually dump a TON OF SHIT and make trying
|
@@ -34,7 +34,7 @@ module GoodData
|
|
34
34
|
c.create(DataSource, ds_data)
|
35
35
|
end
|
36
36
|
else
|
37
|
-
c.create(DataSource, c.get(
|
37
|
+
c.create(DataSource, c.get(DATA_SOURCES_URL + '/' + id))
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -177,6 +177,10 @@ module GoodData
|
|
177
177
|
@json['dataSource']['connectionInfo'][type]
|
178
178
|
end
|
179
179
|
|
180
|
+
def type
|
181
|
+
@json['dataSource']['connectionInfo'].first[0].upcase
|
182
|
+
end
|
183
|
+
|
180
184
|
private
|
181
185
|
|
182
186
|
def build_connection_info
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010-2021 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
|
+
module GoodData
|
9
|
+
class DatasetMapping
|
10
|
+
DATASET_MAPPING_GET_URI = '/gdc/dataload/projects/%<project_id>s/modelMapping/datasets'
|
11
|
+
DATASET_MAPPING_UPDATE_URI = '/gdc/dataload/projects/%<project_id>s/modelMapping/datasets/bulk/upsert'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def [](opts = { :client => GoodData.connection, :project => GoodData.project })
|
15
|
+
client, project = GoodData.get_client_and_project(opts)
|
16
|
+
get_uri = DATASET_MAPPING_GET_URI % { project_id: project.pid }
|
17
|
+
res = client.get(get_uri)
|
18
|
+
res
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :get, :[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(data)
|
25
|
+
@data = data
|
26
|
+
end
|
27
|
+
|
28
|
+
def save(opts)
|
29
|
+
client, project = GoodData.get_client_and_project(opts)
|
30
|
+
|
31
|
+
post_uri = DATASET_MAPPING_UPDATE_URI % { project_id: project.pid }
|
32
|
+
res = client.post(post_uri, @data, opts)
|
33
|
+
res
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# Copyright (c) 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
|
+
module GoodData
|
9
|
+
class LdmLayout
|
10
|
+
DEFAULT_EMPTY_LDM_LAYOUT = {
|
11
|
+
"ldmLayout" => {
|
12
|
+
"layout" => []
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
LDM_LAYOUT_URI = '/gdc/dataload/internal/projects/%<project_id>s/ldmLayout'
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def get(opts = { :client => GoodData.connection, :project => GoodData.project })
|
20
|
+
client, project = GoodData.get_client_and_project(opts)
|
21
|
+
get_uri = LDM_LAYOUT_URI % { project_id: project.pid }
|
22
|
+
|
23
|
+
client.get(get_uri)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(data)
|
28
|
+
@data = data
|
29
|
+
end
|
30
|
+
|
31
|
+
def save(opts)
|
32
|
+
client, project = GoodData.get_client_and_project(opts)
|
33
|
+
post_uri = LDM_LAYOUT_URI % { project_id: project.pid }
|
34
|
+
|
35
|
+
client.post(post_uri, @data, opts)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -40,22 +40,20 @@ module GoodData
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
# Gets valid elements
|
43
|
+
# Gets valid elements of a label for a specific paging (:offset and :limit) or get validElements of a specific value (:filter).
|
44
|
+
# In the case filter a specific value, because the API /validElements only filter by partial match, we need to filter again at client side for exact match.
|
44
45
|
# @return [Array] Results
|
45
46
|
def get_valid_elements(*args)
|
46
|
-
|
47
|
-
|
48
|
-
# so we do a preliminary first request to check and then increase the limit if needed
|
49
|
-
if results['validElements']['paging']['total'].to_i != params[:limit]
|
47
|
+
if args && !args.empty? && args.first[:filter]
|
48
|
+
params = args.first
|
50
49
|
params[:limit] = 100_000
|
51
50
|
results, = valid_elements params
|
52
|
-
|
53
|
-
|
54
|
-
i['element']['title'] != params[:filter]
|
55
|
-
end
|
51
|
+
results['validElements']['items'] = results['validElements']['items'].select do |i|
|
52
|
+
i['element']['title'] == params[:filter]
|
56
53
|
end
|
54
|
+
else
|
55
|
+
results, = valid_elements(*args)
|
57
56
|
end
|
58
|
-
|
59
57
|
results
|
60
58
|
end
|
61
59
|
|
@@ -74,24 +72,25 @@ module GoodData
|
|
74
72
|
# @option options [Number] :limit limits the number of values to certain number. Default is 100
|
75
73
|
# @return [Array]
|
76
74
|
def values(options = {})
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
91
|
-
break if elements['items'].count < page_limit
|
92
|
-
offset += page_limit
|
75
|
+
all_values = []
|
76
|
+
offset = options[:offset] || 0
|
77
|
+
page_limit = options[:limit] || 100
|
78
|
+
loop do
|
79
|
+
results = get_valid_elements(limit: page_limit, offset: offset)
|
80
|
+
|
81
|
+
elements = results['validElements']
|
82
|
+
elements['items'].map do |el|
|
83
|
+
v = el['element']
|
84
|
+
all_values << {
|
85
|
+
:value => v['title'],
|
86
|
+
:uri => v['uri']
|
87
|
+
}
|
93
88
|
end
|
89
|
+
break if elements['items'].count < page_limit
|
90
|
+
|
91
|
+
offset += page_limit
|
94
92
|
end
|
93
|
+
all_values
|
95
94
|
end
|
96
95
|
|
97
96
|
def values_count
|
@@ -136,7 +135,7 @@ module GoodData
|
|
136
135
|
if status_url
|
137
136
|
results = client.poll_on_response(status_url) do |body|
|
138
137
|
status = body['taskState'] && body['taskState']['status']
|
139
|
-
status == 'RUNNING' || status == 'PREPARED'
|
138
|
+
status == 'RUNNING' || status == 'PREPARED' || body['uri']
|
140
139
|
end
|
141
140
|
end
|
142
141
|
|