gooddata 1.3.6-java → 2.0.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +54 -36
  4. data/CHANGELOG.md +37 -1
  5. data/CONTRIBUTING.md +4 -0
  6. data/Gemfile +9 -0
  7. data/Jenkinsfile-chart +14 -0
  8. data/RELEASING.md +5 -8
  9. data/Rakefile +1 -1
  10. data/SDK_VERSION +1 -1
  11. data/bin/run_brick.rb +1 -1
  12. data/bin/test_projects_cleanup.rb +20 -8
  13. data/ci.rake +2 -2
  14. data/k8s/charts/lcm-bricks/Chart.yaml +4 -0
  15. data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +96 -0
  16. data/lcm.rake +1 -1
  17. data/lib/gooddata/bricks/middleware/context_logger_decorator.rb +31 -0
  18. data/lib/gooddata/bricks/middleware/context_manager.rb +68 -0
  19. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +15 -9
  20. data/lib/gooddata/bricks/middleware/logger_middleware.rb +20 -0
  21. data/lib/gooddata/bricks/middleware/mask_logger_decorator.rb +35 -5
  22. data/lib/gooddata/client.rb +2 -3
  23. data/lib/gooddata/core/gd_logger.rb +92 -0
  24. data/lib/gooddata/core/logging.rb +24 -7
  25. data/lib/gooddata/core/nil_logger.rb +1 -2
  26. data/lib/gooddata/core/splunk_logger.rb +23 -0
  27. data/lib/gooddata/lcm/actions/synchronize_users.rb +2 -1
  28. data/lib/gooddata/lcm/helpers/check_helper.rb +3 -15
  29. data/lib/gooddata/lcm/helpers/safe_failure_helper.rb +19 -0
  30. data/lib/gooddata/lcm/lcm2.rb +21 -10
  31. data/lib/gooddata/mixins/property_accessor.rb +30 -0
  32. data/lib/gooddata/models/execution.rb +5 -0
  33. data/lib/gooddata/models/project.rb +6 -4
  34. data/lib/gooddata/rest/client.rb +17 -6
  35. data/lib/gooddata/rest/connection.rb +20 -6
  36. data/lib/gooddata/rest/rest_aggregator.rb +46 -0
  37. metadata +12 -2
@@ -187,7 +187,8 @@ module GoodData
187
187
  ignore_failures: ignore_failures,
188
188
  remove_users_from_project: remove_users_from_project,
189
189
  do_not_touch_users_that_are_not_mentioned: do_not_touch_users_that_are_not_mentioned,
190
- create_non_existing_user_groups: create_non_existing_user_groups
190
+ create_non_existing_user_groups: create_non_existing_user_groups,
191
+ user_groups_cache: nil
191
192
  }
192
193
  results = case mode
193
194
  when 'add_to_organization'
@@ -22,19 +22,11 @@ module GoodData
22
22
  GoodData.logger.warn "WARNING: Default value for parameter '#{param_name}' was not filled because deprecated parameter is used instead."
23
23
  end
24
24
  elsif specification[param_name][:opts][:required]
25
- if ENV['RSPEC_ENV'] == 'test'
26
- fail "Mandatory parameter '#{param_name}' of type '#{type}' is not specified"
27
- else
28
- GoodData.logger.error("Mandatory parameter '#{param_name}' of type '#{type}' is not specified")
29
- end
25
+ fail_if_development "Mandatory parameter '#{param_name}' of type '#{type}' is not specified"
30
26
  end
31
27
  else
32
28
  if type.class.const_get(:CATEGORY) == :complex && !value.is_a?(Hash)
33
- if ENV['RSPEC_ENV'] == 'test'
34
- fail "Expected parameter '#{param_name}' to be kind of '#{type}', got '#{value.class.name}'"
35
- else
36
- GoodData.logger.error("Expected parameter '#{param_name}' to be kind of '#{type}', got '#{value.class.name}'")
37
- end
29
+ fail_if_development "Expected parameter '#{param_name}' to be kind of '#{type}', got '#{value.class.name}'"
38
30
  end
39
31
 
40
32
  if specification[param_name][:opts][:deprecated]
@@ -42,11 +34,7 @@ module GoodData
42
34
  end
43
35
 
44
36
  unless type.check(value)
45
- if ENV['RSPEC_ENV'] == 'test'
46
- fail "Parameter '#{param_name}' has invalid type, expected: #{type}, got #{value.class}"
47
- else
48
- GoodData.logger.error("Parameter '#{param_name}' has invalid type, expected: #{type}, got #{value.class}")
49
- end
37
+ fail_if_development "Parameter '#{param_name}' has invalid type, expected: #{type}, got #{value.class}"
50
38
  end
