gooddata 1.3.6-java → 2.0.0-java

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