gooddata 0.6.51 → 0.6.52

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +13 -1
  4. data/CONTRIBUTING.md +25 -0
  5. data/PULL_REQUEST_TEMPLATE.md +5 -0
  6. data/README.md +7 -4
  7. data/gooddata.gemspec +2 -3
  8. data/lib/gooddata.rb +1 -0
  9. data/lib/gooddata/bricks/base_downloader.rb +6 -6
  10. data/lib/gooddata/bricks/middleware/aws_middleware.rb +15 -5
  11. data/lib/gooddata/bricks/middleware/dwh_middleware.rb +15 -3
  12. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +13 -4
  13. data/lib/gooddata/bricks/middleware/logger_middleware.rb +3 -0
  14. data/lib/gooddata/exceptions/no_project_error.rb +5 -1
  15. data/lib/gooddata/goodzilla/goodzilla.rb +7 -6
  16. data/lib/gooddata/helpers/data_helper.rb +4 -4
  17. data/lib/gooddata/helpers/global_helpers_params.rb +61 -39
  18. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +9 -0
  19. data/lib/gooddata/lcm/actions/associate_clients.rb +23 -4
  20. data/lib/gooddata/lcm/actions/collect_attrs.rb +56 -0
  21. data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +53 -0
  22. data/lib/gooddata/lcm/actions/collect_clients.rb +25 -3
  23. data/lib/gooddata/lcm/actions/collect_meta.rb +83 -0
  24. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +12 -4
  25. data/lib/gooddata/lcm/actions/collect_segments.rb +4 -4
  26. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +74 -0
  27. data/lib/gooddata/lcm/actions/create_segment_masters.rb +16 -30
  28. data/lib/gooddata/lcm/actions/ensure_release_table.rb +0 -3
  29. data/lib/gooddata/lcm/actions/ensure_segments.rb +1 -4
  30. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -5
  31. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +8 -5
  32. data/lib/gooddata/lcm/actions/hello_world.rb +0 -3
  33. data/lib/gooddata/lcm/actions/import_object_collections.rb +60 -0
  34. data/lib/gooddata/lcm/actions/print_actions.rb +0 -3
  35. data/lib/gooddata/lcm/actions/print_modes.rb +0 -3
  36. data/lib/gooddata/lcm/actions/print_types.rb +1 -4
  37. data/lib/gooddata/lcm/actions/provision_clients.rb +5 -5
  38. data/lib/gooddata/lcm/actions/purge_clients.rb +4 -10
  39. data/lib/gooddata/lcm/actions/segments_filter.rb +0 -6
  40. data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +8 -4
  41. data/lib/gooddata/lcm/actions/synchronize_cas.rb +61 -0
  42. data/lib/gooddata/lcm/actions/synchronize_clients.rb +9 -3
  43. data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +13 -5
  44. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +71 -17
  45. data/lib/gooddata/lcm/actions/synchronize_label_types.rb +8 -5
  46. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +17 -8
  47. data/lib/gooddata/lcm/actions/synchronize_meta.rb +0 -3
  48. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +9 -4
  49. data/lib/gooddata/lcm/actions/synchronize_processes.rb +9 -5
  50. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +15 -5
  51. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +61 -0
  52. data/lib/gooddata/lcm/actions/update_release_table.rb +0 -3
  53. data/lib/gooddata/lcm/helpers/tags_helper.rb +35 -0
  54. data/lib/gooddata/lcm/lcm.rb +22 -4
  55. data/lib/gooddata/lcm/lcm2.rb +66 -13
  56. data/lib/gooddata/lcm/types/complex/update_preference.rb +1 -1
  57. data/lib/gooddata/mixins/md_finders.rb +4 -2
  58. data/lib/gooddata/mixins/md_object_indexer.rb +13 -3
  59. data/lib/gooddata/mixins/md_object_query.rb +8 -2
  60. data/lib/gooddata/models/blueprint/date_dimension.rb +6 -0
  61. data/lib/gooddata/models/blueprint/project_blueprint.rb +41 -11
  62. data/lib/gooddata/models/blueprint/project_builder.rb +20 -0
  63. data/lib/gooddata/models/blueprint/to_wire.rb +7 -0
  64. data/lib/gooddata/models/client.rb +6 -0
  65. data/lib/gooddata/models/domain.rb +6 -6
  66. data/lib/gooddata/models/from_wire.rb +5 -1
  67. data/lib/gooddata/models/metadata.rb +55 -9
  68. data/lib/gooddata/models/metadata/attribute.rb +19 -4
  69. data/lib/gooddata/models/metadata/dashboard.rb +15 -3
  70. data/lib/gooddata/models/metadata/dataset.rb +5 -2
  71. data/lib/gooddata/models/metadata/dimension.rb +4 -1
  72. data/lib/gooddata/models/metadata/fact.rb +9 -2
  73. data/lib/gooddata/models/metadata/folder.rb +4 -1
  74. data/lib/gooddata/models/metadata/metric.rb +11 -3
  75. data/lib/gooddata/models/metadata/report.rb +7 -2
  76. data/lib/gooddata/models/metadata/report_definition.rb +11 -4
  77. data/lib/gooddata/models/metadata/scheduled_mail.rb +4 -1
  78. data/lib/gooddata/models/metadata/variable.rb +7 -2
  79. data/lib/gooddata/models/model.rb +14 -3
  80. data/lib/gooddata/models/process.rb +10 -9
  81. data/lib/gooddata/models/project.rb +134 -36
  82. data/lib/gooddata/models/project_creator.rb +43 -20
  83. data/lib/gooddata/models/report_data_result.rb +6 -2
  84. data/lib/gooddata/models/schedule.rb +6 -3
  85. data/lib/gooddata/models/subscription.rb +8 -1
  86. data/lib/gooddata/models/user_filters/user_filter.rb +1 -0
  87. data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -4
  88. data/lib/gooddata/models/user_filters/variable_user_filter.rb +3 -1
  89. data/lib/gooddata/rest/client.rb +4 -6
  90. data/lib/gooddata/rest/connection.rb +10 -2
  91. data/lib/gooddata/version.rb +1 -1
  92. data/spec/data/blueprints/test_blueprint.json +1 -0
  93. data/spec/data/wire_models/test_blueprint.json +3 -0
  94. data/spec/data/workspace_table.csv +3 -0
  95. data/spec/environment/development.rb +4 -1
  96. data/spec/environment/environment.rb +1 -1
  97. data/spec/environment/staging.rb +5 -1
  98. data/spec/environment/testing.rb +5 -2
  99. data/spec/integration/blueprint_with_ca_spec.rb +56 -0
  100. data/spec/integration/clients_spec.rb +21 -0
  101. data/spec/integration/command_datawarehouse_spec.rb +7 -1
  102. data/spec/integration/create_from_template_spec.rb +9 -3
  103. data/spec/integration/project_spec.rb +7 -0
  104. data/spec/integration/segments_spec.rb +0 -53
  105. data/spec/integration/subscription_spec.rb +29 -4
  106. data/spec/integration/urn_date_dim_spec.rb +53 -0
  107. data/spec/integration/user_filters_spec.rb +6 -0
  108. data/spec/integration/variables_spec.rb +1 -2
  109. data/spec/spec_helper.rb +5 -30
  110. data/spec/unit/actions/collect_clients_spec.rb +38 -0
  111. data/spec/unit/actions/collect_meta_spec.rb +87 -0
  112. data/spec/unit/actions/collect_segment_clients_spec.rb +40 -0
  113. data/spec/unit/actions/collect_tagged_objects_spec.rb +110 -0
  114. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +51 -0
  115. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +55 -1
  116. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
  117. data/spec/unit/helpers/data_helper_spec.rb +3 -5
  118. data/spec/unit/helpers/global_helpers_spec.rb +29 -0
  119. data/spec/unit/helpers_spec.rb +18 -1
  120. data/spec/unit/models/blueprint/project_blueprint_spec.rb +1 -23
  121. data/spec/unit/models/domain_spec.rb +19 -0
  122. data/spec/unit/models/metadata_spec.rb +34 -0
  123. data/spec/unit/models/schedule_spec.rb +31 -0
  124. data/spec/unit/models/to_manifest_spec.rb +10 -2
  125. data/spec/unit/models/unit_project_spec.rb +6 -1
  126. data/spec/unit/rest/polling_spec.rb +13 -1
  127. metadata +49 -31
