gooddata 0.6.25 → 0.6.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 251de9ca156643db700ec8307dd7858d0f557558
4
- data.tar.gz: 1202bb213978374571684a8a8024f010b42b9432
3
+ metadata.gz: 2127d4270e7e7ca7cb11b464bc50764279bccdf8
4
+ data.tar.gz: 3422d4671cd05b67654483c2d05528935f5c19c7
5
5
  SHA512:
6
- metadata.gz: 7f69fe0dfbd568c04489bdb2952846a18e090f2eac175e3ea135c1a5d4593464dccf34f68e2be2ce93de8b16f4fb7f149225a6d45a54fd922f62af88ce224f73
7
- data.tar.gz: 1b28234c6dd160762633f02e25d989b81bbfeb8465b05b59ee3d49b6be4f0f955fb9c47958906464ede7366c19bdbeb585e753ff446ec5da8bc1768b4f696391
6
+ metadata.gz: 0de341f4966e2955cc650c06ab6af2ae0d4e14d74a995d165bb9b62c72a1f32391691052d80687be74dc84694d93070114fd99460295b72957bff3614a95b69a
7
+ data.tar.gz: bdcc154ca1a135aaa194f6f6bca3697c1cbef5deb95e8c38eb3220c2b0d71e15367d727ebdd6a221a3fa729cc88acf19d18ffe106af743601e2fd59bc1a944ba
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # GoodData Ruby SDK Changelog
2
2
 
3
+ ## 0.6.26
4
+ - There is first implementation of transfering ETLs
5
+ - Fixed bug with getting clients from domain
6
+ - Temporary workaround for problem on API when it fails with 500 when you are trying to read changes of provision clients when nothing was provisioned
7
+ - Added option to not delete projects when updating clients in segments
8
+
3
9
  ## 0.6.24
4
10
  - Fixed problem with validElements causing 500
5
11
 
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ require 'yard'
15
15
  require 'rubocop/rake_task'
16
16
 
17
17
  desc 'Run RuboCop'
18
- RuboCop::RakeTask.new(:rubocop) do |task|
18
+ RuboCop::RakeTask.new(:cop) do |task|
19
19
  task.patterns = ['lib/**/*.rb']
20
20
  end
21
21
 
data/gooddata.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.homepage = 'http://github.com/gooddata/gooddata-ruby'
28
28
  s.require_paths = ['lib']
29
29
 
30
- s.add_development_dependency 'bundler', '>= 1.10.6'
30
+ s.add_development_dependency 'bundler'
31
31
  s.add_development_dependency 'debase', '~> 0.1', '>= 0.1.7' if !ENV['TRAVIS_BUILD'] && RUBY_VERSION >= '2.0.0'
32
32
  s.add_development_dependency 'guard', '~> 2.13', '>= 2.13.0'
33
33
  s.add_development_dependency 'guard-rspec', '~> 4.6', '>= 4.6.4'
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 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 'pathname'
8
+ require 'pp'
9
+
10
+ require_relative '../shared'
11
+ require_relative '../../commands/domain'
12
+
13
+ module GoodData
14
+ module CLI
15
+ desc 'Manage your domain'
16
+ arg_name 'domain_command'
17
+
18
+ command :domain do |c|
19
+ c.desc 'Shows users in domain'
20
+ c.command :users do |users|
21
+ users.action do |global_options, options, args|
22
+ opts = options.merge(global_options)
23
+ GoodData::Command::Domain.list_users(args[0], opts)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -24,6 +24,14 @@ module GoodData
24
24
  GoodData::Command::Project.jack_in(opts)
25
25
  end
26
26
  end
27
+
28
+ c.desc 'Shows users in project'
29
+ c.command :users do |users|
30
+ users.action do |global_options, options, _args|
31
+ opts = options.merge(global_options)
32
+ GoodData::Command::Project.list_users(opts)
33
+ end
34
+ end
27
35
  end
28
36
 
29
37
  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'
@@ -23,8 +23,16 @@ module GoodData
23
23
  GoodData::Domain.add_user(data.merge(opts))
24
24
  end
25
25
 
26
- def list_users(domain, opts = { :client => GoodData.connection })
27
- GoodData::Domain.users(domain, opts)
26
+ def list_users(domain_name, options = { :client => GoodData.connection })
27
+ client = GoodData.connect(options)
28
+ domain = client.domain(domain_name)
29
+
30
+ rows = domain.users.to_a.map do |user|
31
+ [user.email, user.full_name]
32
+ end
33
+
34
+ table = Terminal::Table.new :headings => ['Email', 'Full Name'], :rows => rows
35
+ puts table
28
36
  end
29
37
  end
30
38
  end
@@ -5,6 +5,9 @@
5
5
  # LICENSE file in the root directory of this source tree.
6
6
 
7
7
  require 'pathname'
8
+ require 'terminal-table'
9
+
10
+ require_relative '../connection'
8
11
 
9
12
  module GoodData
10
13
  module Command
@@ -146,9 +149,26 @@ module GoodData
146
149
  # @param project_id [String | GoodData::Project] Project id or project instance to list the users in
147
150
  # @return [Array <GoodData::Membership>] List of project users
148
151
  def users(project_id, options = { client: GoodData.connection })
149
- client = options[:client]
152
+ client = options[:client] || GoodData.connect(options)
150
153
  client.with_project(project_id, &:users)
151
154
  end
155
+
156
+ # Lists users in a project
157
+ #
158
+ # @param options [Hash] List of users
159
+ #
160
+ # TODO: Review and refactor #users & #list_users
161
+ def list_users(options = { client: GoodData.connection })
162
+ client = GoodData.connect(options)
163
+ project = client.projects(options[:project_id])
164
+
165
+ rows = project.users.to_a.map do |user|
166
+ [user.email, user.full_name, user.role.title, user.user_groups.join(', ')]
167
+ end
168
+
169
+ table = Terminal::Table.new :headings => ['Email', 'Full Name', 'Role', 'Groups'], :rows => rows
170
+ puts table
171
+ end
152
172
  end
153
173
  end
154
174
  end
@@ -63,10 +63,12 @@ module GoodData
63
63
  mapping.pmap { |f, t| [project.objects(f), project.objects(t)] }
64
64
  end
65
65
 
66
- def get_path(an_object, path = [])
66
+ def get_path(an_object, path = [], default = nil)
67
67
  return an_object if path.empty?
68
+ return default if an_object.nil?
69
+
68
70
  path.reduce(an_object) do |a, e|
69
- a && a.key?(e) ? a[e] : nil
71
+ a && a.key?(e) ? a[e] : default
70
72
  end
