gooddata 0.6.51 → 0.6.52

Sign up to get free protection for your applications and to get access to all the features.
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