gooddata 2.1.12-java → 2.1.19-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gdc-ii-config.yaml +1 -1
- data/.sonar.settings +4 -0
- data/.travis.yml +78 -12
- data/CHANGELOG.md +37 -0
- data/Dockerfile +9 -3
- data/Dockerfile.jruby +11 -1
- data/LICENSE +4418 -17
- data/LICENSE.rb +1 -1
- data/README.md +19 -1
- data/Rakefile +8 -1
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/test_projects_cleanup.rb +45 -3
- data/ci/postgresql/pom.xml +57 -0
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/docker-compose.lcm.yml +3 -0
- data/gdc_fossa_ruby_sdk.yaml +1 -0
- data/gooddata.gemspec +8 -5
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +11 -1
- data/lcm.rake +10 -4
- data/lib/gooddata.rb +2 -0
- data/lib/gooddata/cloud_resources/{cloud_resouce_factory.rb → cloud_resource_factory.rb} +8 -0
- data/lib/gooddata/cloud_resources/cloud_resources.rb +1 -1
- data/lib/gooddata/cloud_resources/postgresql/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/postgresql/postgresql_client.rb +107 -0
- data/lib/gooddata/commands/scaffold.rb +9 -10
- data/lib/gooddata/core/nil_logger.rb +3 -1
- data/lib/gooddata/helpers/data_helper.rb +1 -2
- data/lib/gooddata/helpers/global_helpers.rb +6 -5
- data/lib/gooddata/helpers/global_helpers_params.rb +2 -2
- data/lib/gooddata/lcm/actions/associate_clients.rb +8 -2
- data/lib/gooddata/lcm/actions/base_action.rb +0 -2
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +2 -1
- data/lib/gooddata/lcm/actions/migrate_gdc_date_dimension.rb +116 -0
- data/lib/gooddata/lcm/actions/provision_clients.rb +31 -10
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +3 -1
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +4 -0
- data/lib/gooddata/lcm/actions/synchronize_users.rb +7 -6
- data/lib/gooddata/lcm/lcm2.rb +1 -2
- data/lib/gooddata/lcm/types/base_type.rb +0 -2
- data/lib/gooddata/mixins/md_object_query.rb +8 -6
- data/lib/gooddata/models/blueprint/project_blueprint.rb +0 -2
- data/lib/gooddata/models/client.rb +14 -12
- data/lib/gooddata/models/data_source.rb +664 -0
- data/lib/gooddata/models/domain.rb +3 -2
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/metadata/analytical_dashboard.rb +49 -0
- data/lib/gooddata/models/metadata/analytical_visualization_object.rb +30 -0
- data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
- data/lib/gooddata/models/metadata/visualization_object.rb +50 -0
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/project.rb +104 -13
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +0 -1
- data/lib/gooddata/models/user_group.rb +0 -1
- data/lib/gooddata/rest/connection.rb +6 -4
- data/lib/gooddata/rest/phmap.rb +1 -1
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +20 -20
- data/DEPENDENCIES.md +0 -880
@@ -5,7 +5,6 @@
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
6
6
|
|
7
7
|
require 'cgi'
|
8
|
-
require 'active_support/core_ext/hash/compact'
|
9
8
|
|
10
9
|
require_relative 'profile'
|
11
10
|
require_relative '../extensions/enumerable'
|
@@ -457,10 +456,12 @@ Available values for setting language are: #{available_languages}."
|
|
457
456
|
alias_method :add_clients_settings, :update_clients_settings
|
458
457
|
|
459
458
|
def update_clients(data, options = {})
|
459
|
+
results = []
|
460
460
|
data.group_by(&:data_product_id).each do |data_product_id, client_update_data|
|
461
461
|
data_product = data_products(data_product_id)
|
462
|
-
data_product.update_clients(client_update_data, options)
|
462
|
+
results.concat data_product.update_clients(client_update_data, options)
|
463
463
|
end
|
464
|
+
results
|
464
465
|
end
|
465
466
|
|
466
467
|
# Update user in domain
|
@@ -105,6 +105,7 @@ module GoodData
|
|
105
105
|
d[:title] = date_dim['dateDimension']['title']
|
106
106
|
d[:urn] = date_dim['dateDimension']['urn']
|
107
107
|
d[:identifier_prefix] = date_dim['dateDimension']['identifierPrefix']
|
108
|
+
d[:identifier] = date_dim['dateDimension']['identifier'] if date_dim['dateDimension']['identifier']
|
108
109
|
d[:columns] = parse_bridges(date_dim)
|
109
110
|
end
|
110
111
|
end
|
@@ -0,0 +1,49 @@
|
|
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
|
+
require_relative 'analytical_visualization_object'
|
9
|
+
|
10
|
+
module GoodData
|
11
|
+
class AnalyticalDashboard < GoodData::AnalyticalVisualizationObject
|
12
|
+
EMPTY_OBJECT = {
|
13
|
+
'analyticalDashboard' => {
|
14
|
+
'content' => {
|
15
|
+
'filterContext' => '',
|
16
|
+
'layout' => {},
|
17
|
+
'widgets' => []
|
18
|
+
},
|
19
|
+
'meta' => {
|
20
|
+
'deprecated' => '0',
|
21
|
+
'summary' => '',
|
22
|
+
'title' => ''
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
ASSIGNABLE_MEMBERS = %i[filterContext layout widgets deprecated summary title]
|
28
|
+
|
29
|
+
class << self
|
30
|
+
# Method intended to get all AnalyticalDashboard objects in a specified project
|
31
|
+
#
|
32
|
+
# @param options [Hash] the options hash
|
33
|
+
# @option options [Boolean] :full with true value will pull in full objects. Default is false value
|
34
|
+
# @return [Array<GoodData::AnalyticalDashboard>] Return AnalyticalDashboard list
|
35
|
+
def all(options = { :client => GoodData.connection, :project => GoodData.project })
|
36
|
+
query('analyticalDashboard', AnalyticalDashboard, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Create Analytical Dashboard in the specify project
|
40
|
+
#
|
41
|
+
# @param analytical_dashboard [Hash] the data of object will be created
|
42
|
+
# @param options [Hash] The project that the object will be created in
|
43
|
+
# @return GoodData::AnalyticalDashboard object
|
44
|
+
def create(analytical_dashboard = {}, options = { :client => GoodData.client, :project => GoodData.project })
|
45
|
+
GoodData::AnalyticalVisualizationObject.create(analytical_dashboard, AnalyticalDashboard, EMPTY_OBJECT, ASSIGNABLE_MEMBERS, options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 AnalyticalVisualizationObject < GoodData::MdObject
|
10
|
+
class << self
|
11
|
+
# Create a specify object in the specify project
|
12
|
+
#
|
13
|
+
# @param object_data [Hash] the data of object will be created
|
14
|
+
# @param klass [Class] A class used for instantiating the returned data
|
15
|
+
# @param empty_data_object [Hash] the empty data of object will be created
|
16
|
+
# @param assignable_properties [Hash] the properties allow updating
|
17
|
+
# @param options [Hash] The project that the object will be created in
|
18
|
+
# @return klass object
|
19
|
+
def create(object_data, klass, empty_data_object = {}, assignable_properties = [], options = { :client => GoodData.client, :project => GoodData.project })
|
20
|
+
client, project = GoodData.get_client_and_project(GoodData::Helpers.symbolize_keys(options))
|
21
|
+
|
22
|
+
res = client.create(klass, GoodData::Helpers.deep_dup(GoodData::Helpers.stringify_keys(empty_data_object)), :project => project)
|
23
|
+
object_data.each do |k, v|
|
24
|
+
res.send("#{k}=", v) if assignable_properties.include? k
|
25
|
+
end
|
26
|
+
res
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,50 @@
|
|
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
|
+
require_relative 'analytical_visualization_object'
|
9
|
+
|
10
|
+
module GoodData
|
11
|
+
class VisualizationObject < GoodData::AnalyticalVisualizationObject
|
12
|
+
EMPTY_OBJECT = {
|
13
|
+
'visualizationObject' => {
|
14
|
+
'content' => {
|
15
|
+
'buckets' => [],
|
16
|
+
'properties' => '',
|
17
|
+
'visualizationClass' => {}
|
18
|
+
},
|
19
|
+
'links' => {},
|
20
|
+
'meta' => {
|
21
|
+
'deprecated' => '0',
|
22
|
+
'summary' => '',
|
23
|
+
'title' => ''
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
ASSIGNABLE_MEMBERS = %i[buckets properties visualizationClass deprecated summary title]
|
29
|
+
|
30
|
+
class << self
|
31
|
+
# Method intended to get all VisualizationObject objects in a specified project
|
32
|
+
#
|
33
|
+
# @param options [Hash] the options hash
|
34
|
+
# @option options [Boolean] :full with true value to pull full objects
|
35
|
+
# @return [Array<GoodData::VisualizationObject>] Return VisualizationObject list
|
36
|
+
def all(options = { :client => GoodData.connection, :project => GoodData.project })
|
37
|
+
query('visualizationObject', VisualizationObject, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Create Visualization Object in the specify project
|
41
|
+
#
|
42
|
+
# @param visualization_object [Hash] the data of object will be created
|
43
|
+
# @param options [Hash] The project that the object will be created in
|
44
|
+
# @return GoodData::VisualizationObject object
|
45
|
+
def create(visualization_object = {}, options = { :client => GoodData.client, :project => GoodData.project })
|
46
|
+
GoodData::AnalyticalVisualizationObject.create(visualization_object, VisualizationObject, EMPTY_OBJECT, ASSIGNABLE_MEMBERS, options)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -118,11 +118,13 @@ module GoodData
|
|
118
118
|
GoodData.logger.info("Deploying #{path}") if verbose
|
119
119
|
|
120
120
|
deployed_path = Process.upload_package(path, files_to_exclude, client: client, project: project)
|
121
|
+
data_sources = options[:data_sources] || []
|
121
122
|
data = {
|
122
123
|
:process => {
|
123
124
|
:name => deploy_name,
|
124
125
|
:path => "/uploads/#{File.basename(deployed_path)}",
|
125
|
-
:type => type
|
126
|
+
:type => type,
|
127
|
+
:dataSources => data_sources
|
126
128
|
}
|
127
129
|
}
|
128
130
|
|
@@ -171,10 +173,12 @@ module GoodData
|
|
171
173
|
verbose = options[:verbose] || false
|
172
174
|
GoodData.logger.info("Deploying #{path}") if verbose
|
173
175
|
|
176
|
+
data_sources = options[:data_sources] || []
|
174
177
|
data = {
|
175
178
|
process: {
|
176
179
|
name: deploy_name,
|
177
180
|
path: path,
|
181
|
+
dataSources: data_sources,
|
178
182
|
type: 'RUBY'
|
179
183
|
}
|
180
184
|
}
|
@@ -185,7 +189,7 @@ module GoodData
|
|
185
189
|
def deploy_component(data, options = { client: GoodData.client, project: GoodData.project })
|
186
190
|
client, project = GoodData.get_client_and_project(options)
|
187
191
|
data = { process: data } unless data[:process]
|
188
|
-
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component].include? k }
|
192
|
+
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| %i[type name component dataSources].include? k }
|
189
193
|
data[:process][:component] = GoodData::Helpers.symbolize_keys(data[:process][:component]).select { |k| %i[name version configLocation config].include? k }
|
190
194
|
|
191
195
|
save(data, options)
|
@@ -266,7 +270,7 @@ module GoodData
|
|
266
270
|
# @option options [String] :name Readable name of the process
|
267
271
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
268
272
|
def deploy(path, options = {})
|
269
|
-
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type }.merge(options))
|
273
|
+
Process.deploy(path, { client: client, process_id: process_id, :project => project, :name => name, :type => type, :data_sources => data_sources }.merge(options))
|
270
274
|
end
|
271
275
|
|
272
276
|
# Downloads the process from S3 in a zipped form.
|
@@ -326,6 +330,10 @@ module GoodData
|
|
326
330
|
process['component']
|
327
331
|
end
|
328
332
|
|
333
|
+
def data_sources
|
334
|
+
process['dataSources']
|
335
|
+
end
|
336
|
+
|
329
337
|
# Determines whether the process is an ADDv2 component.
|
330
338
|
# @return [Bool] True if the process is an ADDv2 component.
|
331
339
|
def add_v2_component?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
|
-
# Copyright (c) 2010-
|
3
|
+
# Copyright (c) 2010-2021 GoodData Corporation. All rights reserved.
|
4
4
|
# This source code is licensed under the BSD-style license found in the
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
6
6
|
|
@@ -13,7 +13,6 @@ require 'zip'
|
|
13
13
|
require 'net/smtp'
|
14
14
|
|
15
15
|
require 'active_support/core_ext/hash/except'
|
16
|
-
require 'active_support/core_ext/hash/compact'
|
17
16
|
require 'active_support/core_ext/hash/slice'
|
18
17
|
|
19
18
|
require_relative '../exceptions/no_project_error'
|
@@ -38,7 +37,8 @@ require_relative 'metadata/scheduled_mail/report_attachment'
|
|
38
37
|
|
39
38
|
module GoodData
|
40
39
|
class Project < Rest::Resource
|
41
|
-
|
40
|
+
USER_ACCOUNT_PATH = '/gdc/account/profile/'
|
41
|
+
USERSPROJECTS_PATH = USER_ACCOUNT_PATH + '%s/projects'
|
42
42
|
PROJECTS_PATH = '/gdc/projects'
|
43
43
|
PROJECT_PATH = '/gdc/projects/%s'
|
44
44
|
SLIS_PATH = '/ldm/singleloadinterface'
|
@@ -261,21 +261,26 @@ module GoodData
|
|
261
261
|
# @option ads_output_stage_uri Uri of the source output stage. It must be in the same domain as the target project.
|
262
262
|
def transfer_processes(from_project, to_project, options = {})
|
263
263
|
options = GoodData::Helpers.symbolize_keys(options)
|
264
|
+
aliases = {}
|
264
265
|
to_project_processes = to_project.processes
|
265
266
|
additional_hidden_params = options[:additional_hidden_params] || {}
|
266
267
|
result = from_project.processes.uniq(&:name).map do |process|
|
267
|
-
fail "The process name #{process.name} must be unique in
|
268
|
+
fail "The process name #{process.name} must be unique in transferred project #{to_project}" if to_project_processes.count { |p| p.name == process.name } > 1
|
268
269
|
next if process.type == :dataload || process.add_v2_component?
|
270
|
+
collect_process_aliases(process.data, from_project.client, aliases)
|
269
271
|
|
270
272
|
to_process = to_project_processes.find { |p| p.name == process.name }
|
271
273
|
|
274
|
+
data_sources = GoodData::Helpers.symbolize_keys_recursively!(process.data_sources)
|
275
|
+
data_sources = replace_data_source_ids(data_sources, to_project.client, aliases)
|
272
276
|
to_process = if process.path
|
273
277
|
to_process.delete if to_process
|
274
|
-
|
278
|
+
Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project, data_sources: data_sources)
|
275
279
|
elsif process.component
|
276
280
|
to_process.delete if to_process
|
277
281
|
process_hash = GoodData::Helpers::DeepMergeableHash[GoodData::Helpers.symbolize_keys(process.to_hash)].deep_merge(additional_hidden_params)
|
278
|
-
|
282
|
+
process_hash = replace_process_data_source_ids(process_hash, to_project.client, aliases)
|
283
|
+
Process.deploy_component(process_hash, project: to_project, client: to_project.client)
|
279
284
|
else
|
280
285
|
Dir.mktmpdir('etl_transfer') do |dir|
|
281
286
|
dir = Pathname(dir)
|
@@ -283,11 +288,10 @@ module GoodData
|
|
283
288
|
File.open(filename, 'w') do |f|
|
284
289
|
f << process.download
|
285
290
|
end
|
286
|
-
|
287
291
|
if to_process
|
288
|
-
to_process.deploy(filename, type: process.type, name: process.name)
|
292
|
+
to_process.deploy(filename, type: process.type, name: process.name, data_sources: data_sources)
|
289
293
|
else
|
290
|
-
to_project.deploy_process(filename, type: process.type, name: process.name)
|
294
|
+
to_project.deploy_process(filename, type: process.type, name: process.name, data_sources: data_sources)
|
291
295
|
end
|
292
296
|
end
|
293
297
|
end
|
@@ -318,6 +322,78 @@ module GoodData
|
|
318
322
|
result.compact
|
319
323
|
end
|
320
324
|
|
325
|
+
def collect_process_aliases(process_data, client, aliases)
|
326
|
+
data_sources = process_data.dig('process', 'dataSources')
|
327
|
+
unless data_sources.blank?
|
328
|
+
data_sources.map do |data_source|
|
329
|
+
get_data_source_alias(data_source['id'], client, aliases)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
component = process_data.dig('process', 'component')
|
333
|
+
get_data_source_alias(component['configLocation']['dataSourceConfig']['id'], client, aliases) if component&.dig('configLocation', 'dataSourceConfig')
|
334
|
+
aliases
|
335
|
+
end
|
336
|
+
|
337
|
+
def get_data_source_alias(data_source_id, client, aliases)
|
338
|
+
unless aliases[data_source_id]
|
339
|
+
data_source = GoodData::DataSource.from_id(data_source_id, client: client)
|
340
|
+
if data_source&.dig('dataSource', 'alias')
|
341
|
+
aliases[data_source_id] = {
|
342
|
+
:type => get_data_source_type(data_source),
|
343
|
+
:alias => data_source['dataSource']['alias']
|
344
|
+
}
|
345
|
+
end
|
346
|
+
end
|
347
|
+
aliases[data_source_id]
|
348
|
+
end
|
349
|
+
|
350
|
+
def get_data_source_type(data_source_data)
|
351
|
+
data_source_data&.dig('dataSource', 'connectionInfo') ? data_source_data['dataSource']['connectionInfo'].first[0].upcase : ""
|
352
|
+
end
|
353
|
+
|
354
|
+
def replace_process_data_source_ids(process_data, client, aliases)
|
355
|
+
component = process_data.dig(:process, :component)
|
356
|
+
if component&.dig(:configLocation, :dataSourceConfig)
|
357
|
+
the_alias = aliases[component[:configLocation][:dataSourceConfig][:id]]
|
358
|
+
process_data[:process][:component][:configLocation][:dataSourceConfig][:id] = verify_data_source_alias(the_alias, client)
|
359
|
+
end
|
360
|
+
process_data[:process][:dataSources] = replace_data_source_ids(process_data[:process][:dataSources], client, aliases)
|
361
|
+
process_data
|
362
|
+
end
|
363
|
+
|
364
|
+
def replace_data_source_ids(data_sources, client, aliases)
|
365
|
+
array_data_sources = []
|
366
|
+
if data_sources && !data_sources.empty?
|
367
|
+
data_sources.map do |data_source|
|
368
|
+
new_id = verify_data_source_alias(aliases[data_source[:id]], client)
|
369
|
+
array_data_sources.push(:id => new_id)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
array_data_sources
|
373
|
+
end
|
374
|
+
|
375
|
+
# Verify whether the data source exists in the domain using its alias
|
376
|
+
#
|
377
|
+
# @param [String] ds_alias The data source's alias
|
378
|
+
# @param [Object] client The Rest Client object
|
379
|
+
# @return [String] Id of the data source or failed with the reason
|
380
|
+
def verify_data_source_alias(ds_alias, client)
|
381
|
+
domain = client.connection.server.url
|
382
|
+
fail "The data source alias is empty, check your data source configuration." unless ds_alias
|
383
|
+
|
384
|
+
uri = "/gdc/dataload/dataSources/internal/availableAlias?alias=#{ds_alias[:alias]}"
|
385
|
+
res = client.get(uri)
|
386
|
+
fail "Unable to get information about the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" unless res
|
387
|
+
fail "Unable to find the #{ds_alias[:type]} Data Source '#{ds_alias[:alias]}' in the domain '#{domain}'" if res['availableAlias']['available']
|
388
|
+
|
389
|
+
ds_type = res['availableAlias']['existingDataSource']['type']
|
390
|
+
if ds_type && ds_type != ds_alias[:type]
|
391
|
+
fail "Wrong Data Source type - the '#{ds_type}' type is expected but the Data Source '#{ds_alias[:alias]}' in the domain '#{domain}' has the '#{ds_alias[:type]}' type"
|
392
|
+
else
|
393
|
+
res['availableAlias']['existingDataSource']['id']
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
321
397
|
def transfer_user_groups(from_project, to_project)
|
322
398
|
from_project.user_groups.map do |ug|
|
323
399
|
# migrate groups
|
@@ -625,6 +701,7 @@ module GoodData
|
|
625
701
|
def blueprint(options = {})
|
626
702
|
options = { include_ca: true }.merge(options)
|
627
703
|
result = client.get("/gdc/projects/#{pid}/model/view", params: { includeDeprecated: true, includeGrain: true, includeCA: options[:include_ca] })
|
704
|
+
|
628
705
|
polling_url = result['asyncTask']['link']['poll']
|
629
706
|
model = client.poll_on_code(polling_url, options)
|
630
707
|
bp = GoodData::Model::FromWire.from_wire(model, options)
|
@@ -1661,7 +1738,7 @@ module GoodData
|
|
1661
1738
|
end
|
1662
1739
|
end
|
1663
1740
|
diff_results = diff_results.map do |u|
|
1664
|
-
u[:login_uri] =
|
1741
|
+
u[:login_uri] = USER_ACCOUNT_PATH + u[:login]
|
1665
1742
|
u
|
1666
1743
|
end
|
1667
1744
|
return diff_results if options[:dry_run]
|
@@ -1897,17 +1974,17 @@ module GoodData
|
|
1897
1974
|
|
1898
1975
|
def resolve_roles(login, desired_roles, options = {})
|
1899
1976
|
user = if login.is_a?(String) && login.include?('@')
|
1900
|
-
|
1977
|
+
USER_ACCOUNT_PATH + login
|
1901
1978
|
elsif login.is_a?(String)
|
1902
1979
|
login
|
1903
1980
|
elsif login.is_a?(Hash) && login[:login]
|
1904
|
-
|
1981
|
+
USER_ACCOUNT_PATH + login[:login]
|
1905
1982
|
elsif login.is_a?(Hash) && login[:uri]
|
1906
1983
|
login[:uri]
|
1907
1984
|
elsif login.respond_to?(:uri) && login.uri
|
1908
1985
|
login.uri
|
1909
1986
|
elsif login.respond_to?(:login) && login.login
|
1910
|
-
|
1987
|
+
USER_ACCOUNT_PATH + login.login
|
1911
1988
|
else
|
1912
1989
|
fail "Unsupported user specification #{login}"
|
1913
1990
|
end
|
@@ -1922,6 +1999,20 @@ module GoodData
|
|
1922
1999
|
[user, roles]
|
1923
2000
|
end
|
1924
2001
|
|
2002
|
+
def upgrade_custom_v2(message, options = {})
|
2003
|
+
uri = "/gdc/md/#{pid}/datedimension/upgrade"
|
2004
|
+
poll_result = client&.post(uri, message)
|
2005
|
+
|
2006
|
+
return poll_result['wTaskStatus']['status'] if poll_result['wTaskStatus'] && poll_result['wTaskStatus']['status']
|
2007
|
+
|
2008
|
+
polling_uri = poll_result['asyncTask']['link']['poll']
|
2009
|
+
result = client&.poll_on_response(polling_uri, options) do |body|
|
2010
|
+
body && body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
2011
|
+
end
|
2012
|
+
|
2013
|
+
result['wTaskStatus']['status'] == 'OK' ? 'OK' : 'FAIL'
|
2014
|
+
end
|
2015
|
+
|
1925
2016
|
def add
|
1926
2017
|
@add ||= GoodData::AutomatedDataDistribution.new(self)
|
1927
2018
|
@add
|