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.
Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/CONTRIBUTING.md +12 -0
  4. data/README.md +5 -2
  5. data/Rakefile +0 -1
  6. data/dev-gooddata-sso.pub.encrypted +40 -0
  7. data/gooddata.gemspec +3 -3
  8. data/lib/gooddata/connection.rb +23 -13
  9. data/lib/gooddata/helpers/data_helper.rb +0 -1
  10. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +8 -1
  11. data/lib/gooddata/lcm/actions/associate_clients.rb +8 -1
  12. data/lib/gooddata/lcm/actions/base_action.rb +10 -0
  13. data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +7 -1
  14. data/lib/gooddata/lcm/actions/collect_client_projects.rb +3 -0
  15. data/lib/gooddata/lcm/actions/collect_clients.rb +3 -1
  16. data/lib/gooddata/lcm/actions/collect_data_product.rb +10 -2
  17. data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +12 -1
  18. data/lib/gooddata/lcm/actions/collect_ldm_objects.rb +6 -2
  19. data/lib/gooddata/lcm/actions/collect_meta.rb +1 -1
  20. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +8 -1
  21. data/lib/gooddata/lcm/actions/collect_segments.rb +6 -5
  22. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +1 -1
  23. data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +10 -4
  24. data/lib/gooddata/lcm/actions/create_segment_masters.rb +12 -2
  25. data/lib/gooddata/lcm/actions/ensure_data_product.rb +10 -0
  26. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -1
  27. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +3 -0
  28. data/lib/gooddata/lcm/actions/execute_schedules.rb +10 -0
  29. data/lib/gooddata/lcm/actions/import_object_collections.rb +1 -1
  30. data/lib/gooddata/lcm/actions/provision_clients.rb +12 -2
  31. data/lib/gooddata/lcm/actions/purge_clients.rb +2 -0
  32. data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +3 -0
  33. data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +4 -1
  34. data/lib/gooddata/lcm/actions/synchronize_cas.rb +7 -1
  35. data/lib/gooddata/lcm/actions/synchronize_clients.rb +11 -1
  36. data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +7 -1
  37. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +12 -7
  38. data/lib/gooddata/lcm/actions/synchronize_label_types.rb +4 -1
  39. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +18 -7
  40. data/lib/gooddata/lcm/actions/synchronize_meta.rb +9 -0
  41. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +11 -1
  42. data/lib/gooddata/lcm/actions/synchronize_processes.rb +7 -1
  43. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +4 -1
  44. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +6 -0
  45. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +60 -15
  46. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +7 -1
  47. data/lib/gooddata/lcm/actions/synchronize_users.rb +106 -3
  48. data/lib/gooddata/lcm/actions/update_release_table.rb +19 -0
  49. data/lib/gooddata/lcm/helpers/check_helper.rb +21 -6
  50. data/lib/gooddata/lcm/lcm2.rb +35 -22
  51. data/lib/gooddata/lcm/types/class/gd_logger.rb +23 -0
  52. data/lib/gooddata/lcm/types/class/gd_product.rb +23 -0
  53. data/lib/gooddata/lcm/types/class/gd_project.rb +23 -0
  54. data/lib/gooddata/lcm/types/class/smart_hash.rb +23 -0
  55. data/lib/gooddata/lcm/types/complex/segment.rb +1 -1
  56. data/lib/gooddata/lcm/types/scalar/integer.rb +2 -2
  57. data/lib/gooddata/lcm/types/special/any.rb +18 -0
  58. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +1 -1
  59. data/lib/gooddata/models/blueprint/to_manifest.rb +1 -3
  60. data/lib/gooddata/models/blueprint/to_wire.rb +2 -1
  61. data/lib/gooddata/models/from_wire.rb +13 -1
  62. data/lib/gooddata/models/metadata/folder.rb +22 -0
  63. data/lib/gooddata/models/metadata/metric.rb +5 -8
  64. data/lib/gooddata/models/model.rb +1 -1
  65. data/lib/gooddata/models/process.rb +42 -32
  66. data/lib/gooddata/models/project.rb +19 -36
  67. data/lib/gooddata/models/project_creator.rb +3 -1
  68. data/lib/gooddata/models/project_role.rb +3 -4
  69. data/lib/gooddata/models/schedule.rb +0 -2
  70. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +9 -1
  71. data/lib/gooddata/models/user_filters/user_filter.rb +1 -2
  72. data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -6
  73. data/lib/gooddata/rest/client.rb +1 -2
  74. data/lib/gooddata/rest/connection.rb +12 -46
  75. data/lib/gooddata/rest/phmap.rb +101 -56
  76. data/lib/gooddata/version.rb +1 -1
  77. data/rubydev_public.gpg.encrypted +51 -0
  78. data/rubydev_secret_keys.gpg.encrypted +109 -0
  79. data/spec/data/user_filters.csv +2 -0
  80. data/spec/environment/default.rb +2 -2
  81. data/spec/environment/development.rb +1 -1
  82. data/spec/environment/staging.rb +2 -3
  83. data/spec/environment/testing.rb +4 -4
  84. data/spec/integration/connection_spec.rb +37 -0
  85. data/spec/integration/core/connection_spec.rb +1 -1
  86. data/spec/integration/core/logging_spec.rb +8 -6
  87. data/spec/integration/core/project_spec.rb +1 -1
  88. data/spec/integration/mandatory_user_filter_spec.rb +53 -0
  89. data/spec/integration/mixins/id_to_uri_spec.rb +17 -5
  90. data/spec/integration/models/label_spec.rb +9 -0
  91. data/spec/integration/models/metric_spec.rb +24 -0
  92. data/spec/integration/models/process_spec.rb +35 -0
  93. data/spec/integration/models/project_role_spec.rb +1 -1
  94. data/spec/integration/models/schedule_spec.rb +0 -8
  95. data/spec/integration/schedule_spec.rb +4 -6
  96. data/spec/integration/user_filters_spec.rb +20 -16
  97. data/spec/integration/user_group_spec.rb +1 -1
  98. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/can_assign_a_custom_logger.yml +2287 -0
  99. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/client_logs_when_given_custom_message.yml +2287 -0
  100. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/has_the_request_id_logged_when_I_passed_it.yml +2287 -0
  101. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_off/Disables_logging.yml +2287 -0
  102. data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_on/Enables_logging.yml +2287 -0
  103. data/spec/integration/vcr_cassettes/GoodData_-_project/_project/Returns_project_assigned.yml +354 -0
  104. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_nil.yml +299 -0
  105. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_directly.yml +354 -0
  106. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_ID.yml +354 -0
  107. data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_URL.yml +354 -0
  108. data/spec/integration/vcr_cassettes/GoodData_-_project/_with_project/Uses_project_specified.yml +354 -0
  109. data/spec/integration/vcr_cassettes/GoodData_Metric/all.yml +2065 -0
  110. data/spec/integration/vcr_cassettes/GoodData_Metric/should_be_able_to_update_folders.yml +119 -0
  111. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/all.yml +9812 -0
  112. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_get_json_containing_correct_id.yml +174 -0
  113. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_return_nil_for_unknown_id.yml +58 -0
  114. data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_throw_BadRequest_for_-1.yml +63 -0
  115. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_connect/Connects_using_username_and_password.yml +299 -0
  116. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_disconnect/Connects_using_username_and_password.yml +299 -0
  117. data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_generate_request_id/Generates_a_non-empty_string.yml +2287 -0
  118. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_/Should_list_user_groups_as_Array.yml +56 -0
  119. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_add_members/Should_add_member.yml +315 -0
  120. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_members/Should_return_members_as_array.yml +54 -0
  121. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_remove_members/Should_remove_existing_members.yml +258 -0
  122. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_save/updates_existing_group.yml +159 -0
  123. data/spec/integration/vcr_cassettes/GoodData_UserGroup/_set_members/Should_set_new_members.yml +158 -0
  124. data/spec/integration/vcr_cassettes/GoodData_UserGroup/all.yml +809 -0
  125. data/spec/spec_helper.rb +46 -2
  126. data/spec/unit/actions/associate_clients_spec.rb +2 -1
  127. data/spec/unit/actions/collect_data_product_spec.rb +3 -1
  128. data/spec/unit/actions/collect_segment_clients_spec.rb +1 -0
  129. data/spec/unit/actions/create_segment_masters_spec.rb +1 -0
  130. data/spec/unit/actions/ensure_data_product_spec.rb +1 -0
  131. data/spec/unit/actions/ensure_technical_users_domain_spec.rb +2 -0
  132. data/spec/unit/actions/ensure_technical_users_project_spec.rb +4 -0
  133. data/spec/unit/actions/provision_clients_spec.rb +2 -1
  134. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +0 -6
  135. data/spec/unit/actions/synchronize_ldm_spec.rb +20 -7
  136. data/spec/unit/actions/synchronize_user_filters_spec.rb +21 -0
  137. data/spec/unit/helpers/check_helper_production_spec.rb +34 -0
  138. data/spec/unit/helpers/check_helper_spec.rb +97 -9
  139. data/spec/unit/lcm/lcm2_spec.rb +67 -3
  140. data/spec/unit/models/blueprint/to_wire_spec.rb +1 -0
  141. data/spec/unit/models/dataset_blueprint.rb +14 -0
  142. data/spec/unit/models/from_wire_spec.rb +20 -0
  143. data/spec/unit/models/model_spec.rb +10 -0
  144. data/spec/unit/models/to_manifest_spec.rb +29 -0
  145. data/spec/unit/models/user_filters/user_filter_builder_spec.rb +44 -6
  146. data/spec/unit/rest/phmap_spec.rb +117 -0
  147. data/spec/vcr_configurer.rb +63 -0
  148. metadata +283 -24
  149. data/lib/gooddata/lcm/actions/ensure_segments.rb +0 -32