@@ -15,29 +15,29 @@ module GoodData
15
15
  description 'Client Used for Connecting to GD'
16
16
  param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
17
 
18
+ description 'Development Client Used for Connecting to GD'
19
+ param :development_client, instance_of(Type::GdClientType), required: true
20
+
18
21
  description 'Organization Name'
19
22
  param :organization, instance_of(Type::StringType), required: true
20
23
 
21
24
  description 'ADS Client'
22
25
  param :ads_client, instance_of(Type::AdsClientType), required: true
23
26
 
24
- # description 'Queries Used'
25
- # param :query, instance_of(Type::ReleaseQueryType), required: false
26
-
27
27
  description 'Segments to manage'
28
28
  param :segments, array_of(instance_of(Type::SegmentType)), required: true
29
29
 
30
30
  description 'Tokens'
31
31
  param :tokens, instance_of(Type::TokensType), required: true
32
+
33
+ description 'Table Name'
34
+ param :release_table_name, instance_of(Type::StringType), required: false
32
35
  end
33
36
 
34
37
  DEFAULT_TABLE_NAME = 'LCM_RELEASE'
35
38
 
36
39
  class << self
37
40
  def call(params)
38
- # Check if all required parameters were passed
39
- BaseAction.check_params(PARAMS, params)
40
-
41
41
  results = []
