gooddata 0.6.6 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{CHANGELOG.markdown → CHANGELOG.md} +6 -1
- data/lib/gooddata/cli/commands/project_cmd.rb +6 -29
- data/lib/gooddata/commands/project.rb +36 -44
- data/lib/gooddata/connection.rb +7 -0
- data/lib/gooddata/core/connection.rb +3 -0
- data/lib/gooddata/core/rest.rb +38 -19
- data/lib/gooddata/mixins/md_object_query.rb +3 -2
- data/lib/gooddata/models/metadata/dashboard.rb +3 -8
- data/lib/gooddata/models/metadata/report.rb +1 -6
- data/lib/gooddata/models/model.rb +5 -4
- data/lib/gooddata/models/process.rb +10 -14
- data/lib/gooddata/models/project.rb +34 -26
- data/lib/gooddata/models/project_blueprint.rb +14 -7
- data/lib/gooddata/models/project_creator.rb +2 -6
- data/lib/gooddata/models/schedule.rb +13 -2
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
- data/spec/data/ruby_process/process.rb +2 -0
- data/spec/data/ruby_process/stuff.txt +1 -0
- data/spec/integration/full_process_schedule_spec.rb +69 -0
- data/spec/integration/full_project_spec.rb +14 -5
- data/spec/unit/models/schedule_spec.rb +7 -30
- metadata +7 -66
- data/doc/.gitignore +0 -1
- data/doc/css/.gitkeepme +0 -1
- data/doc/images/.gitkeepme +0 -1
- data/doc/images/background.png +0 -0
- data/doc/images/bg-callout-button.png +0 -0
- data/doc/images/header-logo.png +0 -0
- data/doc/images/logo-image.png +0 -0
- data/doc/js/.gitkeepme +0 -1
- data/doc/pages/GET_STARTED.md +0 -310
- data/doc/pages/HOMEPAGE.md +0 -77
- data/doc/pages/TUTORIALS.md +0 -52
- data/doc/pages/tutorial/BRICKS.md +0 -260
- data/doc/pages/tutorial/CREATING_A_MODEL.md +0 -81
- data/doc/pages/tutorial/CRUNCHING_NUMBERS.md +0 -231
- data/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md +0 -120
- data/doc/pages/tutorial/YOUR_FIRST_PROJECT.md +0 -53
- data/doc/templates/default/class/dot/setup.rb +0 -6
- data/doc/templates/default/class/dot/superklass.erb +0 -3
- data/doc/templates/default/class/setup.rb +0 -37
- data/doc/templates/default/class/text/setup.rb +0 -11
- data/doc/templates/default/class/text/subclasses.erb +0 -5
- data/doc/templates/default/constant/text/header.erb +0 -11
- data/doc/templates/default/constant/text/setup.rb +0 -3
- data/doc/templates/default/docstring/setup.rb +0 -51
- data/doc/templates/default/docstring/text/abstract.erb +0 -2
- data/doc/templates/default/docstring/text/deprecated.erb +0 -2
- data/doc/templates/default/docstring/text/index.erb +0 -2
- data/doc/templates/default/docstring/text/note.erb +0 -4
- data/doc/templates/default/docstring/text/private.erb +0 -2
- data/doc/templates/default/docstring/text/returns_void.erb +0 -1
- data/doc/templates/default/docstring/text/text.erb +0 -1
- data/doc/templates/default/docstring/text/todo.erb +0 -4
- data/doc/templates/default/layout/dot/header.erb +0 -6
- data/doc/templates/default/layout/dot/setup.rb +0 -14
- data/doc/templates/default/method/setup.rb +0 -3
- data/doc/templates/default/method/text/header.erb +0 -1
- data/doc/templates/default/method_details/setup.rb +0 -11
- data/doc/templates/default/method_details/text/header.erb +0 -10
- data/doc/templates/default/method_details/text/method_signature.erb +0 -12
- data/doc/templates/default/method_details/text/setup.rb +0 -10
- data/doc/templates/default/module/dot/child.erb +0 -1
- data/doc/templates/default/module/dot/dependencies.erb +0 -3
- data/doc/templates/default/module/dot/header.erb +0 -6
- data/doc/templates/default/module/dot/info.erb +0 -14
- data/doc/templates/default/module/dot/setup.rb +0 -14
- data/doc/templates/default/module/setup.rb +0 -164
- data/doc/templates/default/module/text/children.erb +0 -10
- data/doc/templates/default/module/text/class_meths_list.erb +0 -8
- data/doc/templates/default/module/text/extends.erb +0 -8
- data/doc/templates/default/module/text/header.erb +0 -7
- data/doc/templates/default/module/text/includes.erb +0 -8
- data/doc/templates/default/module/text/instance_meths_list.erb +0 -8
- data/doc/templates/default/module/text/setup.rb +0 -12
- data/doc/templates/default/root/dot/child.erb +0 -3
- data/doc/templates/default/root/dot/setup.rb +0 -5
- data/doc/templates/default/tags/setup.rb +0 -55
- data/doc/templates/default/tags/text/example.erb +0 -12
- data/doc/templates/default/tags/text/index.erb +0 -1
- data/doc/templates/default/tags/text/option.erb +0 -20
- data/doc/templates/default/tags/text/overload.erb +0 -19
- data/doc/templates/default/tags/text/see.erb +0 -11
- data/doc/templates/default/tags/text/tag.erb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57bce714f8ec1d419534b3a6f3730c430b5f67dd
|
4
|
+
data.tar.gz: 53a29990c0fb352dc481ff56b8361ccc25c6ff11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef33ff8a02e8385d2ba0b2fe80091a15f9ac6c69f10d69faf3dd95967e35e0a1095c3d409811d15e917a80fa7001d98e94d81a6396d28494943275d9b0f9bcf9
|
7
|
+
data.tar.gz: 2d9e907507561efc2c0e6de51037dde476c2d5a09a719abc27871fc964c671c14696feb2ef321373cf14bed0504ad45723a230c7f2a7292c3e1e4dba1321e8dc
|
@@ -1,8 +1,13 @@
|
|
1
1
|
# GoodData Ruby SDK Changelog
|
2
2
|
|
3
|
-
## 0.6.
|
3
|
+
## 0.6.7
|
4
4
|
- Fixed the scaffolding templates to take advantage of new syntax (missing references in dataset refs)
|
5
5
|
- Fixing inclusion of extensions when using CLI
|
6
|
+
- Fixed pollers and added/fixed tests for schedules and processes
|
7
|
+
- Added with_connection which automatically disconnects when you are done
|
8
|
+
|
9
|
+
## 0.6.6
|
10
|
+
- Various fixes
|
6
11
|
|
7
12
|
## 0.6.5
|
8
13
|
- Mixins
|
@@ -14,33 +14,9 @@ GoodData::CLI.module_eval do
|
|
14
14
|
c.desc 'If you are in a gooddata project blueprint or if you provide a project id it will start an interactive session inside that project'
|
15
15
|
c.command :jack_in do |jack|
|
16
16
|
jack.action do |global_options, options, args|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
project_id = global_options[:project_id] || goodfile[:project_id]
|
21
|
-
fail "You have to provide 'project_id'. You can either provide it through -p flag or even better way is to fill it in in your Goodfile under key \"project_id\". If you just started a project you have to create it first. One way might be through \"gooddata project build\"" if project_id.nil? || project_id.empty?
|
22
|
-
|
23
|
-
opts = options.merge(global_options)
|
24
|
-
GoodData.connect(opts)
|
25
|
-
|
26
|
-
begin
|
27
|
-
require 'gooddata'
|
28
|
-
GoodData::Command::Project.jack_in(project_id)
|
29
|
-
rescue GoodData::ProjectNotFound
|
30
|
-
puts "Project with id \"#{project_id}\" could not be found. Make sure that the id you provided is correct."
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
if goodfile_path
|
35
|
-
goodfile = MultiJson.load(File.read(goodfile_path), :symbolize_keys => true)
|
36
|
-
model_key = goodfile[:model]
|
37
|
-
blueprint = GoodData::Model::ProjectBlueprint.new(eval(File.read(model_key)).to_hash) if File.exist?(model_key) && !File.directory?(model_key)
|
38
|
-
FileUtils.cd(goodfile_path.dirname) do
|
39
|
-
spin_session.call(goodfile, blueprint)
|
40
|
-
end
|
41
|
-
else
|
42
|
-
spin_session.call({}, nil)
|
43
|
-
end
|
17
|
+
opts = options.merge(global_options)
|
18
|
+
GoodData.connect(opts)
|
19
|
+
GoodData::Command::Project.jack_in(opts)
|
44
20
|
end
|
45
21
|
end
|
46
22
|
|
@@ -95,11 +71,12 @@ GoodData::CLI.module_eval do
|
|
95
71
|
opts = options.merge(global_options)
|
96
72
|
id = global_options[:project_id]
|
97
73
|
token = opts[:token]
|
98
|
-
|
74
|
+
opts[:auth_token] = token
|
99
75
|
fail 'You have to provide a token for creating a project. Please use parameter --token' if token.nil? || token.empty?
|
100
76
|
|
101
77
|
GoodData.connect(opts)
|
102
|
-
GoodData::Command::Project.clone(id, opts)
|
78
|
+
new_project = GoodData::Command::Project.clone(id, opts)
|
79
|
+
puts "Project with title \"#{new_project.title}\" was cloned with id #{new_project.pid}"
|
103
80
|
end
|
104
81
|
end
|
105
82
|
|
@@ -32,44 +32,9 @@ module GoodData
|
|
32
32
|
|
33
33
|
# Clone existing project
|
34
34
|
def clone(project_id, options)
|
35
|
-
|
36
|
-
|
37
|
-
export = {
|
38
|
-
:exportProject => {
|
39
|
-
:exportUsers => with_users ? 1 : 0,
|
40
|
-
:exportData => with_data ? 1 : 0
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
result = GoodData.post("/gdc/md/#{project_id}/maintenance/export", export)
|
45
|
-
export_token = result['exportArtifact']['token']
|
46
|
-
status_url = result['exportArtifact']['status']['uri']
|
47
|
-
|
48
|
-
state = GoodData.get(status_url)['taskState']['status']
|
49
|
-
while state == 'RUNNING'
|
50
|
-
sleep 5
|
51
|
-
result = GoodData.get(status_url)
|
52
|
-
state = result['taskState']['status']
|
53
|
-
end
|
54
|
-
|
55
|
-
old_project = GoodData::Project[project_id]
|
56
|
-
project_uri = create(options.merge(:title => "Clone of #{old_project.title}"))
|
57
|
-
new_project = GoodData::Project[project_uri]
|
58
|
-
|
59
|
-
import = {
|
60
|
-
:importProject => {
|
61
|
-
:token => export_token
|
62
|
-
}
|
63
|
-
}
|
64
|
-
result = GoodData.post("/gdc/md/#{new_project.obj_id}/maintenance/import", import)
|
65
|
-
status_url = result['uri']
|
66
|
-
state = GoodData.get(status_url)['taskState']['status']
|
67
|
-
while state == 'RUNNING'
|
68
|
-
sleep 5
|
69
|
-
result = GoodData.get(status_url)
|
70
|
-
state = result['taskState']['status']
|
35
|
+
GoodData.with_project(project_id) do |project|
|
36
|
+
project.clone(options)
|
71
37
|
end
|
72
|
-
true
|
73
38
|
end
|
74
39
|
|
75
40
|
# Delete existing project
|
@@ -142,13 +107,40 @@ module GoodData
|
|
142
107
|
end
|
143
108
|
end
|
144
109
|
|
145
|
-
def jack_in(
|
146
|
-
GoodData.
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
110
|
+
def jack_in(options)
|
111
|
+
goodfile_path = GoodData::Helpers.find_goodfile(Pathname('.'))
|
112
|
+
|
113
|
+
spin_session = proc do |goodfile, blueprint|
|
114
|
+
project_id = options[:project_id] || goodfile[:project_id]
|
115
|
+
message = 'You have to provide "project_id". You can either provide it through -p flag'\
|
116
|
+
'or even better way is to fill it in in your Goodfile under key "project_id".'\
|
117
|
+
'If you just started a project you have to create it first. One way might be'\
|
118
|
+
'through "gooddata project build"'
|
119
|
+
fail message if project_id.nil? || project_id.empty?
|
120
|
+
|
121
|
+
begin
|
122
|
+
require 'gooddata'
|
123
|
+
GoodData.with_project(project_id) do |project|
|
124
|
+
puts "Use 'exit' to quit the live session. Use 'q' to jump out of displaying a large output."
|
125
|
+
binding.pry(:quiet => true,
|
126
|
+
:prompt => [proc do |target_self, nest_level, pry|
|
127
|
+
'project_live_sesion: '
|
128
|
+
end])
|
129
|
+
end
|
130
|
+
rescue GoodData::ProjectNotFound
|
131
|
+
puts "Project with id \"#{project_id}\" could not be found. Make sure that the id you provided is correct."
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if goodfile_path
|
136
|
+
goodfile = MultiJson.load(File.read(goodfile_path), :symbolize_keys => true)
|
137
|
+
model_key = goodfile[:model]
|
138
|
+
blueprint = GoodData::Model::ProjectBlueprint.new(eval(File.read(model_key)).to_hash) if File.exist?(model_key) && !File.directory?(model_key)
|
139
|
+
FileUtils.cd(goodfile_path.dirname) do
|
140
|
+
spin_session.call(goodfile, blueprint)
|
141
|
+
end
|
142
|
+
else
|
143
|
+
spin_session.call({}, nil)
|
152
144
|
end
|
153
145
|
end
|
154
146
|
end
|
data/lib/gooddata/connection.rb
CHANGED
@@ -67,5 +67,12 @@ module GoodData
|
|
67
67
|
connection.status = :logged_in
|
68
68
|
connection
|
69
69
|
end
|
70
|
+
|
71
|
+
def with_connection(options = nil, second_options = nil, third_options = {}, &bl)
|
72
|
+
connection = connect(options, second_options, third_options)
|
73
|
+
bl.call(connection)
|
74
|
+
ensure
|
75
|
+
disconnect
|
76
|
+
end
|
70
77
|
end
|
71
78
|
end
|
@@ -346,6 +346,9 @@ module GoodData
|
|
346
346
|
if content_type == 'application/json' || content_type == 'application/json;charset=UTF-8'
|
347
347
|
result = response.to_str == '""' ? {} : MultiJson.load(response.to_str)
|
348
348
|
GoodData.logger.debug "Response: #{result.inspect}"
|
349
|
+
elsif ['text/plain;charset=UTF-8', 'text/plain; charset=UTF-8', 'text/plain'].include?(content_type)
|
350
|
+
result = response
|
351
|
+
GoodData.logger.debug 'Response: plain text'
|
349
352
|
elsif content_type == 'application/zip'
|
350
353
|
result = response
|
351
354
|
GoodData.logger.debug 'Response: a zipped stream'
|
data/lib/gooddata/core/rest.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require_relative 'connection'
|
4
4
|
|
5
5
|
module GoodData
|
6
|
+
DEFAULT_SLEEP_INTERVAL = 10
|
7
|
+
|
6
8
|
class << self
|
7
9
|
# Performs a HTTP GET request.
|
8
10
|
#
|
@@ -95,36 +97,53 @@ module GoodData
|
|
95
97
|
connection.download(file, where, options.merge(:staging_url => url))
|
96
98
|
end
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
# Generalizaton of poller. Since we have quite a variation of how async proceses are handled
|
101
|
+
# this is a helper that should help you with resources where the information about "Are we done"
|
102
|
+
# is the http code of response. By default we repeat as long as the code == 202. You can
|
103
|
+
# change the code if necessary. It expects the URI as an input where it can poll. It returns the
|
104
|
+
# value of last poll. In majority of cases these are the data that you need.
|
105
|
+
#
|
106
|
+
# @param link [String] Link for polling
|
107
|
+
# @param options [Hash] Options
|
108
|
+
# @return [Hash] Result of polling
|
109
|
+
def poll_on_code(link, options = {})
|
110
|
+
code = options[:code] || 202
|
111
|
+
sleep_interval = options[:sleep_interval] || DEFAULT_SLEEP_INTERVAL
|
101
112
|
response = GoodData.get(link, :process => false)
|
102
|
-
while response.code
|
113
|
+
while response.code == code
|
103
114
|
sleep sleep_interval
|
104
115
|
GoodData.connection.retryable(:tries => 3, :on => RestClient::InternalServerError) do
|
105
116
|
sleep sleep_interval
|
106
117
|
response = GoodData.get(link, :process => false)
|
107
118
|
end
|
108
119
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
polling_result = GoodData.get(polling_url)
|
114
|
-
while polling_result[root]
|
115
|
-
sleep(3)
|
116
|
-
polling_result = GoodData.get(polling_url)
|
120
|
+
if options[:process] == false
|
121
|
+
response
|
122
|
+
else
|
123
|
+
GoodData.get(link)
|
117
124
|
end
|
118
|
-
polling_result
|
119
125
|
end
|
120
126
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
127
|
+
# Generalizaton of poller. Since we have quite a variation of how async proceses are handled
|
128
|
+
# this is a helper that should help you with resources where the information about "Are we done"
|
129
|
+
# is inside the response. It expects the URI as an input where it can poll and a block that should
|
130
|
+
# return either true -> 'meaning we are done' or false -> meaning sleep and repeat. It returns the
|
131
|
+
# value of last poll. In majority of cases these are the data that you need
|
132
|
+
#
|
133
|
+
# @param link [String] Link for polling
|
134
|
+
# @param options [Hash] Options
|
135
|
+
# @return [Hash] Result of polling
|
136
|
+
def poll_on_response(link, options = {}, &bl)
|
137
|
+
sleep_interval = options[:sleep_interval] || DEFAULT_SLEEP_INTERVAL
|
138
|
+
response = GoodData.get(link)
|
139
|
+
while bl.call(response)
|
140
|
+
sleep sleep_interval
|
141
|
+
GoodData.connection.retryable(:tries => 3, :on => RestClient::InternalServerError) do
|
142
|
+
sleep sleep_interval
|
143
|
+
response = GoodData.get(link)
|
144
|
+
end
|
126
145
|
end
|
127
|
-
|
146
|
+
response
|
128
147
|
end
|
129
148
|
end
|
130
149
|
end
|
@@ -24,8 +24,9 @@ module GoodData
|
|
24
24
|
# @option options [Boolean] :full if passed true the subclass can decide to pull in full objects. This is desirable from the usability POV but unfortunately has negative impact on performance so it is not the default
|
25
25
|
# @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
|
26
26
|
def query(query_obj_type, klass, options = {})
|
27
|
-
|
28
|
-
|
27
|
+
project = options[:project] || GoodData.project
|
28
|
+
fail(NoProjectError, 'Connect to a project before searching for an object') unless project
|
29
|
+
query_result = GoodData.get(project.md['query'] + "/#{query_obj_type}/")['query']['entries']
|
29
30
|
options[:full] ? query_result.map { |item| klass[item['link']] } : query_result
|
30
31
|
end
|
31
32
|
|
@@ -86,14 +86,9 @@ module GoodData
|
|
86
86
|
fail "Wrong format provied \"#{format}\". Only supports formats #{supported_formats.join(', ')}" unless supported_formats.include?(format)
|
87
87
|
tab = options[:tab] || ''
|
88
88
|
|
89
|
-
req_uri = "/gdc/projects/#{GoodData.project.
|
90
|
-
x = GoodData.post(req_uri,
|
91
|
-
|
92
|
-
sleep(1)
|
93
|
-
uri = MultiJson.load(x.body)['asyncTask']['link']['poll']
|
94
|
-
x = GoodData.get(uri, :process => false)
|
95
|
-
end
|
96
|
-
x
|
89
|
+
req_uri = "/gdc/projects/#{GoodData.project.pid}/clientexport"
|
90
|
+
x = GoodData.post(req_uri, 'clientExport' => { 'url' => "https://secure.gooddata.com/dashboard.html#project=#{GoodData.project.uri}&dashboard=#{uri}&tab=#{tab}&export=1", 'name' => title })
|
91
|
+
GoodData.poll_on_code(x['asyncTask']['link']['poll'], process: false)
|
97
92
|
end
|
98
93
|
|
99
94
|
def tabs
|
@@ -103,12 +103,7 @@ module GoodData
|
|
103
103
|
def export(format)
|
104
104
|
result = GoodData.post('/gdc/xtab2/executor3', 'report_req' => { 'report' => uri })
|
105
105
|
result1 = GoodData.post('/gdc/exporter/executor', :result_req => { :format => format, :result => result })
|
106
|
-
|
107
|
-
while png.code == 202
|
108
|
-
sleep(1)
|
109
|
-
png = GoodData.get(result1['uri'], :process => false)
|
110
|
-
end
|
111
|
-
png
|
106
|
+
GoodData.poll_on_code(result1['uri'], process: false)
|
112
107
|
end
|
113
108
|
end
|
114
109
|
end
|
@@ -108,11 +108,12 @@ module GoodData
|
|
108
108
|
pull = { 'pullIntegration' => File.basename(dir) }
|
109
109
|
link = project.md.links('etl')['pull']
|
110
110
|
task = GoodData.post link, pull
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
|
112
|
+
res = GoodData.poll_on_response(task['pullTask']['uri']) do |body|
|
113
|
+
body['taskStatus'] == 'RUNNING' || body['taskStatus'] == 'PREPARED'
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
|
+
if res['taskStatus'] == 'ERROR'
|
116
117
|
s = StringIO.new
|
117
118
|
GoodData.download_from_user_webdav(File.basename(dir) + '/upload_status.json', s)
|
118
119
|
js = MultiJson.load(s.string)
|
@@ -6,6 +6,10 @@ module GoodData
|
|
6
6
|
class Process
|
7
7
|
attr_reader :data
|
8
8
|
|
9
|
+
alias_method :raw_data, :data
|
10
|
+
alias_method :json, :data
|
11
|
+
alias_method :to_hash, :data
|
12
|
+
|
9
13
|
class << self
|
10
14
|
def [](id, options = {})
|
11
15
|
if id == :all
|
@@ -27,7 +31,7 @@ module GoodData
|
|
27
31
|
# TODO: Check the params.
|
28
32
|
def with_deploy(dir, options = {}, &block)
|
29
33
|
# verbose = options[:verbose] || false
|
30
|
-
GoodData.with_project(options[:project_id]) do |project|
|
34
|
+
GoodData.with_project(options[:project_id] || options[:project]) do |project|
|
31
35
|
params = options[:params].nil? ? [] : [options[:params]]
|
32
36
|
if block
|
33
37
|
begin
|
@@ -71,7 +75,6 @@ module GoodData
|
|
71
75
|
#
|
72
76
|
# @param path [String] Path to ZIP archive or to a directory containing files that should be ZIPed
|
73
77
|
# @option options [String] :files_to_exclude
|
74
|
-
# @option options [String] :process_id ('nobody') From address
|
75
78
|
# @option options [String] :type ('GRAPH') Type of process - GRAPH or RUBY
|
76
79
|
# @option options [String] :name Readable name of the process
|
77
80
|
# @option options [String] :process_id ID of a process to be redeployed (do not set if you want to create a new process)
|
@@ -164,19 +167,12 @@ module GoodData
|
|
164
167
|
end
|
165
168
|
|
166
169
|
def schedules
|
167
|
-
|
168
|
-
|
169
|
-
scheds = GoodData::Schedule[:all]
|
170
|
-
scheds['schedules']['items'].each do |item|
|
171
|
-
if item['schedule']['params']['PROCESS_ID'] == obj_id
|
172
|
-
res << GoodData::Schedule.new(item)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
res
|
170
|
+
GoodData::Schedule[:all].select { |schedule| schedule.process_id == obj_id }
|
177
171
|
end
|
178
172
|
|
179
|
-
|
173
|
+
def create_schedule(cron, executable, options = {})
|
174
|
+
GoodData::Schedule.create(process_id, cron, executable, options)
|
175
|
+
end
|
180
176
|
|
181
177
|
def execute(executable, options = {})
|
182
178
|
params = options[:params] || {}
|
@@ -188,7 +184,7 @@ module GoodData
|
|
188
184
|
:hiddenParams => hidden_params
|
189
185
|
})
|
190
186
|
begin
|
191
|
-
GoodData.
|
187
|
+
GoodData.poll_on_code(result['executionTask']['links']['poll'])
|
192
188
|
rescue RestClient::RequestFailed => e
|
193
189
|
raise(e)
|
194
190
|
ensure
|
@@ -119,6 +119,10 @@ module GoodData
|
|
119
119
|
project
|
120
120
|
end
|
121
121
|
|
122
|
+
def create_from_blueprint(blueprint, options = {})
|
123
|
+
GoodData::Model::ProjectCreator.migrate(:spec => blueprint, :token => options[:auth_token])
|
124
|
+
end
|
125
|
+
|
122
126
|
# Takes one CSV line and creates hash from data extracted
|
123
127
|
#
|
124
128
|
# @param row CSV row
|
@@ -139,14 +143,16 @@ module GoodData
|
|
139
143
|
|
140
144
|
def add_metric(options = {})
|
141
145
|
options[:expression] || fail('Metric has to have its expression defined')
|
142
|
-
m1 = GoodData::Metric.
|
146
|
+
m1 = GoodData::Metric.xcreate(options)
|
143
147
|
m1.save
|
144
148
|
end
|
149
|
+
alias_method :create_metric, :add_metric
|
145
150
|
|
146
151
|
def add_report(options = {})
|
147
152
|
rep = GoodData::Report.create(options)
|
148
153
|
rep.save
|
149
154
|
end
|
155
|
+
alias_method :create_report, :add_report
|
150
156
|
|
151
157
|
# Returns an indication whether current user is admin in this project
|
152
158
|
#
|
@@ -160,7 +166,8 @@ module GoodData
|
|
160
166
|
# @return [GoodData::ProjectRole] Project role if found
|
161
167
|
def blueprint
|
162
168
|
result = GoodData.get("/gdc/projects/#{pid}/model/view")
|
163
|
-
|
169
|
+
polling_url = result['asyncTask']['link']['poll']
|
170
|
+
model = GoodData.poll_on_code(polling_url)
|
164
171
|
GoodData::Model::FromWire.from_wire(model)
|
165
172
|
end
|
166
173
|
|
@@ -197,13 +204,10 @@ module GoodData
|
|
197
204
|
|
198
205
|
result = GoodData.post("/gdc/md/#{obj_id}/maintenance/export", export)
|
199
206
|
export_token = result['exportArtifact']['token']
|
200
|
-
status_url = result['exportArtifact']['status']['uri']
|
201
207
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
result = GoodData.get(status_url)
|
206
|
-
state = result['taskState']['status']
|
208
|
+
status_url = result['exportArtifact']['status']['uri']
|
209
|
+
GoodData.poll_on_response(status_url) do |body|
|
210
|
+
body['taskState']['status'] == 'RUNNING'
|
207
211
|
end
|
208
212
|
|
209
213
|
import = {
|
@@ -214,12 +218,10 @@ module GoodData
|
|
214
218
|
|
215
219
|
result = GoodData.post("/gdc/md/#{new_project.obj_id}/maintenance/import", import)
|
216
220
|
status_url = result['uri']
|
217
|
-
|
218
|
-
|
219
|
-
sleep 5
|
220
|
-
result = GoodData.get(status_url)
|
221
|
-
state = result['taskState']['status']
|
221
|
+
GoodData.poll_on_response(status_url) do |body|
|
222
|
+
body['taskState']['status'] == 'RUNNING'
|
222
223
|
end
|
224
|
+
|
223
225
|
new_project
|
224
226
|
end
|
225
227
|
|
@@ -268,6 +270,14 @@ module GoodData
|
|
268
270
|
end
|
269
271
|
end
|
270
272
|
|
273
|
+
# Helper for getting facts of a project
|
274
|
+
#
|
275
|
+
# @param [String | Number | Object] Anything that you can pass to GoodData::Fact[id]
|
276
|
+
# @return [GoodData::Fact] fact instance or list
|
277
|
+
def fact(id)
|
278
|
+
GoodData::Fact[id, project: self]
|
279
|
+
end
|
280
|
+
|
271
281
|
# Gets project role by its identifier
|
272
282
|
#
|
273
283
|
# @param [String] role_name Title of role to look for
|
@@ -476,9 +486,11 @@ module GoodData
|
|
476
486
|
polling_url = result['partialMDArtifact']['status']['uri']
|
477
487
|
token = result['partialMDArtifact']['token']
|
478
488
|
|
479
|
-
polling_result = GoodData.
|
489
|
+
polling_result = GoodData.poll_on_response(polling_url) do |body|
|
490
|
+
body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
491
|
+
end
|
480
492
|
|
481
|
-
fail 'Exporting objects failed' if polling_result['wTaskStatus']['status'] == 'ERROR'
|
493
|
+
fail 'Exporting objects failed' if polling_result['wTaskStatus'] && polling_result['wTaskStatus']['status'] == 'ERROR'
|
482
494
|
|
483
495
|
import_payload = {
|
484
496
|
:partialMDImport => {
|
@@ -490,7 +502,10 @@ module GoodData
|
|
490
502
|
|
491
503
|
result = GoodData.post("#{target_project.md['maintenance']}/partialmdimport", import_payload)
|
492
504
|
polling_url = result['uri']
|
493
|
-
|
505
|
+
|
506
|
+
GoodData.poll_on_response(polling_url) do |body|
|
507
|
+
body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
508
|
+
end
|
494
509
|
|
495
510
|
fail 'Exporting objects failed' if polling_result['wTaskStatus']['status'] == 'ERROR'
|
496
511
|
end
|
@@ -576,12 +591,8 @@ module GoodData
|
|
576
591
|
#
|
577
592
|
# @return [Array<GoodData::Schedule>] List of schedules
|
578
593
|
def schedules
|
579
|
-
res = []
|
580
594
|
tmp = GoodData.get @json['project']['links']['schedules']
|
581
|
-
tmp['schedules']['items'].
|
582
|
-
res << GoodData::Schedule.new(schedule)
|
583
|
-
end
|
584
|
-
res
|
595
|
+
tmp['schedules']['items'].map { |schedule| GoodData::Schedule.new(schedule) }
|
585
596
|
end
|
586
597
|
|
587
598
|
# Gets SLIs data
|
@@ -791,12 +802,9 @@ module GoodData
|
|
791
802
|
def validate(filters = %w(ldm pdm metric_filter invalid_objects))
|
792
803
|
response = GoodData.post "#{GoodData.project.md['validate-project']}", 'validateProject' => filters
|
793
804
|
polling_link = response['asyncTask']['link']['poll']
|
794
|
-
|
795
|
-
|
796
|
-
sleep(3)
|
797
|
-
polling_result = GoodData.get(polling_link)
|
805
|
+
GoodData.poll_on_response(polling_link) do |body|
|
806
|
+
body['wTaskStatus'] && body['wTaskStatus']['status'] == 'RUNNING'
|
798
807
|
end
|
799
|
-
polling_result
|
800
808
|
end
|
801
809
|
end
|
802
810
|
end
|