51
39
  end
52
40
  end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2010-2019 GoodData Corporation. All rights reserved.
2
+ # This source code is licensed under the BSD-style license found in the
3
+ # LICENSE file in the root directory of this source tree.
4
+
5
+ module GoodData
6
+ module LCM2
7
+ class Helpers
8
+ class << self
9
+ def fail_if_development(msg)
10
+ if ENV['RSPEC_ENV'] == 'test'
11
+ fail msg
12
+ else
13
+ GoodData.logger.error msg
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -268,6 +268,8 @@ module GoodData
268
268
  def perform(mode, params = {})
269
269
  params = convert_params(params)
270
270
 
271
+ GoodData.gd_logger.brick = mode
272
+
271
273
  # Get actions for mode specified
272
274
  actions = get_mode_actions(mode)
273
275
 
@@ -353,21 +355,30 @@ module GoodData
353
355
  success: errors.empty?
354
356
  }
355
357
 
356
- has_errors = errors.any?
357
- # Fail whole execution if there is any failed action
358
- fail(JSON.pretty_generate(errors)) if strict_mode && has_errors
358
+ if errors.any?
359
+ error_message = JSON.pretty_generate(errors)
360
+ GoodData.logger.error(error_message)
361
+
362
+ # Fail whole execution if there is any failed action
363
+ fail(error_message) if strict_mode
364
+ end
359
365
 
360
366
  result
361
367
  end
362
368
 
363
369
  def run_action(action, params)
364
- GoodData.logger.info("Running #{action.name} action ...")
365
- params.clear_filters
366
- # Check if all required parameters were passed
367
- BaseAction.check_params(action.const_get('PARAMS'), params)
368
- params.setup_filters(action.const_get('PARAMS'))
369
- out = action.send(:call, params)
370
- params.clear_filters
370
+ begin
371
+ GoodData.gd_logger.start_action action, GoodData.gd_logger
372
+ GoodData.logger.info("Running #{action.name} action ...")
373
+ params.clear_filters
374
+ # Check if all required parameters were passed
375
+ BaseAction.check_params(action.const_get('PARAMS'), params)
376
+ params.setup_filters(action.const_get('PARAMS'))
377
+ out = action.send(:call, params)
378
+ ensure
379
+ params.clear_filters
380
+ GoodData.gd_logger.end_action GoodData.gd_logger
381
+ end
371
382
  out
372
383
  end
373
384
 
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2010-2018 GoodData Corporation. All rights reserved.
2
+ # This source code is licensed under the BSD-style license found in the
3
+ # LICENSE file in the root directory of this source tree.
4
+
5
+ module GoodData
6
+ module Mixin
7
+ module PropertyAccessor
8
+ def property_reader(where, *props)
9
+ props.each do |prop|
10
+ define_method(prop, proc {
11
+ instance_variable_get(where)[prop]
12
+ })
13
+ end
14
+ end
15
+
16
+ def property_writer(where, *props)
17
+ props.each do |prop|
18
+ define_method("#{prop}=", proc { |val|
19
+ instance_variable_get(where)[prop] = val
20
+ })
21
+ end
22
+ end
23
+
24
+ def property_accessor(*args)
25
+ property_reader(*args)
26
+ property_writer(*args)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -92,7 +92,12 @@ module GoodData
92
92
  #
93
93
  # @return [GoodData::Execution] Execution result
94
94
  def wait_for_result(options = {})
95
+ start_time = Time.now
96
+ timeout = options[:timeout]
95
97
  res = client.poll_on_response(uri, options) do |body|
98
+ timeout_exceeded = timeout && (start_time + timeout) < Time.now
99
+ fail 'Waiting for schedule execution timed out.' if timeout_exceeded
100
+
96
101
  body['execution'] && (body['execution']['status'] == 'RUNNING' || body['execution']['status'] == 'SCHEDULED')
97
102
  end
98
103
  @json = res
@@ -1606,7 +1606,7 @@ module GoodData
1606
1606
  whitelisted_new_users, whitelisted_users = whitelist_users(new_users.map(&:to_hash), users_list, options[:whitelists])
1607
1607
 
1608
1608
  # First check that if groups are provided we have them set up
1609
- check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options)
1609
+ options[:user_groups_cache] = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)
1610
1610
 
