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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +54 -36
- data/CHANGELOG.md +37 -1
- data/CONTRIBUTING.md +4 -0
- data/Gemfile +9 -0
- data/Jenkinsfile-chart +14 -0
- data/RELEASING.md +5 -8
- data/Rakefile +1 -1
- data/SDK_VERSION +1 -1
- data/bin/run_brick.rb +1 -1
- data/bin/test_projects_cleanup.rb +20 -8
- data/ci.rake +2 -2
- data/k8s/charts/lcm-bricks/Chart.yaml +4 -0
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +96 -0
- data/lcm.rake +1 -1
- data/lib/gooddata/bricks/middleware/context_logger_decorator.rb +31 -0
- data/lib/gooddata/bricks/middleware/context_manager.rb +68 -0
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +15 -9
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +20 -0
- data/lib/gooddata/bricks/middleware/mask_logger_decorator.rb +35 -5
- data/lib/gooddata/client.rb +2 -3
- data/lib/gooddata/core/gd_logger.rb +92 -0
- data/lib/gooddata/core/logging.rb +24 -7
- data/lib/gooddata/core/nil_logger.rb +1 -2
- data/lib/gooddata/core/splunk_logger.rb +23 -0
- data/lib/gooddata/lcm/actions/synchronize_users.rb +2 -1
- data/lib/gooddata/lcm/helpers/check_helper.rb +3 -15
- data/lib/gooddata/lcm/helpers/safe_failure_helper.rb +19 -0
- data/lib/gooddata/lcm/lcm2.rb +21 -10
- data/lib/gooddata/mixins/property_accessor.rb +30 -0
- data/lib/gooddata/models/execution.rb +5 -0
- data/lib/gooddata/models/project.rb +6 -4
- data/lib/gooddata/rest/client.rb +17 -6
- data/lib/gooddata/rest/connection.rb +20 -6
- data/lib/gooddata/rest/rest_aggregator.rb +46 -0
- 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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/gooddata/lcm/lcm2.rb
CHANGED
@@ -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
|
-
|
357
|
-
|
358
|
-
|
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
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
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 =
|
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
|
-
|
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
|
data/lib/gooddata/rest/client.rb
CHANGED
@@ -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
|
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(
|
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
|
-
|
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
|
623
|
+
def add_stat_record(method, path, delta, time_stamp, request_id)
|
621
624
|
synchronize do
|
622
|
-
orig_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:
|
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-
|
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
|