71
73
  end
72
74
 
@@ -258,6 +260,14 @@ module GoodData
258
260
  m.times.map { n.times.map { val } }
259
261
  end
260
262
 
263
+ # Turns a boolean or string 'true' into boolean. Useful for bricks.
264
+ #
265
+ # @param [Object] Something
266
+ # @return [Boolean] Returns true or false if the input is 'true' or true
267
+ def to_boolean(param)
268
+ (param == 'true' || param == true) ? true : false
269
+ end
270
+
261
271
  # encrypts data with the given key. returns a binary data with the
262
272
  # unhashed random iv in the first 16 bytes
263
273
  def encrypt(data, key)
@@ -38,23 +38,27 @@ module GoodData
38
38
  client = domain.client
39
39
  fail ArgumentError, 'No client specified' if client.nil?
40
40
 
41
- base_uri = domain.segments_uri + "/clients?segment=#{CGI.escape(segment.segment_id)}"
42
- tenants_uri = id == :all ? base_uri : base_uri + "&name=#{CGI.escape(id)}"
43
- e = Enumerator.new do |y|
44
- loop do
45
- res = client.get tenants_uri
46
- res['clients']['paging']['next']
47
- res['clients']['items'].each do |i|
48
- p = i['client']['project']
49
- tenant = client.create(GoodData::Client, i.merge('domain' => domain))
50
- tenant.project = p
51
- y << tenant
41
+ if id == :all
42
+ tenants_uri = domain.segments_uri + "/clients?segment=#{CGI.escape(segment.segment_id)}"
43
+ Enumerator.new do |y|
44
+ loop do
45
+ res = client.get tenants_uri
46
+ res['clients']['paging']['next']
47
+ res['clients']['items'].each do |i|
48
+ p = i['client']['project']
49
+ tenant = client.create(GoodData::Client, i.merge('domain' => domain))
50
+ tenant.project = p
51
+ y << tenant
52
+ end
53
+ url = res['clients']['paging']['next']
54
+ break unless url
52
55
  end
53
- url = res['clients']['paging']['next']
54
- break unless url
55
56
  end
57
+ else
58
+ id = id.respond_to?(:client_id) ? id.client_id : id
59
+ data = client.get(domain.segments_uri + "/clients/#{CGI.escape(id)}")
60
+ client.create(GoodData::Client, data.merge('domain' => domain))
56
61
  end
57
- id == :all ? e : e.first
58
62
  end
59
63
 
60
64
  # Creates new client from parameters passed
@@ -186,7 +186,7 @@ module GoodData
186
186
  url = "#{domain.uri}/users?login=#{escaped_login}"
187
187
  tmp = c.get url
188
188
  items = tmp['accountSettings']['items'] if tmp['accountSettings']
189
- items && items.length > 0 ? c.factory.create(GoodData::Profile, items.first) : nil
189
+ items && !items.empty? ? c.factory.create(GoodData::Profile, items.first) : nil
190
190
  end
191
191
 
192
192
  # Returns list of users for domain specified
@@ -274,12 +274,23 @@ module GoodData
274
274
  GoodData::Domain.add_user(data, name, { client: client }.merge(opts))
275
275
  end
276
276
 
277
- def clients
277
+ # Returns all the clients defined in all segments defined in domain. Alternatively
278
+ # id of a client can be provided in which case it returns just that client
279
+ # if it exists.
280
+ #
281
+ # @param id [String] Id of client that you are looking for
282
+ # @return [Object] Raw response
283
+ #
284
+ def clients(id = :all)
278
285
  clients_uri = "/gdc/domains/#{name}/clients"
279
286
  res = client.get(clients_uri)
280
287
  res_clients = (res['clients'] && res['clients']['items']) || []
281
- res_clients.map do |res_client|
282
- client.create(GoodData::Client, res_client)
288
+ if id == :all
289
+ res_clients.map { |res_client| client.create(GoodData::Client, res_client) }
290
+ else
291
+ find_result = res_clients.find { |c| c['client']['id'] == id }
292
+ fail "Client with id #{id} was not found" unless find_result
293
+ client.create(GoodData::Client, find_result)
283
294
  end
284
295
  end
285
296
 
@@ -376,13 +387,16 @@ module GoodData
376
387
  def provision_client_projects
377
388
  res = client.post(segments_uri + '/provisionClientProjects', nil)
378
389
  res = client.poll_on_code(res['asyncTask']['links']['poll'])
379
- klass = Struct.new('ProvisioningResult', :id, :status, :project_uri)
390
+ klass = Struct.new('ProvisioningResult', :id, :status, :project_uri, :error)
391
+ failed_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult failed count), 0)
392
+ created_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult created count), 0)
393
+ return Enumerator.new([]) if failed_count + created_count == 0
380
394
  Enumerator.new do |y|
381
395
  uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult links details))
382
396
  loop do
383
397
  result = client.get(uri)
384
398
  (GoodData::Helpers.get_path(result, %w(clientProjectProvisioningResultDetails items)) || []).each do |item|
385
- y << klass.new(item['id'], item['status'], item['project'])
399
+ y << klass.new(item['id'], item['status'], item['project'], item['error'])
386
400
  end
387
401
  uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResultDetails paging next))
388
402
  break if uri.nil?
@@ -391,14 +405,16 @@ module GoodData
391
405
  end
392
406
 
393
407
  def update_clients(data, options = {})
408
+ delete_projects = options[:delete_projects] == false ? false : true
394
409
  payload = data.map do |datum|
395
410
  {
396
411
  :client => {
397
412
  :id => datum[:id],
398
- :segment => segments_uri + '/segments/' + datum[:segment],
399
- :project => datum[:project]
413
+ :segment => segments_uri + '/segments/' + datum[:segment]
400
414
  }
401
- }
415
+ }.tap do |h|
416
+ h[:client][:project] = datum[:project] if datum.key?(:project)
417
+ end
402
418
  end
403
419
  if options[:delete_extra] == true
404
420
  res = client.post(segments_uri + '/updateClients?deleteExtra=true', updateClients: { items: payload })
@@ -408,7 +424,7 @@ module GoodData
408
424
  data = GoodData::Helpers.get_path(res, ['updateClientsResponse'])
409
425
  if data
410
426
  result = data.flat_map { |k, v| v.map { |h| GoodData::Helpers.symbolize_keys(h.merge('type' => k)) } }
411
- result.select { |r| r[:status] == 'DELETED' }.peach { |r| r[:originalProject] && client.delete(r[:originalProject]) }
427
+ result.select { |r| r[:status] == 'DELETED' }.peach { |r| r[:originalProject] && client.delete(r[:originalProject]) } if delete_projects
412
428
  result
