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.
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