42
42
 
43
43
  client = params.gdc_gd_client
@@ -50,10 +50,7 @@ module GoodData
50
50
  # TODO: Support for 'per segment' provisioning
51
51
  segments = params.segments
52
52
 
53
- # Output param with info about which projects should be synchronized
54
- synchronize_projects = []
55
-
56
- segments.map do |segment_in| # rubocop:disable Metrics/BlockLength
53
+ synchronize_projects = segments.map do |segment_in| # rubocop:disable Metrics/BlockLength
57
54
  segment_id = segment_in.segment_id
58
55
  development_pid = segment_in.development_pid
59
56
  driver = segment_in.driver.downcase
@@ -75,32 +72,16 @@ module GoodData
75
72
  params.gdc_logger.info "Creating master project - name: '#{master_name}' development_project: '#{development_pid}', segment: '#{segment_id}', driver: '#{driver}'"
76
73
  project = client.create_project(title: master_name, auth_token: token, driver: driver == 'vertica' ? 'vertica' : 'Pg')
77
74
 
78
- # Do we have hash with synchronization info for current development project?
79
- synchronize_info = synchronize_projects.find do |info|
80
- info[:from] == development_pid
81
- end
82
-
83
- # If not, create new one
84
- unless synchronize_info
85
- synchronize_info = {
86
- segment: segment_id,
87
- from: development_pid,
88
- to: []
89
- }
90
- synchronize_projects << synchronize_info
91
- end
92
-
93
- # Add target project (new master for segment) into synchronization info
94
- synchronize_info[:to] << { pid: project.pid }
95
-
96
75
  # Does segment exists? If not, create new one and set initial master
97
76
  if segment
98
77
  segment_in[:is_new] = false
78
+ status = 'untouched'
99
79
  else
100
80
  params.gdc_logger.info "Creating segment #{segment_id}, master #{project.pid}"
101
81
  segment = domain.create_segment(segment_id: segment_id, master_project: project)
102
82
  segment.synchronize_clients
103
83
  segment_in[:is_new] = true
84
+ status = 'created'
104
85
  end
105
86
 
106
87
  master_project = nil
@@ -115,6 +96,7 @@ module GoodData
115
96
  segment.master_project = project
116
97
  segment.save
117
98
  segment_in[:is_new] = true
99
+ status = 'modified'
118
100
  end
119
101
 
120
102
  segment_in[:master_pid] = project.pid
@@ -131,10 +113,14 @@ module GoodData
131
113
  development_pid: development_pid,
132
114
  master_pid: project.pid,
133
115
  driver: driver,
134
- status: 'created'
116
+ status: status
135
117
  }
136
118
 
137
- project
119
+ {
120
+ segment: segment_id,
121
+ from: development_pid,
122
+ to: [{ pid: project.pid }]
123
+ }
138
124
  end
139
125
 
140
126
  # Return results
@@ -28,9 +28,6 @@ module GoodData
28
28
 