413
429
  else
414
430
  []
@@ -9,6 +9,7 @@ require 'pmap'
9
9
 
10
10
  require_relative 'project'
11
11
  require_relative 'project_role'
12
+ require_relative 'user_group'
12
13
 
13
14
  require_relative '../rest/object'
14
15
 
@@ -162,6 +163,14 @@ module GoodData
162
163
  @json['user']['content']['firstname'] = new_first_name
163
164
  end
164
165
 
166
+ # Get full name
167
+ #
168
+ # @return String Full Name
169
+ # NOTE: This can be tricky to implement correctly for i18n
170
+ def full_name
171
+ "#{first_name} #{last_name}"
172
+ end
173
+
165
174
  # Gets the invitations
166
175
  #
167
176
  # @return [Array<GoodData::Invitation>] List of invitations
@@ -289,6 +298,8 @@ module GoodData
289
298
  #
290
299
  # @return [Array<GoodData::ProjectRole>] Array of project roles
291
300
  def roles
301
+ # TODO: Implement getting roles in project and cache them there
302
+ # See: https://jira.intgdc.com/browse/TMA-112
292
303
  roles_link = GoodData::Helpers.get_path(@json, %w(user links roles))
293
304
  return unless roles_link
294
305
  tmp = client.get roles_link
@@ -81,7 +81,7 @@ module GoodData
81
81
  tab = options[:tab] || ''
82
82
 
83
83
  req_uri = "/gdc/projects/#{project.pid}/clientexport"
84
- x = client.post(req_uri, 'clientExport' => { 'url' => "#{client.connection.server_url}/dashboard.html#project=#{GoodData.project.uri}&dashboard=#{uri}&tab=#{tab}&export=1", 'name' => title })
84
+ x = client.post(req_uri, 'clientExport' => { 'url' => "#{client.connection.server_url}/dashboard.html#project=#{project.uri}&dashboard=#{uri}&tab=#{tab}&export=1", 'name' => title })
85
85
  client.poll_on_code(x['asyncTask']['link']['poll'], options.merge(process: false))
86
86
  end
87
87
 
@@ -16,8 +16,7 @@ module GoodData
16
16
  # @param [String] value value of an label you are looking for
17
17
  # @return [String]
18
18
  def find_value_uri(value)
19
- escaped_value = CGI.escape(value)
20
- results = client.post("#{uri}/validElements?limit=1&offset=0&order=asc&filter=#{escaped_value}", 'validElementsRequest' => {})
19
+ results = get_valid_elements(filter: value)
21
20
  items = results['validElements']['items']
22
21
  if items.empty?
23
22
  fail(AttributeElementNotFound, value)
@@ -41,6 +40,36 @@ module GoodData
41
40
  end
42
41
  end
43
42
 
43
+ # Gets valid elements using /validElements? API
44
+ # @return [Array] Results
45
+ def get_valid_elements(url_or_params = {}, request_payload = {})
46
+ final_url = url_or_params
47
+
48
+ if url_or_params.is_a?(Hash)
49
+ default_params = {
50
+ limit: 1,
51
+ offset: 0,
52
+ order: 'asc'
53
+ }
54
+ params = default_params.merge(url_or_params).map { |x, v| "#{x}=#{CGI.escape(v.to_s)}" }.reduce { |a, e| "#{a}&#{e}" }
55
+ final_url = "#{uri}/validElements?#{params}"
56
+ end
57
+
58
+ results = client.post(final_url, 'validElementsRequest' => request_payload)
59
+
60
+ # Implementation of polling is based on
61
+ # https://opengrok.intgdc.com/source/xref/gdc-backend/src/test/java/com/gooddata/service/dao/ValidElementsDaoTest.java
62
+ status_url = results['uri']
63
+ if status_url
64
+ results = client.poll_on_response(status_url) do |body|
65
+ status = body['taskState'] && body['taskState']['status']
66
+ status == 'RUNNING' || status == 'PREPARED'
67
+ end
68
+ end
69
+
70
+ results
71
+ end
72
+
44
73
  # Finds if a label has an attribute element for given value.
45
74
  # @param [String] value value of an label you are looking for
46
75
  # @return [Boolean]
@@ -56,22 +85,11 @@ module GoodData
56
85
  # @option options [Number] :limit limits the number of values to certain number. Default is 100
57
86
  # @return [Array]
58
87
  def values(options = {})
59
- client = client(options)
60
88
  Enumerator.new do |y|
61
89
  offset = options[:offset] || 0
62
90
  page_limit = options[:limit] || 100
63
91
  loop do
64
- results = client.post("#{uri}/validElements?limit=#{page_limit}&offset=#{offset}&order=asc", 'validElementsRequest' => {})
65
-
66
- # Implementation of polling is based on
67
- # https://opengrok.intgdc.com/source/xref/gdc-backend/src/test/java/com/gooddata/service/dao/ValidElementsDaoTest.java
68
- status_url = results['uri']
69
- if status_url
70
- results = client.poll_on_response(status_url) do |body|
71
- status = body['taskState']['status']
72
- status == 'RUNNING' || status == 'PREPARED'
73
- end
74
- end
92
+ results = get_valid_elements(limit: page_limit, offset: offset)
75
93
 
76
94
  elements = results['validElements']
77
95
  elements['items'].map do |el|
@@ -88,7 +106,7 @@ module GoodData
88
106
  end
89
107
 
90
108
  def values_count
91
- results = client.post("#{uri}/validElements?limit=1&offset=0&order=asc", 'validElementsRequest' => {})
109
+ results = get_valid_elements
92
110
  count = GoodData::Helpers.get_path(results, %w(validElements paging total))
93
111
  count && count.to_i
94
112
  end
@@ -6,6 +6,7 @@
6
6
 
7
7
  require 'pry'
8
8
  require 'zip'
9
+ require 'uri'
9
10
 
10
11
  require_relative '../helpers/global_helpers'
11
12
  require_relative '../rest/resource'
@@ -13,6 +14,8 @@ require_relative '../rest/resource'
13
14
  require_relative 'execution_detail'
14
15
  require_relative 'schedule'
15
16
 
17
+ APP_STORE_URL ||= 'https://github.com/gooddata/app_store'
18
+
16
19
  module GoodData
17
20
  class Process < Rest::Resource
18
21
  attr_reader :data
@@ -91,6 +94,8 @@ module GoodData
91
94
  def deploy(path, options = { :client => GoodData.client, :project => GoodData.project })
