gooddata 1.0.2-java → 1.1.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 +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
|