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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +12 -0
- data/README.md +5 -2
- data/Rakefile +0 -1
- data/dev-gooddata-sso.pub.encrypted +40 -0
- data/gooddata.gemspec +3 -3
- data/lib/gooddata/connection.rb +23 -13
- data/lib/gooddata/helpers/data_helper.rb +0 -1
- data/lib/gooddata/lcm/actions/apply_custom_maql.rb +8 -1
- data/lib/gooddata/lcm/actions/associate_clients.rb +8 -1
- data/lib/gooddata/lcm/actions/base_action.rb +10 -0
- data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +7 -1
- data/lib/gooddata/lcm/actions/collect_client_projects.rb +3 -0
- data/lib/gooddata/lcm/actions/collect_clients.rb +3 -1
- data/lib/gooddata/lcm/actions/collect_data_product.rb +10 -2
- data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +12 -1
- data/lib/gooddata/lcm/actions/collect_ldm_objects.rb +6 -2
- data/lib/gooddata/lcm/actions/collect_meta.rb +1 -1
- data/lib/gooddata/lcm/actions/collect_segment_clients.rb +8 -1
- data/lib/gooddata/lcm/actions/collect_segments.rb +6 -5
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +1 -1
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +10 -4
- data/lib/gooddata/lcm/actions/create_segment_masters.rb +12 -2
- data/lib/gooddata/lcm/actions/ensure_data_product.rb +10 -0
- data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -1
- data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +3 -0
- data/lib/gooddata/lcm/actions/execute_schedules.rb +10 -0
- data/lib/gooddata/lcm/actions/import_object_collections.rb +1 -1
- data/lib/gooddata/lcm/actions/provision_clients.rb +12 -2
- data/lib/gooddata/lcm/actions/purge_clients.rb +2 -0
- data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +3 -0
- data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_cas.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_clients.rb +11 -1
- data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +12 -7
- data/lib/gooddata/lcm/actions/synchronize_label_types.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +18 -7
- data/lib/gooddata/lcm/actions/synchronize_meta.rb +9 -0
- data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +11 -1
- data/lib/gooddata/lcm/actions/synchronize_processes.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_schedules.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +6 -0
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +60 -15
- data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_users.rb +106 -3
- data/lib/gooddata/lcm/actions/update_release_table.rb +19 -0
- data/lib/gooddata/lcm/helpers/check_helper.rb +21 -6
- data/lib/gooddata/lcm/lcm2.rb +35 -22
- data/lib/gooddata/lcm/types/class/gd_logger.rb +23 -0
- data/lib/gooddata/lcm/types/class/gd_product.rb +23 -0
- data/lib/gooddata/lcm/types/class/gd_project.rb +23 -0
- data/lib/gooddata/lcm/types/class/smart_hash.rb +23 -0
- data/lib/gooddata/lcm/types/complex/segment.rb +1 -1
- data/lib/gooddata/lcm/types/scalar/integer.rb +2 -2
- data/lib/gooddata/lcm/types/special/any.rb +18 -0
- data/lib/gooddata/models/blueprint/dataset_blueprint.rb +1 -1
- data/lib/gooddata/models/blueprint/to_manifest.rb +1 -3
- data/lib/gooddata/models/blueprint/to_wire.rb +2 -1
- data/lib/gooddata/models/from_wire.rb +13 -1
- data/lib/gooddata/models/metadata/folder.rb +22 -0
- data/lib/gooddata/models/metadata/metric.rb +5 -8
- data/lib/gooddata/models/model.rb +1 -1
- data/lib/gooddata/models/process.rb +42 -32
- data/lib/gooddata/models/project.rb +19 -36
- data/lib/gooddata/models/project_creator.rb +3 -1
- data/lib/gooddata/models/project_role.rb +3 -4
- data/lib/gooddata/models/schedule.rb +0 -2
- data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +9 -1
- data/lib/gooddata/models/user_filters/user_filter.rb +1 -2
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -6
- data/lib/gooddata/rest/client.rb +1 -2
- data/lib/gooddata/rest/connection.rb +12 -46
- data/lib/gooddata/rest/phmap.rb +101 -56
- data/lib/gooddata/version.rb +1 -1
- data/rubydev_public.gpg.encrypted +51 -0
- data/rubydev_secret_keys.gpg.encrypted +109 -0
- data/spec/data/user_filters.csv +2 -0
- data/spec/environment/default.rb +2 -2
- data/spec/environment/development.rb +1 -1
- data/spec/environment/staging.rb +2 -3
- data/spec/environment/testing.rb +4 -4
- data/spec/integration/connection_spec.rb +37 -0
- data/spec/integration/core/connection_spec.rb +1 -1
- data/spec/integration/core/logging_spec.rb +8 -6
- data/spec/integration/core/project_spec.rb +1 -1
- data/spec/integration/mandatory_user_filter_spec.rb +53 -0
- data/spec/integration/mixins/id_to_uri_spec.rb +17 -5
- data/spec/integration/models/label_spec.rb +9 -0
- data/spec/integration/models/metric_spec.rb +24 -0
- data/spec/integration/models/process_spec.rb +35 -0
- data/spec/integration/models/project_role_spec.rb +1 -1
- data/spec/integration/models/schedule_spec.rb +0 -8
- data/spec/integration/schedule_spec.rb +4 -6
- data/spec/integration/user_filters_spec.rb +20 -16
- data/spec/integration/user_group_spec.rb +1 -1
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/can_assign_a_custom_logger.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/client_logs_when_given_custom_message.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/has_the_request_id_logged_when_I_passed_it.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_off/Disables_logging.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_on/Enables_logging.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project/Returns_project_assigned.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_nil.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_directly.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_ID.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_URL.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_with_project/Uses_project_specified.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_Metric/all.yml +2065 -0
- data/spec/integration/vcr_cassettes/GoodData_Metric/should_be_able_to_update_folders.yml +119 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/all.yml +9812 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_get_json_containing_correct_id.yml +174 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_return_nil_for_unknown_id.yml +58 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_throw_BadRequest_for_-1.yml +63 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_connect/Connects_using_username_and_password.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_disconnect/Connects_using_username_and_password.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_generate_request_id/Generates_a_non-empty_string.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_/Should_list_user_groups_as_Array.yml +56 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_add_members/Should_add_member.yml +315 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_members/Should_return_members_as_array.yml +54 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_remove_members/Should_remove_existing_members.yml +258 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_save/updates_existing_group.yml +159 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_set_members/Should_set_new_members.yml +158 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/all.yml +809 -0
- data/spec/spec_helper.rb +46 -2
- data/spec/unit/actions/associate_clients_spec.rb +2 -1
- data/spec/unit/actions/collect_data_product_spec.rb +3 -1
- data/spec/unit/actions/collect_segment_clients_spec.rb +1 -0
- data/spec/unit/actions/create_segment_masters_spec.rb +1 -0
- data/spec/unit/actions/ensure_data_product_spec.rb +1 -0
- data/spec/unit/actions/ensure_technical_users_domain_spec.rb +2 -0
- data/spec/unit/actions/ensure_technical_users_project_spec.rb +4 -0
- data/spec/unit/actions/provision_clients_spec.rb +2 -1
- data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +0 -6
- data/spec/unit/actions/synchronize_ldm_spec.rb +20 -7
- data/spec/unit/actions/synchronize_user_filters_spec.rb +21 -0
- data/spec/unit/helpers/check_helper_production_spec.rb +34 -0
- data/spec/unit/helpers/check_helper_spec.rb +97 -9
- data/spec/unit/lcm/lcm2_spec.rb +67 -3
- data/spec/unit/models/blueprint/to_wire_spec.rb +1 -0
- data/spec/unit/models/dataset_blueprint.rb +14 -0
- data/spec/unit/models/from_wire_spec.rb +20 -0
- data/spec/unit/models/model_spec.rb +10 -0
- data/spec/unit/models/to_manifest_spec.rb +29 -0
- data/spec/unit/models/user_filters/user_filter_builder_spec.rb +44 -6
- data/spec/unit/rest/phmap_spec.rb +117 -0
- data/spec/vcr_configurer.rb +63 -0
- metadata +283 -24
- data/lib/gooddata/lcm/actions/ensure_segments.rb +0 -32
data/lib/gooddata/lcm/lcm2.rb
CHANGED
@@ -13,28 +13,35 @@ require_relative 'helpers/helpers'
|
|
13
13
|
module GoodData
|
14
14
|
module LCM2
|
15
15
|
class SmartHash < Hash
|
16
|
+
@specification = nil
|
16
17
|
def method_missing(name, *_args)
|
17
|
-
|
18
|
+
data(name)
|
19
|
+
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
value = self[k]
|
23
|
-
break
|
24
|
-
end
|
25
|
-
end
|
21
|
+
def [](variable)
|
22
|
+
data(variable)
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
def clear_filters
|
26
|
+
@specification = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_filters(filter)
|
30
|
+
@specification = filter.to_hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_specification(variable)
|
34
|
+
if @specification && !@specification[variable.to_sym] && !@specification[variable.to_s] \
|
35
|
+
&& !@specification[variable.to_s.downcase.to_sym] && !@specification[variable.to_s.downcase]
|
36
|
+
fail "Param #{variable} is not defined in the specification"
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
40
|
+
def data(variable)
|
41
|
+
check_specification(variable)
|
42
|
+
fetch(keys.find { |k| k.to_s.downcase.to_sym == variable.to_s.downcase.to_sym }, nil)
|
43
|
+
end
|
44
|
+
|
38
45
|
def key?(key)
|
39
46
|
return true if super
|
40
47
|
|
@@ -308,12 +315,7 @@ module GoodData
|
|
308
315
|
|
309
316
|
# Invoke action
|
310
317
|
begin
|
311
|
-
|
312
|
-
|
313
|
-
# Check if all required parameters were passed
|
314
|
-
BaseAction.check_params(action.const_get('PARAMS'), params)
|
315
|
-
|
316
|
-
out = action.send(:call, params)
|
318
|
+
out = run_action action, params
|
317
319
|
rescue => e
|
318
320
|
errors << {
|
319
321
|
action: action,
|
@@ -357,6 +359,17 @@ module GoodData
|
|
357
359
|
}
|
358
360
|
end
|
359
361
|
|
362
|
+
def run_action(action, params)
|
363
|
+
GoodData.logger.info("Running #{action.name} action ...")
|
364
|
+
params.clear_filters
|
365
|
+
# Check if all required parameters were passed
|
366
|
+
BaseAction.check_params(action.const_get('PARAMS'), params)
|
367
|
+
params.setup_filters(action.const_get('PARAMS'))
|
368
|
+
out = action.send(:call, params)
|
369
|
+
params.clear_filters
|
370
|
+
out
|
371
|
+
end
|
372
|
+
|
360
373
|
def check_unused_params(actions, params)
|
361
374
|
default_params = [
|
362
375
|
:client_gdc_hostname,
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
require_relative '../base_type'
|
8
|
+
|
9
|
+
require_relative 'class'
|
10
|
+
|
11
|
+
module GoodData
|
12
|
+
module LCM2
|
13
|
+
module Type
|
14
|
+
class GdLogger < ClassType
|
15
|
+
CATEGORY = :class
|
16
|
+
|
17
|
+
def check(value)
|
18
|
+
value.class == Logger
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
require_relative '../base_type'
|
8
|
+
|
9
|
+
require_relative 'class'
|
10
|
+
|
11
|
+
module GoodData
|
12
|
+
module LCM2
|
13
|
+
module Type
|
14
|
+
class GDDataProductType < ClassType
|
15
|
+
CATEGORY = :class
|
16
|
+
|
17
|
+
def check(value)
|
18
|
+
value.class == GoodData::DataProduct
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
require_relative '../base_type'
|
8
|
+
|
9
|
+
require_relative 'class'
|
10
|
+
|
11
|
+
module GoodData
|
12
|
+
module LCM2
|
13
|
+
module Type
|
14
|
+
class GdProjectType < ClassType
|
15
|
+
CATEGORY = :class
|
16
|
+
|
17
|
+
def check(value)
|
18
|
+
value.class == GoodData::Project
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
require_relative '../base_type'
|
8
|
+
|
9
|
+
require_relative 'class'
|
10
|
+
|
11
|
+
module GoodData
|
12
|
+
module LCM2
|
13
|
+
module Type
|
14
|
+
class GdSmartHashType < ClassType
|
15
|
+
CATEGORY = :class
|
16
|
+
|
17
|
+
def check(value)
|
18
|
+
value.class == GoodData::LCM2::SmartHash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -22,7 +22,7 @@ module GoodData
|
|
22
22
|
param :development_pid, instance_of(Type::StringType), required: true
|
23
23
|
|
24
24
|
description 'Storage Driver'
|
25
|
-
param :driver, instance_of(Type::StringType), required:
|
25
|
+
param :driver, instance_of(Type::StringType), required: false, default: 'pg'
|
26
26
|
|
27
27
|
description 'Master Project Name'
|
28
28
|
param :master_name, instance_of(Type::StringType), required: true
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
module GoodData
|
8
|
+
module LCM2
|
9
|
+
module Type
|
10
|
+
class AnyType
|
11
|
+
CATEGORY = :special
|
12
|
+
def check(_)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -98,7 +98,7 @@ module GoodData
|
|
98
98
|
# @param dataset [Hash] Dataset blueprint
|
99
99
|
# @return [Array<Hash>] returns the attribute or an empty array
|
100
100
|
def self.facts(dataset)
|
101
|
-
find_columns_by_type(dataset, :fact, :date_fact)
|
101
|
+
find_columns_by_type(dataset, :fact, :date_fact, :hll)
|
102
102
|
end
|
103
103
|
|
104
104
|
# Finds a specific column given a name
|
@@ -36,9 +36,7 @@ module GoodData
|
|
36
36
|
case c[:type].to_sym
|
37
37
|
when :label
|
38
38
|
label_to_manifest(project, dataset, c, mode)
|
39
|
-
when :fact
|
40
|
-
fact_to_manifest(project, dataset, c, mode)
|
41
|
-
when :date_fact
|
39
|
+
when :fact, :date_fact, :hll
|
42
40
|
fact_to_manifest(project, dataset, c, mode)
|
43
41
|
when :reference
|
44
42
|
reference_to_manifest(project, dataset, c, mode)
|
@@ -129,7 +129,8 @@ module GoodData
|
|
129
129
|
identifier: fact[:id],
|
130
130
|
title: GoodData::Model.title(fact),
|
131
131
|
folder: fact[:folder] || dataset[:folder] || GoodData::Model.title(dataset),
|
132
|
-
dataType: GoodData::Model.normalize_gd_data_type(fact[:gd_data_type]) || DEFAULT_FACT_DATATYPE
|
132
|
+
dataType: GoodData::Model.normalize_gd_data_type(fact[:gd_data_type]) || DEFAULT_FACT_DATATYPE,
|
133
|
+
type: fact[:type]
|
133
134
|
}
|
134
135
|
}
|
135
136
|
payload.tap do |p|
|
@@ -120,7 +120,7 @@ module GoodData
|
|
120
120
|
facts = stuff['dataset']['facts'] || []
|
121
121
|
facts.map do |fact|
|
122
122
|
{}.tap do |f|
|
123
|
-
f[:type] = fact
|
123
|
+
f[:type] = resolve_fact_type(fact)
|
124
124
|
f[:id] = fact['fact']['identifier']
|
125
125
|
f[:title] = fact['fact']['title']
|
126
126
|
f[:description] = fact['fact']['description'] if fact['fact']['description']
|
@@ -168,6 +168,18 @@ module GoodData
|
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
def self.resolve_fact_type(fact)
|
175
|
+
if fact['fact']['type'].to_s.downcase == 'hll'
|
176
|
+
:hll
|
177
|
+
elsif fact['fact']['identifier'] =~ /^dt\./
|
178
|
+
:date_fact
|
179
|
+
else
|
180
|
+
:fact
|
181
|
+
end
|
182
|
+
end
|
171
183
|
end
|
172
184
|
end
|
173
185
|
end
|
@@ -26,6 +26,28 @@ module GoodData
|
|
26
26
|
def all(options = { :client => GoodData.connection, :project => GoodData.project })
|
27
27
|
query('folder', Folder, options)
|
28
28
|
end
|
29
|
+
|
30
|
+
def create(opts)
|
31
|
+
title = opts[:title]
|
32
|
+
summary = opts[:summary] || ''
|
33
|
+
type = opts[:type] || 'fact'
|
34
|
+
|
35
|
+
folder = {
|
36
|
+
'folder' => {
|
37
|
+
'content' => {
|
38
|
+
'type' => Array(type)
|
39
|
+
},
|
40
|
+
'meta' => {
|
41
|
+
'tags' => '',
|
42
|
+
'summary' => summary,
|
43
|
+
'title' => title
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
client, project = GoodData.get_client_and_project(opts)
|
49
|
+
client.create(Folder, folder, project: project)
|
50
|
+
end
|
29
51
|
end
|
30
52
|
|
31
53
|
def entries
|
@@ -13,6 +13,11 @@ module GoodData
|
|
13
13
|
# Metric representation
|
14
14
|
class Metric < MdObject
|
15
15
|
include Mixin::Lockable
|
16
|
+
extend GoodData::Mixin::ContentPropertyReader
|
17
|
+
extend GoodData::Mixin::ContentPropertyWriter
|
18
|
+
|
19
|
+
content_property_reader :folders, :expression
|
20
|
+
content_property_writer :folders, :expression
|
16
21
|
|
17
22
|
class << self
|
18
23
|
# Method intended to get all objects of that type in a specified project
|
@@ -125,14 +130,6 @@ module GoodData
|
|
125
130
|
res.data[0][0] if res && !res.empty?
|
126
131
|
end
|
127
132
|
|
128
|
-
def expression
|
129
|
-
content['expression']
|
130
|
-
end
|
131
|
-
|
132
|
-
def expression=(value)
|
133
|
-
content['expression'] = value
|
134
|
-
end
|
135
|
-
|
136
133
|
def validate
|
137
134
|
fail 'Metric needs to have title' if title.nil?
|
138
135
|
true
|
@@ -86,7 +86,7 @@ module GoodData
|
|
86
86
|
'GDC.time.day_us_noleading', # M/d/yy
|
87
87
|
]
|
88
88
|
|
89
|
-
GD_DATA_TYPES = ['BIGINT', 'DOUBLE', 'INTEGER', 'INT', /^VARCHAR\(([1-9]\d{0,3}|10000)\)$/i, /^DECIMAL\(\d{1,3},\s*\d{1,3}\)$/i]
|
89
|
+
GD_DATA_TYPES = ['BIGINT', 'DOUBLE', 'INTEGER', 'INT', 'HLL', /^VARCHAR\(([1-9]\d{0,3}|10000)\)$/i, /^DECIMAL\(\d{1,3},\s*\d{1,3}\)$/i]
|
90
90
|
|
91
91
|
DEFAULT_FACT_DATATYPE = 'DECIMAL(12,2)'
|
92
92
|
DEFAULT_ATTRIBUTE_DATATYPE = 'VARCHAR(128)'
|
@@ -90,16 +90,23 @@ module GoodData
|
|
90
90
|
# @option options [String] :name Readable name of the process
|
91
91
|
# @option options [String] :process_id ID of a process to be redeployed (do not set if you want to create a new process)
|
92
92
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
93
|
-
def deploy(path, options = { :
|
94
|
-
|
95
|
-
|
96
|
-
|
93
|
+
def deploy(path, options = { client: GoodData.client, project: GoodData.project })
|
94
|
+
if path.is_a?(Hash) && path[:component]
|
95
|
+
deploy_component path, options
|
96
|
+
elsif path.to_s.start_with?(APP_STORE_URL)
|
97
|
+
deploy_brick path, options
|
98
|
+
elsif path.to_s =~ %r{\${.*}:(.*)\/(.*):\/}
|
99
|
+
deploy_from_appstore path.to_s, options
|
100
|
+
else
|
101
|
+
deploy_simple_process path, options
|
102
|
+
end
|
103
|
+
end
|
97
104
|
|
105
|
+
def deploy_simple_process(path, options = { client: GoodData.client, project: GoodData.project })
|
98
106
|
client, project = GoodData.get_client_and_project(options)
|
99
107
|
|
100
108
|
path = Pathname(path) || fail('Path is not specified')
|
101
109
|
files_to_exclude = options[:files_to_exclude].nil? ? [] : options[:files_to_exclude].map { |pname| Pathname(pname) }
|
102
|
-
process_id = options[:process_id]
|
103
110
|
|
104
111
|
type = options[:type] || 'GRAPH'
|
105
112
|
deploy_name = options[:name]
|
@@ -117,21 +124,7 @@ module GoodData
|
|
117
124
|
}
|
118
125
|
}
|
119
126
|
|
120
|
-
|
121
|
-
client.post("/gdc/projects/#{project.pid}/dataload/processes", data)
|
122
|
-
else
|
123
|
-
client.put("/gdc/projects/#{project.pid}/dataload/processes/#{process_id}", data)
|
124
|
-
end
|
125
|
-
|
126
|
-
File.delete(deployed_path) if File.exist?(deployed_path)
|
127
|
-
|
128
|
-
if res['asyncTask']
|
129
|
-
res = client.poll_on_response(res['asyncTask']['links']['poll']) { |body| body['asyncTask'] }
|
130
|
-
end
|
131
|
-
|
132
|
-
process = client.create(Process, res, project: project)
|
133
|
-
puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
|
134
|
-
process
|
127
|
+
save(data, options)
|
135
128
|
end
|
136
129
|
|
137
130
|
def deploy_brick(path, options = { :client => GoodData.client, :project => GoodData.project })
|
@@ -173,16 +166,12 @@ module GoodData
|
|
173
166
|
end
|
174
167
|
|
175
168
|
def deploy_from_appstore(path, options = { :client => GoodData.client, :project => GoodData.project })
|
176
|
-
client, project = GoodData.get_client_and_project(options)
|
177
|
-
|
178
169
|
deploy_name = options[:name]
|
179
170
|
fail ArgumentError, 'options[:name] can not be nil or empty!' if deploy_name.nil? || deploy_name.empty?
|
180
171
|
|
181
172
|
verbose = options[:verbose] || false
|
182
173
|
puts HighLine.color("Deploying #{path}", HighLine::BOLD) if verbose
|
183
174
|
|
184
|
-
process_id = options[:process_id]
|
185
|
-
|
186
175
|
data = {
|
187
176
|
process: {
|
188
177
|
name: deploy_name,
|
@@ -191,26 +180,43 @@ module GoodData
|
|
191
180
|
}
|
192
181
|
}
|
193
182
|
|
183
|
+
save(data, options)
|
184
|
+
end
|
185
|
+
|
186
|
+
def deploy_component(data, options = { client: GoodData.client, project: GoodData.project })
|
187
|
+
client, project = GoodData.get_client_and_project(options)
|
188
|
+
data = { process: data } unless data[:process]
|
189
|
+
data[:process] = GoodData::Helpers.symbolize_keys(data[:process]).select { |k| [:type, :name, :component].include? k }
|
190
|
+
data[:process][:component] = GoodData::Helpers.symbolize_keys(data[:process][:component]).select { |k| [:name, :version].include? k }
|
191
|
+
|
192
|
+
# a feature flag is required to create component type processes
|
193
|
+
client.post "/gdc/projects/#{project.pid}/projectFeatureFlags",
|
194
|
+
featureFlag: {
|
195
|
+
key: 'enableEtlComponent',
|
196
|
+
value: true
|
197
|
+
}
|
198
|
+
|
199
|
+
save(data, options)
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def save(data, options = { client: GoodData.client, project: GoodData.project })
|
205
|
+
client, project = GoodData.get_client_and_project(options)
|
206
|
+
process_id = data[:process_id]
|
194
207
|
res =
|
195
208
|
if process_id.nil?
|
196
209
|
client.post("/gdc/projects/#{project.pid}/dataload/processes", data)
|
197
|
-
|
198
210
|
else
|
199
211
|
client.put("/gdc/projects/#{project.pid}/dataload/processes/#{process_id}", data)
|
200
|
-
|
201
212
|
end
|
202
|
-
|
203
213
|
if res.keys.first == 'asyncTask'
|
204
214
|
res = JSON.parse(client.poll_on_code(res['asyncTask']['links']['poll'], options.merge(process: false)))
|
205
215
|
end
|
206
216
|
|
207
|
-
|
208
|
-
puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
|
209
|
-
process
|
217
|
+
client.create(Process, res, project: project)
|
210
218
|
end
|
211
219
|
|
212
|
-
private
|
213
|
-
|
214
220
|
def with_zip(opts = {})
|
215
221
|
client = opts[:client]
|
216
222
|
temp = Tempfile.new(['deploy-graph-archive', '.zip'])
|
@@ -326,6 +332,10 @@ module GoodData
|
|
326
332
|
process['path']
|
327
333
|
end
|
328
334
|
|
335
|
+
def component
|
336
|
+
process['component']
|
337
|
+
end
|
338
|
+
|
329
339
|
def schedules
|
330
340
|
project.schedules.select { |schedule| schedule.process_id == obj_id }
|
331
341
|
end
|