92
95
  client, project = GoodData.get_client_and_project(options)
93
96
 
97
+ return deploy_brick(path, options) if path.to_s.start_with?(APP_STORE_URL)
98
+
94
99
  path = Pathname(path) || fail('Path is not specified')
95
100
  files_to_exclude = options[:files_to_exclude].nil? ? [] : options[:files_to_exclude].map { |pname| Pathname(pname) }
96
101
  process_id = options[:process_id]
@@ -122,6 +127,44 @@ module GoodData
122
127
  process
123
128
  end
124
129
 
130
+ def deploy_brick(path, options = { :client => GoodData.client, :project => GoodData.project })
131
+ client, project = GoodData.get_client_and_project(options)
132
+
133
+ brick_uri_parts = URI(path).path.split('/')
134
+ ref = brick_uri_parts[4]
135
+ brick_name = brick_uri_parts.last
136
+ brick_path = brick_uri_parts[5..-1].join('/')
137
+
138
+ Dir.mktmpdir do |dir|
139
+ Dir.chdir(dir) do
140
+ `git clone #{APP_STORE_URL}`
141
+ end
142
+
143
+ Dir.chdir(File.join(dir, 'app_store')) do
144
+ if ref
145
+ `git checkout #{ref}`
146
+
147
+ fail 'Wrong branch or tag specified!' if $CHILD_STATUS.to_i != 0
148
+ end
149
+
150
+ opts = {
151
+ :client => client,
152
+ :project => project,
153
+ :name => brick_name,
154
+ :type => 'RUBY'
155
+ }
156
+
157
+ full_brick_path = File.join(dir, 'app_store', brick_path)
158
+
159
+ unless File.exist?(full_brick_path)
160
+ fail "Invalid brick name specified - '#{brick_name}'"
161
+ end
162
+
163
+ return deploy(full_brick_path, opts)
164
+ end
165
+ end
166
+ end
167
+
125
168
  # ----------------------------- Private Stuff
126
169
 
127
170
  private
@@ -145,10 +188,13 @@ module GoodData
145
188
  with_zip(opts) do |zipfile|
146
189
  zipfile.add(File.basename(path), path)
147
190
  end
148
-
149
191
  elsif !path.directory?
150
- client.upload_to_user_webdav(path, opts)
151
- path
192
+ # this branch expects a zipped file. Since the filename on webdav is by default
193
+ # equal to the filename of a local file. I happened often that the name clashed
194
+ # if ran in parallel. Create a randomized name to mitigate that
195
+ randomized_filename = (0...16).map { (65 + rand(26)).chr }.join
196
+ client.upload_to_user_webdav(path, { filename: randomized_filename }.merge(opts))
197
+ randomized_filename
152
198
  else
153
199
  with_zip(opts) do |zipfile|
154
200
  files_to_upload = Dir[File.join(path, '**', '**')].reject { |f| files_to_exclude.include?(Pathname(path) + f) }
@@ -226,6 +226,7 @@ module GoodData
226
226
  # Get full name
227
227
  #
228
228
  # @return String Full Name
229
+ # NOTE: This can be tricky to implement correctly for i18n
229
230
  def full_name
230
231
  "#{first_name} #{last_name}"
231
232
  end
@@ -21,6 +21,7 @@ require_relative '../mixins/contributor'
21
21
  require_relative '../mixins/rest_resource'
22
22
  require_relative '../mixins/uri_getter'
23
23
 
24
+ require_relative 'membership'
24
25
  require_relative 'process'
25
26
  require_relative 'project_role'
26
27
  require_relative 'blueprint/blueprint'
@@ -91,6 +92,17 @@ module GoodData
91
92
  end
92
93
  end
93
94
 
95
+ # Clones project along with etl and schedules
96
+ #
97
+ # @param project [Project] Project to be cloned from
98
+ # @param [options] Options that are passed into project.clone
99
+ # @return [GoodData::Project] New cloned project
100
+ def clone_with_etl(project, options = {})
101
+ a_clone = project.clone(options)
102
+ GoodData::Project.transfer_etl(project.client, project, a_clone)
103
+ a_clone
104
+ end
105
+
94
106
  def create_object(data = {})
95
107
  c = client(data)
96
108
  new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
@@ -172,6 +184,131 @@ module GoodData
172
184
  }
173
185
  }
174
186
  end