1611
1611
  # conform the role on list of new users so we can diff them with the users coming from the project
1612
1612
  diffable_new_with_default_role = whitelisted_new_users.map do |u|
@@ -1706,7 +1706,7 @@ module GoodData
1706
1706
  user_groups(g).set_members(remote_users)
1707
1707
  end
1708
1708
  mentioned_groups = mappings.map(&:last).uniq
1709
- groups_to_cleanup = user_groups.reject { |g| mentioned_groups.include?(g.name) }
1709
+ groups_to_cleanup = options[:user_groups_cache].reject { |g| mentioned_groups.include?(g.name) }
1710
1710
  # clean all groups not mentioned with exception of whitelisted users
1711
1711
  groups_to_cleanup.each do |g|
1712
1712
  g.set_members(whitelist_users(g.members.map(&:to_hash), [], options[:whitelists], :include).first.map { |x| x[:uri] })
@@ -1744,8 +1744,9 @@ module GoodData
1744
1744
  end
1745
1745
  end
1746
1746
 
1747
- def check_groups(specified_groups, options = {})
1748
- groups = user_groups.map(&:name)
1747
+ def check_groups(specified_groups, user_groups_cache = nil, options = {})
1748
+ user_groups_cache = user_groups if user_groups_cache.nil? || user_groups_cache.empty?
1749
+ groups = user_groups_cache.map(&:name)
1749
1750
  missing_groups = specified_groups - groups
1750
1751
  if options[:create_non_existing_user_groups]
1751
1752
  missing_groups.each do |g|
@@ -1758,6 +1759,7 @@ module GoodData
1758
1759
  "#{groups.join(',')} and you asked for #{missing_groups.join(',')}"
1759
1760
  end
1760
1761
  end
1762
+ user_groups_cache
1761
1763
  end
1762
1764
 
1763
1765
  # Update user
@@ -67,6 +67,17 @@ module GoodData
67
67
  # @param password [String] Password to be used for authentication
68
68
  # @return [GoodData::Rest::Client] Client
69
69
  def connect(username, password = 'aaaa', opts = {})
70
+ execution_id = ""
71
+ if username.is_a?(Hash) && username.key?(:execution_id)
72
+ execution_id = username[:execution_id]
73
+ username.delete(:execution_id)
74
+ end
75
+
76
+ if opts.key?(:execution_id)
77
+ execution_id = opts[:execution_id]
78
+ opts.delete(:execution_id)
79
+ end
80
+
70
81
  if username.nil? && password.nil?
71
82
  username = ENV['GD_GEM_USER']
72
83
  password = ENV['GD_GEM_PASSWORD']
@@ -88,7 +99,7 @@ module GoodData
88
99
  new_opts[:password] = password
89
100
  end
90
101
 
91
- new_opts = { verify_ssl: true }.merge(new_opts)
102
+ new_opts = { verify_ssl: true, execution_id: execution_id }.merge(new_opts)
92
103
  if username.is_a?(Hash) && username[:cookies]
93
104
  new_opts[:sst_token] = username[:cookies]['GDCAuthSST']
94
105
  new_opts[:cookies] = username[:cookies]
@@ -195,7 +206,7 @@ module GoodData
195
206
  def disconnect
196
207
  if stats_on?
197
208
  GoodData.logger.info("API call statistics to server #{@connection.server}")
198
- GoodData.logger.info(@connection.stats_table)
209
+ GoodData.logger.info(@connection.stats_table.to_s)
199
210
  end
200
211
  @connection.disconnect
201
212
  end
@@ -256,14 +267,14 @@ module GoodData
256
267
  #
257
268
  # @param uri [String] Target URI
258
269
  def delete(uri, opts = {})
259
- @connection.delete uri, opts
270
+ @connection.delete uri, opts.merge(stats_on: stats_on?)
260
271
  end
261
272
 
262
273
  # HTTP GET
263
274
  #
264
275
  # @param uri [String] Target URI
265
276
  def get(uri, opts = {}, & block)
266
- @connection.get uri, opts, & block
277
+ @connection.get uri, opts.merge(stats_on: stats_on?), & block
267
278
  end
268
279
 
269
280
  def project_webdav_path(opts = { project: GoodData.project })
@@ -349,14 +360,14 @@ module GoodData
349
360
  #
350
361
  # @param uri [String] Target URI
351
362
  def put(uri, data, opts = {})
352
- @connection.put uri, data, opts
363
+ @connection.put uri, data, opts.merge(stats_on: stats_on?)
353
364
  end