@@ -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
- key = name.to_s.downcase.to_sym
18
+ data(name)
19
+ end
18
20
 
19
- value = nil
20
- keys.each do |k|
21
- if k.to_s.downcase.to_sym == key
22
- value = self[k]
23
- break
24
- end
25
- end
21
+ def [](variable)
22
+ data(variable)
23
+ end
26
24
 
27
- if value
28
- value
29
- else
30
- begin
31
- super
32
- rescue
33
- nil
34
- end
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
- GoodData.logger.info("Running #{action.name} action ...")
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: true # required: false, , default: 'pg'
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
@@ -13,8 +13,8 @@ module GoodData
13
13
  CATEGORY = :scalar
14
14
  INTERNAL_TYPE = Integer
15
15
 
16
- def check(_value)
17
- true
16
+ def check(value)
17
+ value.is_number?
18
18
  end
19
19
  end
20
20
  end
@@ -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['fact']['identifier'] =~ /^dt\./ ? :date_fact : :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 = { :client => GoodData.client, :project => GoodData.project })
94
- return deploy_brick(path, options) if path.to_s.start_with?(APP_STORE_URL)
95
-
96
- return deploy_from_appstore(path.to_s, options) if (path.to_s =~ %r{\${.*}:(.*)\/(.*):\/}) == 0 # rubocop:disable Style/NumericPredicate
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
- res = if process_id.nil?
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
- process = client.create(Process, res, project: project)
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