187
+
188
+ # Clones project along with etl and schedules.
189
+ #
190
+ # @param client [GoodData::Rest::Client] GoodData client to be used for connection
191
+ # @param from_project [GoodData::Project | GoodData::Segment | GoodData:Client | String] Object to be cloned from. Can be either segment in which case we take the master, client in which case we take its project, string in which case we treat is as an project object or directly project
192
+ def transfer_etl(client, from_project, to_project)
193
+ from_project = case from_project
194
+ when GoodData::Client
195
+ from_project.project
196
+ when GoodData::Segment
197
+ from_project.master_project
198
+ else
199
+ client.projects(from_project)
200
+ end
201
+
202
+ to_project = case to_project
203
+ when GoodData::Client
204
+ to_project.project
205
+ when GoodData::Segment
206
+ to_project.master_project
207
+ else
208
+ client.projects(to_project)
209
+ end
210
+
211
+ from_project.processes.each do |process|
212
+ Dir.mktmpdir('etl_transfer') do |dir|
213
+ dir = Pathname(dir)
214
+ filename = dir + 'process.zip'
215
+ File.open(filename, 'w') do |f|
216
+ f << process.download
217
+ end
218
+ to_process = to_project.processes.find { |p| p.name == process.name }
219
+ to_process ? to_process.deploy(filename, type: process.type, name: process.name) : to_project.deploy_process(filename, type: process.type, name: process.name)
220
+ end
221
+ end
222
+ res = (from_project.processes + to_project.processes).map { |p| [p, p.name, p.type] }
223
+ res.group_by { |x| [x[1], x[2]] }
224
+ .select { |_, procs| procs.length == 1 }
225
+ .flat_map { |_, procs| procs.select { |p| p[0].project.pid == to_project.pid }.map { |p| p[0] } }
226
+ .peach(&:delete)
227
+ transfer_schedules(from_project, to_project)
228
+ end
229
+
230
+ # Clones project along with etl and schedules.
231
+ #
232
+ # @param client [GoodData::Rest::Client] GoodData client to be used for connection
233
+ # @param from_project [GoodData::Project | GoodData::Segment | GoodData:Client | String] Object to be cloned from. Can be either segment in which case we take the master, client in which case we take its project, string in which case we treat is as an project object or directly project
234
+ def transfer_schedules(from_project, to_project)
235
+ cache = to_project.processes.sort_by(&:name).zip(from_project.processes.sort_by(&:name)).flat_map { |remote, local| local.schedules.map { |schedule| [remote, local, schedule] } }
236
+
237
+ remote_schedules = to_project.schedules
238
+ remote_stuff = remote_schedules.map do |s|
239
+ v = s.to_hash
240
+ after_schedule = remote_schedules.find { |s2| s.trigger_id == s2.obj_id }
241
+ v[:after] = s.trigger_id && after_schedule && after_schedule.name
242
+ v[:remote_schedule] = s
243
+ v[:params] = v[:params].except("EXECUTABLE", "PROCESS_ID")
244
+ v.compact
245
+ end
246
+
247
+ local_schedules = from_project.schedules
248
+ local_stuff = local_schedules.map do |s|
249
+ v = s.to_hash
250
+ after_schedule = local_schedules.find { |s2| s.trigger_id == s2.obj_id }
251
+ v[:after] = s.trigger_id && after_schedule && after_schedule.name
252
+ v[:remote_schedule] = s
253
+ v[:params] = v[:params].except("EXECUTABLE", "PROCESS_ID")
254
+ v.compact
255
+ end
256
+
257
+ diff = GoodData::Helpers.diff(remote_stuff, local_stuff, key: :name, fields: [:name, :cron, :after, :params, :hidden_params, :reschedule])
258
+ stack = diff[:added].map { |x| [:added, x] } + diff[:changed].map { |x| [:changed, x] }
259
+ schedule_cache = remote_schedules.reduce({}) do |a, e|
260
+ a[e.name] = e
261
+ a
262
+ end
263
+ messages = []
264
+ loop do
265
+ break if stack.empty?
266
+ state, changed_schedule = stack.shift
267
+ if state == :added
268
+ schedule_spec = changed_schedule
269
+ if schedule_spec[:after] && !schedule_cache[schedule_spec[:after]]
270
+ stack << [state, schedule_spec]
271
+ next
272
+ end
273
+ remote_process, process_spec = cache.find { |_remote, _local, schedule| schedule.name == schedule_spec[:name] }
274
+ messages << { message: "Creating schedule #{schedule_spec[:name]} for process #{remote_process.name}" }
275
+ executable = schedule_spec[:executable] || (process_spec["process_type"] == 'ruby' ? 'main.rb' : 'main.grf')
276
+ params = {
277
+ params: schedule_spec[:params].merge('PROJECT_ID' => to_project.pid),
278
+ hidden_params: schedule_spec[:hidden_params],
279
+ name: schedule_spec[:name],
280
+ reschedule: schedule_spec[:reschedule]
281
+ }
282
+ created_schedule = remote_process.create_schedule(schedule_spec[:cron] || schedule_cache[schedule_spec[:after]], executable, params)
283
+ schedule_cache[created_schedule.name] = created_schedule
284
+ else
285
+ schedule_spec = changed_schedule[:new_obj]
286
+ if schedule_spec[:after] && !schedule_cache[schedule_spec[:after]]
287
+ stack << [state, schedule_spec]
288
+ next
289
+ end
290
+ remote_process, process_spec = cache.find { |i| i[2].name == schedule_spec[:name] }
291
+ schedule = changed_schedule[:old_obj][:remote_schedule]
292
+ messages << { message: "Updating schedule #{schedule_spec[:name]} for process #{remote_process.name}" }
293
+ schedule.params = (schedule_spec[:params] || {})
294
+ schedule.cron = schedule_spec[:cron] if schedule_spec[:cron]
295
+ schedule.after = schedule_cache[schedule_spec[:after]] if schedule_spec[:after]
296
+ schedule.hidden_params = schedule_spec[:hidden_params] || {}
297
+ schedule.executable = schedule_spec[:executable] || (process_spec["process_type"] == 'ruby' ? 'main.rb' : 'main.grf')
298
+ schedule.reschedule = schedule_spec[:reschedule]
299
+ schedule.name = schedule_spec[:name]
300
+ schedule.save
301
+ schedule_cache[schedule.name] = schedule
302
+ end
303
+ end
304
+
305
+ diff[:removed].each do |removed_schedule|
306
+ messages << { message: "Removing schedule #{removed_schedule[:name]}" }
307
+ removed_schedule[:remote_schedule].delete
308
+ end
309
+ messages
310
+ # messages.map {|m| m.merge({custom_project_id: custom_project_id})}
311
+ end
175
312
  end
176
313
 
177
314
  def add_dashboard(dashboard)
@@ -846,13 +983,20 @@ module GoodData
846
983
  if projects.is_a?(Array)
847
984
  projects.each_slice(batch_size).flat_map do |batch|
848
985
  batch.pmap do |proj|
849
- target_project = client.projects(proj)
850
986
  begin
987
+ target_project = client.projects(proj)
851
988
  target_project.objects_import(token, options)
852
989
  {
853
990
  project: target_project,
854
991
  result: true
855
992
  }
993
+ rescue RestClient::Exception => e
994
+ {
995
+ project: proj,
996
+ exception: e,
997
+ result: false,
998
+ reason: GoodData::Helpers.interpolate_error_message(MultiJson.load(e.response))
999
+ }
856
1000
  rescue GoodData::ObjectsImportError => e