354
365
 
355
366
  # HTTP POST
356
367
  #
357
368
  # @param uri [String] Target URI
358
369
  def post(uri, data, opts = {})
359
- @connection.post uri, data, opts
370
+ @connection.post uri, data, opts.merge(stats_on: stats_on?)
360
371
  end
361
372
 
362
373
  # Uploads file to staging
@@ -131,6 +131,7 @@ module GoodData
131
131
  def initialize(opts)
132
132
  super()
133
133
  @stats = ThreadSafe::Hash.new
134
+ @execution_id = opts[:execution_id]
134
135
 
135
136
  headers = opts[:headers] || {}
136
137
  @webdav_headers = DEFAULT_WEBDAV_HEADERS.merge(headers)
@@ -328,10 +329,12 @@ module GoodData
328
329
  def request(method, uri, data, options = {}, &user_block)
329
330
  request_id = options[:request_id] || generate_request_id
330
331
  log_info(options.merge(request_id: request_id))
332
+ stats_on = options[:stats_on]
333
+
331
334
  payload = data.is_a?(Hash) ? data.to_json : data
332
335
 
333
336
  GoodData.rest_logger.info "#{method.to_s.upcase}: #{@server.url}#{uri}, #{scrub_params(data, KEYS_TO_SCRUB)}"
334
- profile "#{method.to_s.upcase} #{uri}" do
337
+ profile method.to_s.upcase, uri, request_id, stats_on do
335
338
  b = proc do
336
339
  params = fresh_request_params(request_id).merge(options)
337
340
  begin
@@ -452,7 +455,7 @@ module GoodData
452
455
  end
453
456
 
454
457
  def generate_request_id
455
- "#{session_id}:#{call_id}"
458
+ "#{@execution_id}:#{session_id}:#{call_id}"
456
459
  end
457
460
 
458
461
  private
@@ -591,13 +594,13 @@ ERR
591
594
  raise $ERROR_INFO
592
595
  end
593
596
 
594
- def profile(title, &block)
597
+ def profile(method, path, request_id, stats_on, &block)
595
598
  t1 = Time.now
596
599
  res = block.call
597
600
  t2 = Time.now
598
601
  delta = t2 - t1
599
602
 
600
- update_stats title, delta
603
+ add_stat_record method, path, delta, t1, request_id if stats_on
601
604
  res
602
605
  end
603
606
 
@@ -617,9 +620,10 @@ ERR
617
620
  new_params
618
621
  end
619
622
 
620
- def update_stats(title, delta)
623
+ def add_stat_record(method, path, delta, time_stamp, request_id)
621
624
  synchronize do
622
- orig_title = title
625
+ orig_title = "#{method.to_s.upcase} #{path}"
626
+ title = "#{method.to_s.upcase} #{path}"
623
627
 
624
628
  placeholders = true
625
629
 
@@ -648,6 +652,16 @@ ERR
648
652
  stat[:entries] << orig_title if placeholders
649
653
 
650
654
  stats[title] = stat