29
29
  class << self
30
30
  def call(params)
31
- # Check if all required parameters were passed
32
- BaseAction.check_params(PARAMS, params)
33
-
34
31
  replacements = {
35
32
  table_name: params.release_table_name || DEFAULT_TABLE_NAME
36
33
  }
@@ -20,10 +20,7 @@ module GoodData
20
20
  end
21
21
 
22
22
  class << self
23
- def call(params)
24
- # Check if all required parameters were passed
25
- BaseAction.check_params(PARAMS, params)
26
-
23
+ def call(_params)
27
24
  results = []
28
25
 
29
26
  # Return results
@@ -17,6 +17,9 @@ module GoodData
17
17
 
18
18
  description 'Organization Name'
19
19
  param :organization, instance_of(Type::StringType), required: true
20
+
21
+ description 'Technical users'
22
+ param :technical_user, array_of(instance_of(Type::StringType)), required: false
20
23
  end
21
24
 
22
25
  RESULT_HEADER = [
@@ -28,16 +31,13 @@ module GoodData
28
31
 
29
32
  class << self
30
33
  def call(params)
31
- # Check if all required parameters were passed
32
- BaseAction.check_params(PARAMS, params)
33
-
34
34
  client = params.gdc_gd_client
35
35
 
36
36
  domain_name = params.organization || params.domain
37
37
  domain = client.domain(domain_name) || fail("Invalid domain name specified - #{domain_name}")
38
38
 
39
- technical_users = params.technical_user || []
40
- technical_users.map do |technical_user|
39
+ technical_users = (params.technical_user || []).uniq
40
+ technical_users.pmap do |technical_user|
41
41
  domain_user = domain.users.find do |du|
42
42
  du.login == technical_user
43
43
  end
@@ -14,6 +14,12 @@ module GoodData
14
14
  PARAMS = define_params(self) do
15
15
  description 'Client Used for Connecting to GD'
16
16
  param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
+
18
+ description 'Technical users'
19
+ param :technical_user, array_of(instance_of(Type::StringType)), required: false
20
+
21
+ description 'Synchronization Info'
22
+ param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true
17
23
  end
18
24
 
19
25
  RESULT_HEADER = [
@@ -28,9 +34,6 @@ module GoodData
28
34
 
29
35
  class << self
30
36
  def call(params)
31
- # Check if all required parameters were passed
32
- BaseAction.check_params(PARAMS, params)
33
-
34
37
  client = params.gdc_gd_client
35
38
 
36
39
  technical_users = params.technical_user || []
@@ -41,8 +44,8 @@ module GoodData
41
44
  }
42
45
  end
43
46
 
44
- results = params.synchronize.map do |synchronize_info|
45
- synchronize_info[:to].map do |entry|
47
+ results = params.synchronize.pmap do |synchronize_info|
48
+ synchronize_info[:to].pmap do |entry|
46
49
  project = client.projects(entry[:pid])
47
50
  res = project.create_users(new_users)
48
51
 
@@ -25,9 +25,6 @@ module GoodData
25
25
  end
26
26
 
27
27
  def call(params)
28
- # Check if all required parameters were passed
29
- BaseAction.check_params(PARAMS, params)
30
-
31
28
  say(params.message)
32
29
 
33
30
  msg = {
@@ -0,0 +1,60 @@
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_action'
8
+
9
+ module GoodData
10
+ module LCM2
11
+ class ImportObjectCollections < BaseAction
12
+ DESCRIPTION = 'Import all objects in CollectXXX action to master projects'
13
+
14
+ PARAMS = define_params(self) do
15
+ description 'Client Used for Connecting to GD'
16
+ param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
+
18
+ description 'Development Client Used for Connecting to GD'
19
+ param :development_client, instance_of(Type::GdClientType), required: true
20
+
21
+ description 'Synchronization Info'
22
+ param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true
23
+ end
24
+
25
+ class << self
26
+ def call(params)
27
+ results = []
28
+
29
+ client = params.gdc_gd_client
30
+ development_client = params.development_client
31
+
32
+ params.synchronize.peach do |info|
33
+ from = info.from
34
+ to_projects = info.to
35
+ transfer_uris = info.transfer_uris
36
+
37
+ from_project = development_client.projects(from) || fail("Invalid 'from' project specified - '#{from}'")
38
+
39
+ to_projects.peach do |entry|
40
+ pid = entry[:pid]
41
+ to_project = client.projects(pid) || fail("Invalid 'to' project specified - '#{pid}'")
42
+
43
+ if transfer_uris.any?
44
+ from_project.partial_md_export(transfer_uris, project: to_project)
45
+ end
46
+
47
+ results << {
48
+ from: from,
49
+ to: pid,
50
+ status: 'ok'
51
+ }
52
+ end
53
+ end
54
+
55
+ results
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -16,9 +16,6 @@ module GoodData
16
16
 
17
17
  class << self
18
18
  def call(params)
19
- # Check if all required parameters were passed
20
- BaseAction.check_params(PARAMS, params)
21
-
22
19
  results = []
23
20
 
24
21
  actions = GoodData::LCM2::BaseAction.descendants
@@ -16,9 +16,6 @@ module GoodData
16
16
 
17
17
  class << self
18
18
  def call(params)
19
- # Check if all required parameters were passed
20
- BaseAction.check_params(PARAMS, params)
21
-
22
19
  results = []
23
20
  GoodData::LCM2::MODES.keys.each_with_index do |mode, index|
24
21
  actions = GoodData::LCM2::MODES[mode]
@@ -15,10 +15,7 @@ module GoodData
15
15
  }
16
16
 
17
17
  class << self
18
- def call(params)
19
- # Check if all required parameters were passed
20
- BaseAction.check_params(PARAMS, params)
21
-
18
+ def call(_params)
22
19
  results = []
23
20
 
24
21
  GoodData::LCM2::Dsl::Dsl::TYPES.each_pair do |k, v|
@@ -32,17 +32,14 @@ module GoodData
32
32
 
33
33
  class << self
34
34
  def call(params)
35
- # Check if all required parameters were passed
36
- BaseAction.check_params(PARAMS, params)
37
-
38
35
  client = params.gdc_gd_client
39
36
 
40
37
  domain_name = params.organization || params.domain
41
38
  domain = client.domain(domain_name) || fail("Invalid domain name specified - #{domain_name}")
42
39
 
43
40
  synchronize_projects = []
44
- results = params.segments.map do |segment|
45
- tmp = domain.provision_client_projects(segment.segment_id).map do |m|
41
+ results = params.segments.pmap do |segment|
42
+ tmp = domain.provision_client_projects(segment.segment_id).pmap do |m|
46
43
  Hash[m.each_pair.to_a].merge(type: :provision_result)
47
44
  end
48
45
 
@@ -51,6 +48,9 @@ module GoodData
51
48
  segment_id: segment.segment_id,
52
49
  from: segment.development_pid,
53
50
  to: tmp.map do |entry|
51
+ unless entry[:project_uri]
52
+ raise "Provisioning project for client id #{entry[:id]} has error: #{entry[:error]}"
53
+ end
54
54
  {
55
55
  pid: entry[:project_uri].split('/').last,
56
56
  client_id: entry[:id]
@@ -12,17 +12,14 @@ module GoodData
12
12
  DESCRIPTION = 'Purge LCM Clients'
13
13
 
14
14
  PARAMS = define_params(self) do
15
+ description 'Client Used for Connecting to GD'
16
+ param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
+
15
18
  description 'Organization Name'
16
19
  param :organization, instance_of(Type::StringType), required: true
17
20
 
18
21
  description 'Segments to manage'
19
22
  param :segments, array_of(instance_of(Type::SegmentType)), required: true
20
-
21
- description 'Delete Extra Clients'
22
- param :delete_extra, instance_of(Type::BooleanType), required: false, default: false
23
-
24
- description 'Physically Delete Client Projects'
25
- param :delete_projects, instance_of(Type::BooleanType), required: false, default: false
26
23
  end
27
24
 
28
25
  RESULT_HEADER = [
@@ -33,9 +30,6 @@ module GoodData
33
30
 
34
31
  class << self
35
32
  def call(params)
36
- # Check if all required parameters were passed
37
- BaseAction.check_params(PARAMS, params)
38
-
39
33
  client = params.gdc_gd_client
40
34
 
41
35
  domain_name = params.organization || params.domain
@@ -50,7 +44,7 @@ module GoodData
50
44
  segment_names.include?(segment.segment_id.downcase)
51
45
  end
52
46
 
53
- results = segments.map do |segment|
47
+ results = segments.pmap do |segment|
54
48
  segment.clients.map do |segment_client|
55
49
  project = segment_client.project
56
50
  res = {
@@ -12,9 +12,6 @@ module GoodData
12
12
  DESCRIPTION = 'Filter Segments'
13
13
 
14
14
  PARAMS = define_params(self) do
15
- description 'Client Used for Connecting to GD'
16
- param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
-
18
15
  description 'Segments to manage'
19
16
  param :segments, array_of(instance_of(Type::SegmentType)), required: true
20
17
 
@@ -24,9 +21,6 @@ module GoodData
24
21
 
25
22
  class << self
26
23
  def call(params)
27
- # Check if all required parameters were passed
28
- BaseAction.check_params(PARAMS, params)
29
-
30
24
  filtered_segments = params.segments
31
25
  if params.segments_filter
32
26
  segments_filter = params.segments_filter.map(&:downcase)
@@ -14,6 +14,12 @@ module GoodData
14
14
  PARAMS = define_params(self) do
15
15
  description 'Client Used for Connecting to GD'
16
16
  param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
+
18
+ description 'Development Client Used for Connecting to GD'
19
+ param :development_client, instance_of(Type::GdClientType), required: true
20
+
21
+ description 'Synchronization Info'
22
+ param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true
17
23
  end
18
24
 
19
25
  RESULT_HEADER = [
@@ -24,19 +30,17 @@ module GoodData
24
30
 
25
31
  class << self
26
32
  def call(params)
27
- BaseAction.check_params(PARAMS, params)
28
-
29
33
  results = []
30
34
 
31
35
  client = params.gdc_gd_client
32
36
  development_client = params.development_client
33
37
 
34
- params.synchronize.each do |info|
38
+ params.synchronize.peach do |info|
35
39
  from = info.from
36
40
  to = info.to
37
41
 
38
42
  from_project = development_client.projects(from) || fail("Invalid 'from' project specified - '#{from}'")
39
- to_projects = to.map do |entry|
43
+ to_projects = to.pmap do |entry|
40
44
  pid = entry[:pid]
41
45
  client.projects(pid) || fail("Invalid 'to' project specified - '#{pid}'")
42
46
  end
@@ -0,0 +1,61 @@
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_action'
8
+
9
+ module GoodData
10
+ module LCM2
11
+ class SynchronizeComputedAttributes < BaseAction
12
+ DESCRIPTION = 'Synchronize Computed Attributes'
13
+
14
+ PARAMS = define_params(self) do
15
+ description 'Client Used for Connecting to GD'
16
+ param :gdc_gd_client, instance_of(Type::GdClientType), required: true
17
+
18
+ description 'Synchronization Info'
19
+ param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true
20
+ end
21
+
22
+ class << self
23
+ def call(params)
24
+ results = []
25
+ client = params.gdc_gd_client
26
+
27
+ params.synchronize.each do |info|
28
+ from = info.from
29
+ to_projects = info.to
30
+
31
+ params.gdc_logger.info "Synchronize Computed Attributes from project pid: #{from}"
32
+
33
+ to_projects.peach do |entry|
34
+ ca_scripts = entry[:ca_scripts]
35
+ next unless ca_scripts
36
+
37
+ pid = entry[:pid]
38
+ ca_chunks = ca_scripts['maqlDdlChunks']
39
+ to_project = client.projects(pid) || fail("Invalid 'to' project specified - '#{pid}'")
40
+ params.gdc_logger.info "Synchronizing Computed Attributes to project: '#{to_project.title}', PID: #{pid}"
41
+
42
+ begin
43
+ ca_chunks.each { |chunk| to_project.execute_maql(chunk) }
44
+ rescue => e
45
+ raise "Error occured when executing MAQL, project: \"#{to_project.title}\" reason: \"#{e.message}\", chunks: #{ca_chunks.inspect}"
46
+ end
47
+
48
+ results << {
49
+ from: from,
50
+ to: pid,
51
+ status: 'ok'
52
+ }
53
+ end
54
+ end
55
+
56
+ results
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end