857
1001
  {
858
1002
  project: target_project,
@@ -122,9 +122,26 @@ module GoodData
122
122
  saved? ? client.delete(uri) : nil
123
123
  end
124
124
 
125
+ # Is schedule enabled?
126
+ #
127
+ # @return [GoodData::Schedule]
128
+ def disable
129
+ @json['schedule']['state'] = 'DISABLED'
130
+ @dirty = true
131
+ self
132
+ end
133
+
125
134
  # Is schedule enabled?
126
135
  #
127
136
  # @return [Boolean]
137
+ def disable!
138
+ disable
139
+ save
140
+ end
141
+
142
+ # Is schedule disabled?
143
+ #
144
+ # @return [Boolean]
128
145
  def disabled?
129
146
  state == 'DISABLED'
130
147
  end
@@ -136,7 +153,7 @@ module GoodData
136
153
  !disabled?
137
154
  end
138
155
 
139
- # enables
156
+ # Enables the schedule
140
157
  #
141
158
  # @return [GoodData::Schedule]
142
159
  def enable
@@ -145,13 +162,12 @@ module GoodData
145
162
  self
146
163
  end
147
164
 
148
- # Is schedule enabled?
165
+ # Enables and saves the schedule
149
166
  #
150
167
  # @return [GoodData::Schedule]
151
- def disable
152
- @json['schedule']['state'] = 'DISABLED'
153
- @dirty = true
154
- self
168
+ def enable!
169
+ enable
170
+ save
155
171
  end
156
172
 
157
173
  # Executes schedule
@@ -116,6 +116,15 @@ module GoodData
116
116
  # Master project id getter for the Segment.
117
117
  #
118
118
  # @return [String] Project uri
119
+ def master_project_id
120
+ GoodData::Helpers.last_uri_part(master_project_uri)
121
+ end
122
+
123
+ alias_method :master_id, :master_project_id
124
+
125
+ # Master project uri getter for the Segment.
126
+ #
127
+ # @return [String] Project uri
119
128
  def master_project_uri
120
129
  data['masterProject']
121
130
  end
@@ -6,7 +6,7 @@
6
6
 
7
7
  # GoodData Module
8
8
  module GoodData
9
- VERSION = '0.6.25'
9
+ VERSION = '0.6.26'
10
10
 
11
11
  class << self
12
12
  # Version
@@ -13,19 +13,19 @@ module GoodData
13
13
  end
14
14
 
15
15
  module ProcessHelper
16
- set_const :PROCESS_ID, 'eb9032d6-766c-45d4-a446-9103985ef9b9'
16
+ set_const :PROCESS_ID, '93027bc3-c731-4788-a179-d83bd04aae35'
17
17
  set_const :DEPLOY_NAME, 'graph/graph.grf'
18
18
  end
19
19
 
20
20
  module ProjectHelper
21
- set_const :PROJECT_ID, 'fj6npa2wwl49vbzdbhk1doui3jqisexh'
21
+ set_const :PROJECT_ID, 'yz7e0iwh7gdih02dssf47rw4e096t7nb'
22
22
  set_const :PROJECT_URL, "/gdc/projects/#{PROJECT_ID}"
23
23
  set_const :PROJECT_TITLE, 'GoodTravis'
24
24
  set_const :PROJECT_SUMMARY, 'No summary'
25
25
  end
26
26
 
27
27
  module ScheduleHelper
28
- set_const :SCHEDULE_ID, '56bb4421e4b09a37d0ff0b70'
28
+ set_const :SCHEDULE_ID, '571024efe4b025350e321b85'
29
29
  end
30
30
  end
31
31
  end
@@ -38,7 +38,7 @@ describe GoodData::Client do
38
38
  end
39
39
 
40
40
  it 'Returns specific tenant when schedule ID passed' do
41
- client = @segment.clients(@segment_client.uri)
41
+ client = @segment.clients(@segment_client)
42
42
  expect(client).to be_an_instance_of(GoodData::Client)
43
43
  expect(client.uri).to eq @segment_client.uri
44
44
  end
@@ -58,7 +58,7 @@ describe GoodData::Client do
58
58
 
59
59
  it 'Deletes particular client' do
60
60
  expect(@segment.clients.count).to eq 1
61
- s = @segment.clients(@segment_client.uri)
61
+ s = @segment.clients(@segment_client)
62
62
  s.delete
63
63
  expect(@segment.clients.count).to eq 0
64
64
  @segment_client = nil
@@ -78,7 +78,7 @@ describe GoodData::Client do
78
78
 
79
79
  it 'Deletes particular client. Project is cleaned up as well' do
80
80
  expect(@segment.clients.count).to eq 1
81
- s = @segment.clients(@segment_client.uri)
81
+ s = @segment.clients(@segment_client)
82
82
  s.delete
83
83
  expect(@segment.clients.count).to eq 0
84
84
  expect(@client_project.reload!.state).to eq :deleted
@@ -86,7 +86,7 @@ describe GoodData::Client do
86
86
  end
87
87
 
88
88
  after(:all) do
89
- @segment_client && segment_client.delete
89
+ @segment_client && @segment_client.delete
90
90
  end
91
91
  end
92
92
 
@@ -102,7 +102,7 @@ describe GoodData::Client do
102
102
  other_client_project = @client.create_project(title: "client_#{@client_id} other project", auth_token: TOKEN)
103
103
  @segment_client.project = other_client_project
104
104
  @segment_client.save
105
- expect(@segment.clients('tenant_1').project_uri).to eq other_client_project.uri
105
+ expect(@segment.clients(@segment_client).project_uri).to eq other_client_project.uri
106
106
  ensure
107
107
  other_client_project && other_client_project.delete
108
108
  end
@@ -268,4 +268,31 @@ describe "Full process and schedule exercise", :constraint => 'slow' do
268
268
  process1 && process1.delete
269
269
  end
270
270
  end
271
+
272
+ it 'should be able to deploy from app_store' do
273
+ begin
274
+ process = @project.deploy_process('https://github.com/gooddata/app_store/tree/sfdc_downloader_brick-v0.0.4/apps/ads_integrator_brick')
275
+ expect(process.class).to eql(GoodData::Process)
276
+ ensure
277
+ process.delete
278
+ end
279
+ end
280
+
281
+
282
+ it 'should be able to clone with etl' do
283
+ begin
284
+ # Deploy two schedules
285
+ process = @project.processes.first
286
+ schedule_first = process.create_schedule('0 15 27 7 *', process.executables.first)
287
+ schedule_second = process.create_schedule('0 15 27 8 *', process.executables.first)
288
+ cloned_project = GoodData::Project.clone_with_etl(@project)
289
+ a = @project.processes.flat_map {|p| p.schedules.map {|s| [p.name, s.name]}}
290
+ b = cloned_project.processes.flat_map {|p| p.schedules.map {|s| [p.name, s.name]}}
291
+ expect(a).to eq b
292
+ ensure
293
+ cloned_project && cloned_project.delete
294
+ schedule_first && schedule_first.delete
295
+ schedule_second && schedule_second.delete
296
+ end
297
+ end
271
298
  end
@@ -24,7 +24,6 @@ describe GoodData::Schedule do
24
24
  @client = ConnectionHelper.create_default_connection
25
25
 
26
26
  @project = ProjectHelper.get_default_project(:client => @client)
27
- @project_executable = 'graph/graph.grf'
28
27
  @test_cron = '0 15 27 7 *'
29
28
  @test_data = {
30
29
  :timezone => 'UTC',
@@ -87,7 +86,7 @@ describe GoodData::Schedule do
87
86
  describe '#create' do
88
87
  it 'Creates new schedule if mandatory params passed' do
89
88
  begin
90
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
89
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
91
90
  expect(schedule).to be_truthy
92
91
  ensure
93
92
  schedule && schedule.delete
@@ -96,7 +95,7 @@ describe GoodData::Schedule do
96
95
 
97
96
  it 'Creates new schedule if mandatory params passed and optional params are present' do
98
97
  begin
99
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
98
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
100
99
  expect(schedule).to be_truthy
101
100
  ensure
102
101
  schedule && schedule.delete
@@ -107,7 +106,7 @@ describe GoodData::Schedule do
107
106
  schedule = nil
108
107
  begin
109
108
  expect {
110
- schedule = @project.create_schedule(nil, @test_cron, @project_executable, @test_data)
109
+ schedule = @project.create_schedule(nil, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
111
110
  }.to raise_error 'Process ID has to be provided'
112
111
  ensure
113
112
  schedule && schedule.delete
@@ -131,7 +130,7 @@ describe GoodData::Schedule do
131
130
  schedule = nil
132
131
  begin
133
132
  expect {
134
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, nil, @project_executable, data)
133
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, nil, ProcessHelper::DEPLOY_NAME, data)
135
134
  }.to raise_error 'Trigger schedule has to be provided'
136
135
  ensure
137
136
  schedule && schedule.delete
@@ -140,7 +139,7 @@ describe GoodData::Schedule do
140
139
 
141
140
  it 'Throws exception when no timezone specified' do
142
141
  data = GoodData::Helpers.deep_dup(@test_data)
143
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, data)
142
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, data)
144
143
  schedule.timezone = nil