655
+
656
+ endpoint = self.class.map_placeholders path.clone
657
+ duration = delta
658
+ time_stamp = time_stamp.utc.strftime "%Y-%m-%dT%H:%M:%S.%L"
659
+ domain = server_url.gsub %r{http://|https://}, ""
660
+ execution_id = request_id
661
+
662
+ GoodData.gd_logger.update_store(domain, method, duration, endpoint)
663
+ GoodData.gd_logger.add Logger::INFO, { endpoint: endpoint, duration: duration, domain: domain,
664
+ execution_id: execution_id, time_stamp: time_stamp }, "rest_call"
651
665
  end
652
666
  end
653
667
 
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
2
+ # This source code is licensed under the BSD-style license found in the
3
+ # LICENSE file in the root directory of this source tree.
4
+
5
+ module GoodData
6
+ module Rest
7
+ # class is responsible for storage and aggregation of REST calls information
8
+ module Aggregator
9
+ attr_reader :store
10
+
11
+ def initialize_store
12
+ @store = {}
13
+ end
14
+
15
+ def clear_store
16
+ @store.clear
17
+ end
18
+
19
+ def update_store(domain, method, duration, endpoint)
20
+ domain = domain.to_sym
21
+ method = method.to_sym
22
+ endpoint = endpoint.to_sym
23
+ @store[domain] = {} unless @store.key?(domain)
24
+ @store[domain][method] = {} unless @store[domain].key?(method)
25
+ if @store[domain][method].key?(endpoint)
26
+ record = @store[domain][method][endpoint]
27
+ record[:min] = [duration, record[:min]].min
28
+ record[:max] = [duration, record[:max]].max
29
+ record[:avg] = (record[:avg] * record[:count] + duration).to_f / (record[:count] + 1)
30
+ record[:count] += 1
31
+ @store[domain][method][endpoint] = record
32
+ else
33
+ @store[domain][method][endpoint] = {
34
+ :min => duration,
35
+ :max => duration,
36
+ :avg => duration,
37
+ :count => 1,
38
+ :method => method.to_s,
39
+ :endpoint => endpoint.to_s,
40
+ :domain => domain.to_s
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gooddata
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 2.0.0
5
5
  platform: java
6
6
  authors:
7
7
  - Pavel Kolesnikov
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2019-01-16 00:00:00.000000000 Z
17
+ date: 2019-02-18 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  requirement: !ruby/object:Gem::Requirement
@@ -502,6 +502,7 @@ files:
502
502
  - Gemfile
503
503
  - Guardfile
504
504
  - Jenkinsfile
505
+ - Jenkinsfile-chart
505
506
  - LICENSE
506
507
  - LICENSE.rb
507
508
  - README.md
@@ -532,6 +533,8 @@ files:
532
533
  - docker-compose.yml
533
534
  - gooddata
534
535
  - gooddata.gemspec
536
+ - k8s/charts/lcm-bricks/Chart.yaml
537
+ - k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml
535
538
  - lcm.rake
536
539
  - lib/gooddata.rb
537
540
  - lib/gooddata/app/app.rb
@@ -544,6 +547,8 @@ files:
544
547
  - lib/gooddata/bricks/middleware/base_middleware.rb
545
548
  - lib/gooddata/bricks/middleware/bench_middleware.rb
546
549
  - lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb
550
+ - lib/gooddata/bricks/middleware/context_logger_decorator.rb
551
+ - lib/gooddata/bricks/middleware/context_manager.rb
547
552
  - lib/gooddata/bricks/middleware/decode_params_middleware.rb
548
553
  - lib/gooddata/bricks/middleware/dwh_middleware.rb
549
554
  - lib/gooddata/bricks/middleware/fs_download_middleware.rb
@@ -587,10 +592,12 @@ files:
587
592
  - lib/gooddata/commands/user.rb
588
593
  - lib/gooddata/connection.rb
589
594
  - lib/gooddata/core/core.rb
595
+ - lib/gooddata/core/gd_logger.rb
590
596
  - lib/gooddata/core/logging.rb
591
597
  - lib/gooddata/core/nil_logger.rb
592
598
  - lib/gooddata/core/project.rb
593
599
  - lib/gooddata/core/rest.rb
600
+ - lib/gooddata/core/splunk_logger.rb
594
601
  - lib/gooddata/core/user.rb
595
602
  - lib/gooddata/data/data.rb
596
603
  - lib/gooddata/data/guesser.rb
@@ -685,6 +692,7 @@ files:
685
692
  - lib/gooddata/lcm/helpers/check_helper.rb
686
693
  - lib/gooddata/lcm/helpers/helpers.rb
687
694
  - lib/gooddata/lcm/helpers/release_table_helper.rb
695
+ - lib/gooddata/lcm/helpers/safe_failure_helper.rb
688
696
  - lib/gooddata/lcm/helpers/tags_helper.rb
689
697
  - lib/gooddata/lcm/lcm.rb
690
698
  - lib/gooddata/lcm/lcm2.rb
@@ -754,6 +762,7 @@ files:
754
762
  - lib/gooddata/mixins/not_label.rb
755
763
  - lib/gooddata/mixins/not_metric.rb
756
764
  - lib/gooddata/mixins/obj_id.rb
765
+ - lib/gooddata/mixins/property_accessor.rb
757
766
  - lib/gooddata/mixins/rest_getters.rb
758
767
  - lib/gooddata/mixins/rest_resource.rb
759
768
  - lib/gooddata/mixins/root_key_getter.rb
@@ -849,6 +858,7 @@ files:
849
858
  - lib/gooddata/rest/phmap.rb
850
859
  - lib/gooddata/rest/resource.rb
851
860
  - lib/gooddata/rest/rest.rb
861
+ - lib/gooddata/rest/rest_aggregator.rb
852
862
  - lib/gooddata/version.rb
853
863
  - lib/templates/bricks/brick.rb.erb
854
864
  - lib/templates/bricks/main.rb.erb