145
144
  begin
146
145
  expect {
@@ -155,7 +154,7 @@ describe GoodData::Schedule do
155
154
  schedule = nil
156
155
  data = GoodData::Helpers.deep_dup(@test_data)
157
156
  begin
158
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, data)
157
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, data)
159
158
  schedule.type = nil
160
159
  expect {
161
160
  schedule.save
@@ -169,7 +168,7 @@ describe GoodData::Schedule do
169
168
  describe '#cron' do
170
169
  it 'Should return cron as string' do
171
170
  begin
172
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
171
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
173
172
  res = schedule.cron
174
173
  res.should_not be_nil
175
174
  res.should_not be_empty
@@ -186,7 +185,7 @@ describe GoodData::Schedule do
186
185
  test_cron = '2 2 2 2 *'
187
186
 
188
187
  begin
189
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
188
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
190
189
  schedule.cron = test_cron
191
190
  expect(schedule.cron).to eq(test_cron)
192
191
  expect(schedule.dirty).to eq(true)
@@ -199,7 +198,7 @@ describe GoodData::Schedule do
199
198
  describe '#executable' do
200
199
  it 'Should return executable as string' do
201
200
  begin
202
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
201
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
203
202
  res = schedule.executable
204
203
  res.should_not be_nil
205
204
  res.should_not be_empty
@@ -215,7 +214,7 @@ describe GoodData::Schedule do
215
214
  test_executable = 'this/is/test.grf'
216
215
 
217
216
  begin
218
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
217
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
219
218
  schedule.executable = test_executable
220
219
  expect(schedule.executable).to eq(test_executable)
221
220
  expect(schedule.dirty).to eq(true)
@@ -260,7 +259,7 @@ describe GoodData::Schedule do
260
259
  describe '#execution_url' do
261
260
  it 'Should return execution URL as string' do
262
261
  begin
263
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
262
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
264
263
  res = schedule.execution_url
265
264
  res.should_not be_nil
266
265
  res.should_not be_empty
@@ -274,7 +273,7 @@ describe GoodData::Schedule do
274
273
  describe '#type' do
275
274
  it 'Should return execution type as string' do
276
275
  begin
277
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
276
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
278
277
  res = schedule.type
279
278
  res.should_not be_nil
280
279
  res.should be_a_kind_of(String)
@@ -287,7 +286,7 @@ describe GoodData::Schedule do
287
286
  describe '#hidden_params' do
288
287
  it 'Should return execution hidden_params as hash' do
289
288
  begin
290
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
289
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
291
290
  res = schedule.hidden_params
292
291
  res.should_not be_nil
293
292
  res.should be_a_kind_of(Hash)
@@ -300,7 +299,7 @@ describe GoodData::Schedule do
300
299
  describe '#hidden_params=' do
301
300
  it 'Assigns the hidden params and marks the object dirty' do
302
301
  begin
303
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
302
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
304
303
  old_params = schedule.hidden_params
305
304
 
306
305
  test_params = {
@@ -319,7 +318,7 @@ describe GoodData::Schedule do
319
318
  describe '#set_hidden_parameter' do
320
319
  it 'Assigns the hidden parameter and marks the object dirty' do
321
320
  begin
322
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
321
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
323
322
  old_params = schedule.hidden_params
324
323
 
325
324
  test_parameter = {'test_parameter' => 'just_testing' }
@@ -335,7 +334,7 @@ describe GoodData::Schedule do
335
334
  describe '#set_parameter' do
336
335
  it 'Assigns the hidden parameter and marks the object dirty' do
337
336
  begin
338
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
337
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
339
338
  old_params = schedule.params
340
339
 
341
340
  test_parameter = {'test_parameter' => 'just_testing' }
@@ -352,7 +351,7 @@ describe GoodData::Schedule do
352
351
  describe '#params' do
353
352
  it 'Should return execution params as hash' do
354
353
  begin
355
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
354
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
356
355
  res = schedule.params
357
356
  res.should_not be_nil
358
357
  res.should_not be_empty
@@ -366,7 +365,7 @@ describe GoodData::Schedule do
366
365
  describe '#params=' do
367
366
  it 'Assigns the params and marks the object dirty' do
368
367
  begin
369
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
368
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
370
369
  old_params = schedule.params
371
370
 
372
371
  test_params = {
@@ -387,7 +386,7 @@ describe GoodData::Schedule do
387
386
  describe '#process_id' do
388
387
  it 'Should return process id as string' do
389
388
  begin
390
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
389
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
391
390
  res = schedule.process_id
392
391
  res.should_not be_nil
393
392
  res.should_not be_empty
@@ -403,7 +402,7 @@ describe GoodData::Schedule do
403
402
  test_process_id = '1-2-3-4'
404
403
 
405
404
  begin
406
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
405
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
407
406
  schedule.process_id = test_process_id
408
407
  expect(schedule.process_id).to eq(test_process_id)
409
408
  expect(schedule.dirty).to eq(true)
@@ -416,7 +415,7 @@ describe GoodData::Schedule do
416
415
  describe '#save' do
417
416
  it 'Should save a schedule' do
418
417
  begin
419
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
418
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
420
419
  expect(@project.schedules(schedule.uri)).to eq schedule
421
420
  expect(@project.schedules).to include(schedule)
422
421
  ensure
@@ -428,7 +427,7 @@ describe GoodData::Schedule do
428
427
  describe '#state' do
429
428
  it 'Should return execution state as string' do
430
429
  begin
431
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
430
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
432
431
  res = schedule.state
433
432
  res.should_not be_nil
434
433
  res.should_not be_empty
@@ -442,7 +441,7 @@ describe GoodData::Schedule do
442
441
  describe '#type' do
443
442
  it 'Should return execution type as string' do
444
443
  begin
445
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
444
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
446
445
  res = schedule.type
447
446
  res.should_not be_nil
448
447
  res.should_not be_empty
@@ -458,7 +457,7 @@ describe GoodData::Schedule do
458
457
  test_type = 'TEST'
459
458
 
460
459
  begin
461
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
460
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
462
461
  schedule.type = test_type
463
462
  expect(schedule.type).to eq(test_type)
464
463
  expect(schedule.dirty).to eq(true)
@@ -471,7 +470,7 @@ describe GoodData::Schedule do
471
470
  describe '#timezone' do
472
471
  it 'Should return timezone as string' do
473
472
  begin
474
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
473
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
475
474
  res = schedule.timezone
476
475
  res.should_not be_nil
477
476
  res.should_not be_empty
@@ -487,7 +486,7 @@ describe GoodData::Schedule do
487
486
  test_timezone = 'PST'
488
487
 
489
488
  begin
490
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
489
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data)
491
490
  schedule.timezone = test_timezone
492
491
  expect(schedule.timezone).to eq(test_timezone)
493
492
  expect(schedule.dirty).to eq(true)
@@ -500,7 +499,7 @@ describe GoodData::Schedule do
500
499
  describe '#reschedule' do
501
500
  it 'Should return reschedule as integer' do
502
501
  begin
503
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
502
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
504
503
  res = schedule.reschedule
505
504
  res.should_not be_nil
506
505
  res.should be_a_kind_of(Integer)
@@ -515,7 +514,7 @@ describe GoodData::Schedule do
515
514
  test_reschedule = 45
516
515
 
517
516
  begin
518
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
517
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
519
518
  schedule.reschedule = test_reschedule
520
519
  expect(schedule.reschedule).to eq(test_reschedule)
521
520
  expect(schedule.dirty).to eq(true)
@@ -528,7 +527,7 @@ describe GoodData::Schedule do
528
527
  describe '#executions' do
529
528
  it 'Returns executions' do
530
529
  begin
531
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
530
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
532
531
  expect(schedule.executions.to_a).to be_empty
533
532
  schedule.execute
534
533
  ensure
@@ -540,7 +539,7 @@ describe GoodData::Schedule do
540
539
  describe '#name' do
541
540
  it 'should be able to get name of the schedule.' do
542
541
  begin
543
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
542
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
544
543
  expect(schedule.name).to eq 'graph.grf'
545
544
  ensure
546
545
  schedule && schedule.delete
@@ -549,7 +548,7 @@ describe GoodData::Schedule do
549
548
 
550
549
  it 'should be able to return your name if specified during creation.' do
551
550
  begin
552
- schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param.merge(name: 'My schedule name'))
551
+ schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param.merge(name: 'My schedule name'))
553
552
  expect(schedule.name).to eq 'My schedule name'
554
553
  ensure
555
554
  schedule && schedule.delete
@@ -561,7 +560,7 @@ describe GoodData::Schedule do
561
560
  it 'should be able to set trigger_id of the schedule.' do
562
561
  begin
563
562
  process = @project.processes(ProcessHelper::PROCESS_ID)
564
- schedule = process.create_schedule(@test_cron, @project_executable, @test_data_with_optional_param)
563
+ schedule = process.create_schedule(@test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
565
564
  expect(schedule.dirty).to be_falsey
566
565
  schedule.trigger_id = 'some_other_id'
567
566
  expect(schedule.dirty).to be_truthy
@@ -575,7 +574,7 @@ describe GoodData::Schedule do
575
574
  it 'should be able to set trigger_id of the schedule.' do
576
575
  begin
577
576
  process = @project.processes(ProcessHelper::PROCESS_ID)
578
- schedule = process.create_schedule(@test_cron, @project_executable, @test_data_with_optional_param)
577
+ schedule = process.create_schedule(@test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
579
578
  expect(schedule.dirty).to be_falsey
580
579
  schedule.trigger_id = 'some_other_id'
581
580
  expect(schedule.dirty).to be_truthy
@@ -589,7 +588,7 @@ describe GoodData::Schedule do
589
588
  it 'should be able to set name of the schedule.' do
590
589
  begin
591
590
  process = @project.processes(ProcessHelper::PROCESS_ID)
592
- schedule = process.create_schedule(@test_cron, @project_executable, @test_data_with_optional_param)
591
+ schedule = process.create_schedule(@test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param)
593
592
  expect(schedule.name).to eq 'graph.grf'
594
593
  schedule.name = 'MY NAME'
595
594
  schedule.save
@@ -605,7 +604,7 @@ describe GoodData::Schedule do
605
604
  it 'should preserve the hidden parmeters.' do
606
605
  begin
607
606
  process = @project.processes(ProcessHelper::PROCESS_ID)
608
- schedule = process.create_schedule(@test_cron, @project_executable, @test_data_with_optional_param.merge({hidden_params: {
607
+ schedule = process.create_schedule(@test_cron, ProcessHelper::DEPLOY_NAME, @test_data_with_optional_param.merge({hidden_params: {
609
608
  "a" => {
610
609
  "b" => "c"
611
610
  }
@@ -62,7 +62,7 @@ describe GoodData::Profile do
62
62
  end
63
63
 
64
64
  after(:all) do
65
- @client.disconnect
65
+ @client && @client.disconnect
66
66
  end
67
67
 
68
68
  describe '#[]' do
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: 0.6.25
4
+ version: 0.6.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Kolesnikov
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-02-26 00:00:00.000000000 Z
14
+ date: 2016-04-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.10.6
22
+ version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.10.6
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: debase
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -670,6 +670,7 @@ files:
670
670
  - lib/gooddata/bricks/utils.rb
671
671
  - lib/gooddata/cli/cli.rb
672
672
  - lib/gooddata/cli/commands/auth_cmd.rb
673
+ - lib/gooddata/cli/commands/domain_cmd.rb
673
674
  - lib/gooddata/cli/commands/project_cmd.rb
674
675
  - lib/gooddata/cli/hooks.rb
675
676
  - lib/gooddata/cli/shared.rb