td-client 1.0.3 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/td/client.rb +27 -37
- data/lib/td/client/api.rb +16 -6
- data/lib/td/client/api/export.rb +1 -1
- data/lib/td/client/api/import.rb +1 -3
- data/lib/td/client/api/job.rb +10 -3
- data/lib/td/client/api/schedule.rb +1 -1
- data/lib/td/client/api/table.rb +26 -5
- data/lib/td/client/api_error.rb +32 -8
- data/lib/td/client/model.rb +23 -11
- data/lib/td/client/version.rb +1 -1
- data/spec/spec_helper.rb +1 -5
- data/spec/td/client/api_ssl_connection_spec.rb +14 -13
- data/spec/td/client/import_api_spec.rb +14 -14
- data/spec/td/client/job_api_spec.rb +18 -1
- data/spec/td/client/model_job_spec.rb +56 -5
- data/spec/td/client/table_api_spec.rb +117 -0
- metadata +36 -25
- data/lib/td/client/api/access_control.rb +0 -74
- data/spec/td/client/access_control_api_spec.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8650b4fe6267d1edb91dad045ac0b31f77d0d0e37d776ea5433ec88debfe4b81
|
4
|
+
data.tar.gz: baf35bbd09b187c8f76ee48f68328f23ac09721ddb31641154a97900dc4ac93b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 643dc4c3d7ec6e5e73b506f3b18750a7aeaf73e915890c68ccd7b590f8d539a1fb047f5adbb4652bb0a732f2e8466658be112384d9d57aae1cb72b902b8a4b46
|
7
|
+
data.tar.gz: fbf3228a704dd954299becd06462920f72934674d8cae49ba1db91d169441fe4a079348e33ec8f2e3b08c986b5383fbf476f7161de8711a3677583da1b4b3169
|
data/lib/td/client.rb
CHANGED
@@ -88,9 +88,14 @@ class Client
|
|
88
88
|
raise NotFoundError, "Database '#{db_name}' does not exist"
|
89
89
|
end
|
90
90
|
|
91
|
+
# @param [String] db
|
92
|
+
# @param [String] table
|
93
|
+
# @option params [Fixnum] :expire_days days to expire table
|
94
|
+
# @option params [Boolean] :include_v (true) include v column on Hive
|
95
|
+
# @option params [Boolean] :detect_schema (true) detect schema on import
|
91
96
|
# @return [true]
|
92
|
-
def create_log_table(db_name, table_name)
|
93
|
-
@api.create_log_table(db_name, table_name)
|
97
|
+
def create_log_table(db_name, table_name, params={})
|
98
|
+
@api.create_log_table(db_name, table_name, params)
|
94
99
|
end
|
95
100
|
|
96
101
|
# Swap table names
|
@@ -111,6 +116,16 @@ class Client
|
|
111
116
|
@api.update_schema(db_name, table_name, schema.to_json)
|
112
117
|
end
|
113
118
|
|
119
|
+
# @param [String] db
|
120
|
+
# @param [String] table
|
121
|
+
# @option params [Fixnum] :expire_days days to expire table
|
122
|
+
# @option params [Boolean] :include_v (true) include v column on Hive
|
123
|
+
# @option params [Boolean] :detect_schema (true) detect schema on import
|
124
|
+
# @return [true]
|
125
|
+
def update_table(db_name, table_name, params={})
|
126
|
+
@api.update_table(db_name, table_name, params)
|
127
|
+
end
|
128
|
+
|
114
129
|
# @param [String] db_name
|
115
130
|
# @param [String] table_name
|
116
131
|
# @param [Fixnum] expire_days
|
@@ -130,10 +145,10 @@ class Client
|
|
130
145
|
# @return [Array] Tables
|
131
146
|
def tables(db_name)
|
132
147
|
m = @api.list_tables(db_name)
|
133
|
-
m.map {|table_name, (type, schema, count, created_at, updated_at, estimated_storage_size, last_import, last_log_timestamp, expire_days)|
|
148
|
+
m.map {|table_name, (type, schema, count, created_at, updated_at, estimated_storage_size, last_import, last_log_timestamp, expire_days, include_v)|
|
134
149
|
schema = Schema.new.from_json(schema)
|
135
150
|
Table.new(self, db_name, table_name, type, schema, count, created_at, updated_at,
|
136
|
-
estimated_storage_size, last_import, last_log_timestamp, expire_days)
|
151
|
+
estimated_storage_size, last_import, last_log_timestamp, expire_days, include_v)
|
137
152
|
}
|
138
153
|
end
|
139
154
|
|
@@ -158,6 +173,14 @@ class Client
|
|
158
173
|
@api.tail(db_name, table_name, count, to, from, &block)
|
159
174
|
end
|
160
175
|
|
176
|
+
# @param [String] db_name
|
177
|
+
# @param [String] table_name
|
178
|
+
# @param [String] new_db_name
|
179
|
+
# @return [true]
|
180
|
+
def change_database(db_name, table_name, new_db_name)
|
181
|
+
@api.change_database(db_name, table_name, new_db_name)
|
182
|
+
end
|
183
|
+
|
161
184
|
# @param [String] db_name
|
162
185
|
# @param [String] q
|
163
186
|
# @param [String] result_url
|
@@ -519,39 +542,6 @@ class Client
|
|
519
542
|
@api.change_my_password(old_password, password)
|
520
543
|
end
|
521
544
|
|
522
|
-
# @return [Array<AccessControl>]
|
523
|
-
def access_controls
|
524
|
-
list = @api.list_access_controls
|
525
|
-
list.map {|subject,action,scope,grant_option|
|
526
|
-
AccessControl.new(self, subject, action, scope, grant_option)
|
527
|
-
}
|
528
|
-
end
|
529
|
-
|
530
|
-
# @param [String] subject
|
531
|
-
# @param [String] action
|
532
|
-
# @param [String] scope
|
533
|
-
# @param [Array] grant_option
|
534
|
-
# @return [true]
|
535
|
-
def grant_access_control(subject, action, scope, grant_option)
|
536
|
-
@api.grant_access_control(subject, action, scope, grant_option)
|
537
|
-
end
|
538
|
-
|
539
|
-
# @param [String] subject
|
540
|
-
# @param [String] action
|
541
|
-
# @param [String] scope
|
542
|
-
# @return [true]
|
543
|
-
def revoke_access_control(subject, action, scope)
|
544
|
-
@api.revoke_access_control(subject, action, scope)
|
545
|
-
end
|
546
|
-
|
547
|
-
# @param [String] user
|
548
|
-
# @param [String] action
|
549
|
-
# @param [String] scope
|
550
|
-
# @return [Array]
|
551
|
-
def test_access_control(user, action, scope)
|
552
|
-
@api.test_access_control(user, action, scope)
|
553
|
-
end
|
554
|
-
|
555
545
|
# => BulkLoad::Job
|
556
546
|
def bulk_load_guess(job)
|
557
547
|
@api.bulk_load_guess(job)
|
data/lib/td/client/api.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'td/client/api_error'
|
2
2
|
require 'td/client/version'
|
3
|
-
require 'td/client/api/access_control'
|
4
3
|
require 'td/client/api/account'
|
5
4
|
require 'td/client/api/bulk_import'
|
6
5
|
require 'td/client/api/bulk_load'
|
@@ -21,7 +20,6 @@ require 'td/core_ext/openssl/ssl/sslcontext/set_params'
|
|
21
20
|
module TreasureData
|
22
21
|
|
23
22
|
class API
|
24
|
-
include API::AccessControl
|
25
23
|
include API::Account
|
26
24
|
include API::BulkImport
|
27
25
|
include API::BulkLoad
|
@@ -638,15 +636,27 @@ private
|
|
638
636
|
klass
|
639
637
|
else
|
640
638
|
case status_code
|
639
|
+
when "400"
|
640
|
+
BadRequestError
|
641
|
+
when "401"
|
642
|
+
AuthError
|
643
|
+
when "403"
|
644
|
+
ForbiddenError
|
641
645
|
when "404"
|
642
646
|
NotFoundError
|
647
|
+
when "405"
|
648
|
+
MethodNotAllowedError
|
643
649
|
when "409"
|
644
650
|
message = "#{message}: conflicts_with job:#{error["details"]["conflicts_with"]}" if error["details"] && error["details"]["conflicts_with"]
|
645
651
|
AlreadyExistsError
|
646
|
-
when "
|
647
|
-
|
648
|
-
when "
|
649
|
-
|
652
|
+
when "415"
|
653
|
+
UnsupportedMediaTypeError
|
654
|
+
when "422"
|
655
|
+
UnprocessableEntityError
|
656
|
+
when "429"
|
657
|
+
TooManyRequestsError
|
658
|
+
when /\A4\d\d\z/
|
659
|
+
ClientError
|
650
660
|
else
|
651
661
|
message = "#{status_code}: #{message}"
|
652
662
|
APIError
|
data/lib/td/client/api/export.rb
CHANGED
@@ -28,7 +28,7 @@ module Export
|
|
28
28
|
# @return [String] job_id
|
29
29
|
def result_export(target_job_id, opts={})
|
30
30
|
code, body, res = post("/v3/job/result_export/#{target_job_id}", opts)
|
31
|
-
if code !=
|
31
|
+
if code[0] != ?2
|
32
32
|
raise_error("Result Export failed", res)
|
33
33
|
end
|
34
34
|
js = checked_json(body, %w[job_id])
|
data/lib/td/client/api/import.rb
CHANGED
data/lib/td/client/api/job.rb
CHANGED
@@ -6,7 +6,7 @@ module Job
|
|
6
6
|
##
|
7
7
|
|
8
8
|
# @param [Fixnum] from
|
9
|
-
# @param [Fixnum] to
|
9
|
+
# @param [Fixnum] to (to is inclusive)
|
10
10
|
# @param [String] status
|
11
11
|
# @param [Hash] conditions
|
12
12
|
# @return [Array]
|
@@ -67,6 +67,8 @@ module Job
|
|
67
67
|
num_records = js['num_records']
|
68
68
|
duration = js['duration']
|
69
69
|
result = js['result'] # result target URL
|
70
|
+
linked_result_export_job_id = js['linked_result_export_job_id']
|
71
|
+
result_export_target_job_id = js['result_export_target_job_id']
|
70
72
|
hive_result_schema = (js['hive_result_schema'] || '')
|
71
73
|
if hive_result_schema.empty?
|
72
74
|
hive_result_schema = nil
|
@@ -100,7 +102,8 @@ module Job
|
|
100
102
|
priority = js['priority']
|
101
103
|
retry_limit = js['retry_limit']
|
102
104
|
return [type, query, status, url, debug, start_at, end_at, cpu_time,
|
103
|
-
result_size, result, hive_result_schema, priority, retry_limit, nil, database, duration, num_records
|
105
|
+
result_size, result, hive_result_schema, priority, retry_limit, nil, database, duration, num_records,
|
106
|
+
linked_result_export_job_id, result_export_target_job_id]
|
104
107
|
end
|
105
108
|
|
106
109
|
# @param [String] job_id
|
@@ -313,8 +316,12 @@ module Job
|
|
313
316
|
current_total_chunk_size = 0
|
314
317
|
infl = nil
|
315
318
|
begin # LOOP of Network/Server errors
|
319
|
+
first_chunk_p = true
|
316
320
|
response = client.get(url, params, header) do |res, chunk|
|
317
|
-
|
321
|
+
# Validate only on first chunk
|
322
|
+
validate_response_status(res, current_total_chunk_size) if first_chunk_p
|
323
|
+
first_chunk_p = false
|
324
|
+
|
318
325
|
if infl.nil? && autodecode
|
319
326
|
case res.header['Content-Encoding'][0].to_s.downcase
|
320
327
|
when 'gzip'
|
data/lib/td/client/api/table.rb
CHANGED
@@ -25,16 +25,18 @@ module Table
|
|
25
25
|
estimated_storage_size = m['estimated_storage_size'].to_i
|
26
26
|
schema = JSON.parse(m['schema'] || '[]')
|
27
27
|
expire_days = m['expire_days']
|
28
|
-
|
28
|
+
include_v = m['include_v']
|
29
|
+
result[name] = [type, schema, count, created_at, updated_at, estimated_storage_size, last_import, last_log_timestamp, expire_days, include_v]
|
29
30
|
}
|
30
31
|
return result
|
31
32
|
end
|
32
33
|
|
33
34
|
# @param [String] db
|
34
35
|
# @param [String] table
|
36
|
+
# @param [Hash] params
|
35
37
|
# @return [true]
|
36
|
-
def create_log_table(db, table)
|
37
|
-
create_table(db, table, :log)
|
38
|
+
def create_log_table(db, table, params={})
|
39
|
+
create_table(db, table, :log, params)
|
38
40
|
end
|
39
41
|
|
40
42
|
# @param [String] db
|
@@ -81,9 +83,19 @@ module Table
|
|
81
83
|
# @param [Fixnum] expire_days
|
82
84
|
# @return [true]
|
83
85
|
def update_expire(db, table, expire_days)
|
84
|
-
|
86
|
+
update_table(db, table, {:expire_days=>expire_days})
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [String] db
|
90
|
+
# @param [String] table
|
91
|
+
# @option params [Fixnum] :expire_days days to expire table
|
92
|
+
# @option params [Boolean] :include_v (true) include v column on Hive
|
93
|
+
# @option params [Boolean] :detect_schema (true) detect schema on import
|
94
|
+
# @return [true]
|
95
|
+
def update_table(db, table, params={})
|
96
|
+
code, body, res = post("/v3/table/update/#{e db}/#{e table}", params)
|
85
97
|
if code != "200"
|
86
|
-
raise_error("Update table
|
98
|
+
raise_error("Update table failed", res)
|
87
99
|
end
|
88
100
|
return true
|
89
101
|
end
|
@@ -128,5 +140,14 @@ module Table
|
|
128
140
|
end
|
129
141
|
end
|
130
142
|
|
143
|
+
def change_database(db, table, dest_db)
|
144
|
+
params = { 'dest_database_name' => dest_db }
|
145
|
+
code, body, res = post("/v3/table/change_database/#{e db}/#{e table}", params)
|
146
|
+
if code != "200"
|
147
|
+
raise_error("Change database failed", res)
|
148
|
+
end
|
149
|
+
return true
|
150
|
+
end
|
151
|
+
|
131
152
|
end
|
132
153
|
end
|
data/lib/td/client/api_error.rb
CHANGED
@@ -13,16 +13,32 @@ class APIError < StandardError
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
#
|
17
|
-
class
|
16
|
+
# 4xx Client Errors
|
17
|
+
class ClientError < APIError
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
21
|
-
class
|
20
|
+
# 400 Bad Request
|
21
|
+
class BadRequestError < ClientError
|
22
22
|
end
|
23
23
|
|
24
|
-
#
|
25
|
-
class
|
24
|
+
# 401 Unauthorized
|
25
|
+
class AuthError < ClientError
|
26
|
+
end
|
27
|
+
|
28
|
+
# 403 Forbidden, used for database permissions
|
29
|
+
class ForbiddenError < ClientError
|
30
|
+
end
|
31
|
+
|
32
|
+
# 404 Not Found
|
33
|
+
class NotFoundError < ClientError
|
34
|
+
end
|
35
|
+
|
36
|
+
# 405 Method Not Allowed
|
37
|
+
class MethodNotAllowedError < ClientError
|
38
|
+
end
|
39
|
+
|
40
|
+
# 409 Conflict
|
41
|
+
class AlreadyExistsError < ClientError
|
26
42
|
attr_reader :conflicts_with
|
27
43
|
def initialize(error_message = nil, api_backtrace = nil, conflicts_with=nil)
|
28
44
|
super(error_message, api_backtrace)
|
@@ -30,8 +46,16 @@ class AlreadyExistsError < APIError
|
|
30
46
|
end
|
31
47
|
end
|
32
48
|
|
33
|
-
#
|
34
|
-
class
|
49
|
+
# 415 Unsupported Media Type
|
50
|
+
class UnsupportedMediaTypeError < ClientError
|
51
|
+
end
|
52
|
+
|
53
|
+
# 422 Unprocessable Entity
|
54
|
+
class UnprocessableEntityError < ClientError
|
55
|
+
end
|
56
|
+
|
57
|
+
# 429 Too Many Requests
|
58
|
+
class TooManyRequestsError < ClientError
|
35
59
|
end
|
36
60
|
|
37
61
|
end
|
data/lib/td/client/model.rb
CHANGED
@@ -153,7 +153,7 @@ class Table < Model
|
|
153
153
|
# @param [String] last_import
|
154
154
|
# @param [String] last_log_timestamp
|
155
155
|
# @param [Fixnum, String] expire_days
|
156
|
-
def initialize(client, db_name, table_name, type, schema, count, created_at=nil, updated_at=nil, estimated_storage_size=nil, last_import=nil, last_log_timestamp=nil, expire_days=nil)
|
156
|
+
def initialize(client, db_name, table_name, type, schema, count, created_at=nil, updated_at=nil, estimated_storage_size=nil, last_import=nil, last_log_timestamp=nil, expire_days=nil, include_v=false)
|
157
157
|
super(client)
|
158
158
|
@database = nil
|
159
159
|
@db_name = db_name
|
@@ -167,6 +167,7 @@ class Table < Model
|
|
167
167
|
@last_import = last_import
|
168
168
|
@last_log_timestamp = last_log_timestamp
|
169
169
|
@expire_days = expire_days
|
170
|
+
@include_v = include_v
|
170
171
|
end
|
171
172
|
|
172
173
|
# @!attribute [r] type
|
@@ -175,7 +176,7 @@ class Table < Model
|
|
175
176
|
# @!attribute [r] schema
|
176
177
|
# @!attribute [r] count
|
177
178
|
# @!attribute [r] estimated_storage_size
|
178
|
-
attr_reader :type, :db_name, :table_name, :schema, :count, :estimated_storage_size
|
179
|
+
attr_reader :type, :db_name, :table_name, :schema, :count, :estimated_storage_size, :include_v
|
179
180
|
|
180
181
|
alias database_name db_name
|
181
182
|
alias name table_name
|
@@ -425,6 +426,7 @@ class Job < Model
|
|
425
426
|
@db_name = db_name
|
426
427
|
@duration = duration
|
427
428
|
@num_records = num_records
|
429
|
+
@auto_update_status = true
|
428
430
|
end
|
429
431
|
|
430
432
|
# @!attribute [r] job_id
|
@@ -440,6 +442,16 @@ class Job < Model
|
|
440
442
|
attr_reader :priority, :retry_limit, :org_name, :db_name
|
441
443
|
attr_reader :duration, :num_records
|
442
444
|
|
445
|
+
# whether it update status if the job is not finished yet or not
|
446
|
+
def auto_update_status?
|
447
|
+
@auto_update_status
|
448
|
+
end
|
449
|
+
|
450
|
+
# set whether it update status if the job is not finished yet or not
|
451
|
+
def auto_update_status=(bool)
|
452
|
+
@auto_update_status = bool ? true : false
|
453
|
+
end
|
454
|
+
|
443
455
|
# @option timeout [Integer,nil] timeout in second
|
444
456
|
# @option wait_interval [Integer,nil] interval in second of polling the job status
|
445
457
|
# @param detail [Boolean] update job detail or not
|
@@ -478,55 +490,55 @@ class Job < Model
|
|
478
490
|
|
479
491
|
# @return [String]
|
480
492
|
def query
|
481
|
-
update_status! unless @query || finished?
|
493
|
+
update_status! unless @query || !@auto_update_status || finished?
|
482
494
|
@query
|
483
495
|
end
|
484
496
|
|
485
497
|
# @return [String]
|
486
498
|
def status
|
487
|
-
update_status! unless @status || finished?
|
499
|
+
update_status! unless @status || !@auto_update_status || finished?
|
488
500
|
@status
|
489
501
|
end
|
490
502
|
|
491
503
|
# @return [String]
|
492
504
|
def url
|
493
|
-
update_status! unless @url || finished?
|
505
|
+
update_status! unless @url || !@auto_update_status || finished?
|
494
506
|
@url
|
495
507
|
end
|
496
508
|
|
497
509
|
# @return [Boolean]
|
498
510
|
def debug
|
499
|
-
update_status! unless @debug || finished?
|
511
|
+
update_status! unless @debug || !@auto_update_status || finished?
|
500
512
|
@debug
|
501
513
|
end
|
502
514
|
|
503
515
|
# @return [Time, nil]
|
504
516
|
def start_at
|
505
|
-
update_status! unless @start_at || finished?
|
517
|
+
update_status! unless @start_at || !@auto_update_status || finished?
|
506
518
|
@start_at && !@start_at.empty? ? Time.parse(@start_at) : nil
|
507
519
|
end
|
508
520
|
|
509
521
|
# @return [Time, nil]
|
510
522
|
def end_at
|
511
|
-
update_status! unless @end_at || finished?
|
523
|
+
update_status! unless @end_at || !@auto_update_status || finished?
|
512
524
|
@end_at && !@end_at.empty? ? Time.parse(@end_at) : nil
|
513
525
|
end
|
514
526
|
|
515
527
|
# @return [String]
|
516
528
|
def cpu_time
|
517
|
-
update_status! unless @cpu_time || finished?
|
529
|
+
update_status! unless @cpu_time || !@auto_update_status || finished?
|
518
530
|
@cpu_time
|
519
531
|
end
|
520
532
|
|
521
533
|
# @return [Array]
|
522
534
|
def hive_result_schema
|
523
|
-
update_status! unless @hive_result_schema.instance_of?
|
535
|
+
update_status! unless @hive_result_schema.instance_of?(Array) || !@auto_update_status || finished?
|
524
536
|
@hive_result_schema
|
525
537
|
end
|
526
538
|
|
527
539
|
# @return [String]
|
528
540
|
def result_size
|
529
|
-
update_status! unless @result_size || finished?
|
541
|
+
update_status! unless @result_size || !@auto_update_status || finished?
|
530
542
|
@result_size
|
531
543
|
end
|
532
544
|
|
data/lib/td/client/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -49,11 +49,7 @@ shared_context 'common helper' do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
let :headers do
|
52
|
-
|
53
|
-
{'Accept' => '*/*', 'Accept-Encoding' => /gzip/, 'Date' => /.*/, 'User-Agent' => /Ruby/}
|
54
|
-
else
|
55
|
-
{'Accept' => '*/*', 'Date' => /.*/, 'User-Agent' => /Ruby/}
|
56
|
-
end
|
52
|
+
{'Accept' => '*/*', 'Accept-Encoding' => /gzip/, 'Date' => /.*/, 'User-Agent' => /Ruby/}
|
57
53
|
end
|
58
54
|
|
59
55
|
def stub_api_request(method, path, opts = nil)
|
@@ -39,29 +39,30 @@ describe 'API SSL connection' do
|
|
39
39
|
api = API.new(nil, :endpoint => "https://localhost:#{@serverport}", :retry_post_requests => false)
|
40
40
|
api.ssl_ca_file = File.join(DIR, 'ca-all.cert')
|
41
41
|
expect {
|
42
|
-
|
42
|
+
begin
|
43
|
+
api.delete_database('no_such_database')
|
44
|
+
rescue Errno::ECONNRESET
|
45
|
+
raise OpenSSL::SSL::SSLError # When openssl does not support SSLv3, httpclient server will not start. For context: https://github.com/nahi/httpclient/pull/424#issuecomment-731714786
|
46
|
+
end
|
43
47
|
}.to raise_error OpenSSL::SSL::SSLError
|
44
48
|
end
|
45
49
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
api.
|
52
|
-
|
53
|
-
api.delete_database('no_such_database')
|
54
|
-
}.to raise_error TreasureData::NotFoundError
|
55
|
-
end
|
50
|
+
it 'should success to connect TLSv1 only server' do
|
51
|
+
@server = setup_server(:TLSv1)
|
52
|
+
api = API.new(nil, :endpoint => "https://localhost:#{@serverport}", :retry_post_requests => false)
|
53
|
+
api.ssl_ca_file = File.join(DIR, 'ca-all.cert')
|
54
|
+
expect {
|
55
|
+
api.delete_database('no_such_database')
|
56
|
+
}.to raise_error TreasureData::NotFoundError
|
56
57
|
end
|
57
58
|
|
58
|
-
def setup_server(ssl_version)
|
59
|
+
def setup_server(ssl_version, port = 1000 + rand(1000))
|
59
60
|
logger = Logger.new(STDERR)
|
60
61
|
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
|
61
62
|
@server = WEBrick::HTTPServer.new(
|
62
63
|
:BindAddress => "localhost",
|
63
64
|
:Logger => logger,
|
64
|
-
:Port =>
|
65
|
+
:Port => port,
|
65
66
|
:AccessLog => [],
|
66
67
|
:DocumentRoot => '.',
|
67
68
|
:SSLEnable => true,
|
@@ -46,9 +46,9 @@ describe 'Import API' do
|
|
46
46
|
end
|
47
47
|
stub_request(:put, "https://#{endpoint_import}/v3/table/import_with_id/db/table/unique_id/format").
|
48
48
|
with(:body => '12345').
|
49
|
-
to_return(:
|
49
|
+
to_return(:status => 200)
|
50
50
|
File.open(t.path) do |f|
|
51
|
-
expect(api.import('db', 'table', 'format', f, 5, 'unique_id')).to eq(
|
51
|
+
expect(api.import('db', 'table', 'format', f, 5, 'unique_id')).to eq(true)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -59,9 +59,9 @@ describe 'Import API' do
|
|
59
59
|
end
|
60
60
|
stub_request(:put, "https://#{endpoint_import}/v3/table/import/db/table/format").
|
61
61
|
with(:body => '12345').
|
62
|
-
to_return(:
|
62
|
+
to_return(:status => 200)
|
63
63
|
File.open(t.path) do |f|
|
64
|
-
expect(api.import('db', 'table', 'format', f, 5)).to eq(
|
64
|
+
expect(api.import('db', 'table', 'format', f, 5)).to eq(true)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -72,9 +72,9 @@ describe 'Import API' do
|
|
72
72
|
end
|
73
73
|
stub_request(:put, "http://#{endpoint_import_old}/v3/table/import/db/table/format").
|
74
74
|
with(:body => '12345').
|
75
|
-
to_return(:
|
75
|
+
to_return(:status => 200)
|
76
76
|
File.open(t.path) do |f|
|
77
|
-
expect(api_old.import('db', 'table', 'format', f, 5)).to eq(
|
77
|
+
expect(api_old.import('db', 'table', 'format', f, 5)).to eq(true)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -85,9 +85,9 @@ describe 'Import API' do
|
|
85
85
|
end
|
86
86
|
stub_request(:put, "https://#{endpoint_import}/v3/table/import/db/table/format").
|
87
87
|
with(:body => '12345').
|
88
|
-
to_return(:
|
88
|
+
to_return(:status => 200)
|
89
89
|
File.open(t.path) do |f|
|
90
|
-
expect(api_default.import('db', 'table', 'format', f, 5)).to eq
|
90
|
+
expect(api_default.import('db', 'table', 'format', f, 5)).to eq true
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -98,9 +98,9 @@ describe 'Import API' do
|
|
98
98
|
end
|
99
99
|
stub_request(:put, "http://#{endpoint_import}/v3/table/import/db/table/format").
|
100
100
|
with(:body => '12345').
|
101
|
-
to_return(:
|
101
|
+
to_return(:status => 200)
|
102
102
|
File.open(t.path) do |f|
|
103
|
-
expect(api_default_http.import('db', 'table', 'format', f, 5)).to eq
|
103
|
+
expect(api_default_http.import('db', 'table', 'format', f, 5)).to eq true
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -111,9 +111,9 @@ describe 'Import API' do
|
|
111
111
|
end
|
112
112
|
stub_request(:put, "https://#{endpoint_unknown}/v3/table/import/db/table/format").
|
113
113
|
with(:body => '12345').
|
114
|
-
to_return(:
|
114
|
+
to_return(:status => 200)
|
115
115
|
File.open(t.path) do |f|
|
116
|
-
expect(api_unknown_host.import('db', 'table', 'format', f, 5)).to eq
|
116
|
+
expect(api_unknown_host.import('db', 'table', 'format', f, 5)).to eq true
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
@@ -124,9 +124,9 @@ describe 'Import API' do
|
|
124
124
|
end
|
125
125
|
stub_request(:put, "http://#{endpoint_unknown}/v3/table/import/db/table/format").
|
126
126
|
with(:body => '12345').
|
127
|
-
to_return(:
|
127
|
+
to_return(:status => 200)
|
128
128
|
File.open(t.path) do |f|
|
129
|
-
expect(api_unknown_host_http.import('db', 'table', 'format', f, 5)).to eq
|
129
|
+
expect(api_unknown_host_http.import('db', 'table', 'format', f, 5)).to eq true
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -31,7 +31,7 @@ describe 'Job API' do
|
|
31
31
|
jobs = api.list_jobs
|
32
32
|
jobs[i..i].map {|job_id, type, status, query, start_at, end_at, cpu_time,
|
33
33
|
result_size, result_url, priority, retry_limit, org, db,
|
34
|
-
duration, num_records|
|
34
|
+
duration, num_records, linked_result_export_job_id, result_export_target_job_id|
|
35
35
|
expect(job_id).to eq(job['job_id'])
|
36
36
|
expect(type).to eq(job['type'])
|
37
37
|
expect(status).to eq(job['status'])
|
@@ -47,6 +47,8 @@ describe 'Job API' do
|
|
47
47
|
expect(db).to eq(job['database'])
|
48
48
|
expect(duration).to eq(job['duration'])
|
49
49
|
expect(num_records).to eq(job['num_records'])
|
50
|
+
expect(linked_result_export_job_id).to eq(job['linked_result_export_job_id'])
|
51
|
+
expect(result_export_target_job_id).to eq(job['result_export_target_job_id'])
|
50
52
|
}
|
51
53
|
end
|
52
54
|
}
|
@@ -341,6 +343,21 @@ describe 'Job API' do
|
|
341
343
|
expect(api.job_result(12345)).to eq ['hello', 'world']
|
342
344
|
end
|
343
345
|
|
346
|
+
it 'has multiple chunks' do
|
347
|
+
client = double('client')
|
348
|
+
allow(api).to receive(:new_client).and_return([client, {}])
|
349
|
+
allow(client).to receive(:send_timeout=)
|
350
|
+
allow(client).to receive(:receive_timeout=)
|
351
|
+
res = HTTP::Message.new_response(nil, HTTP::Message::Headers.new)
|
352
|
+
sz = 3
|
353
|
+
chunk1 = packed[0, sz]
|
354
|
+
chunk2 = packed[sz, packed.bytesize-sz]
|
355
|
+
expect(client).to receive(:get).
|
356
|
+
and_yield(res, chunk1).
|
357
|
+
and_yield(res, chunk2).
|
358
|
+
and_return(res)
|
359
|
+
expect(api.job_result(12345)).to eq ['hello', 'world']
|
360
|
+
end
|
344
361
|
end
|
345
362
|
|
346
363
|
describe 'job_result_format' do
|
@@ -35,6 +35,56 @@ describe 'Job Model' do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
describe '#auto_update_status' do
|
39
|
+
let(:client) { Client.authenticate('user', 'password') }
|
40
|
+
let(:job_id) { 12345678 }
|
41
|
+
let(:job) { Job.new(client, job_id, nil, nil) }
|
42
|
+
let(:format) { 'json' }
|
43
|
+
let(:io) { StringIO.new }
|
44
|
+
before { allow(job).to receive(:finished?) { false } }
|
45
|
+
|
46
|
+
it 'can set' do
|
47
|
+
expect(job.auto_update_status?).to eq true
|
48
|
+
job.auto_update_status = false
|
49
|
+
expect(job.auto_update_status?).to eq false
|
50
|
+
job.auto_update_status = true
|
51
|
+
expect(job.auto_update_status?).to eq true
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'calls API if auto_update_status=true' do
|
55
|
+
job.auto_update_status = true
|
56
|
+
result_job = {
|
57
|
+
'job_id' => job_id,
|
58
|
+
'status' => 'queued',
|
59
|
+
'created_at' => Time.now,
|
60
|
+
}
|
61
|
+
stub_request(:get, "https://api.treasuredata.com/v3/job/show/#{job_id}").
|
62
|
+
to_return(:body => result_job.to_json)
|
63
|
+
expect(job.query).to be_nil
|
64
|
+
expect(job.status).to eq "queued"
|
65
|
+
expect(job.url).to be_nil
|
66
|
+
expect(job.debug).to be_nil
|
67
|
+
expect(job.start_at).to be_nil
|
68
|
+
expect(job.end_at).to be_nil
|
69
|
+
expect(job.cpu_time).to be_nil
|
70
|
+
expect(job.hive_result_schema).to be_nil
|
71
|
+
expect(job.result_size).to be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it "doesn't call API if auto_update_status=false" do
|
75
|
+
job.auto_update_status = false
|
76
|
+
expect(job.query).to be_nil
|
77
|
+
expect(job.status).to be_nil
|
78
|
+
expect(job.url).to be_nil
|
79
|
+
expect(job.debug).to be_nil
|
80
|
+
expect(job.start_at).to be_nil
|
81
|
+
expect(job.end_at).to be_nil
|
82
|
+
expect(job.cpu_time).to be_nil
|
83
|
+
expect(job.hive_result_schema).to be_nil
|
84
|
+
expect(job.result_size).to be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
38
88
|
describe '#result_raw' do
|
39
89
|
let(:client) { Client.authenticate('user', 'password') }
|
40
90
|
let(:job_id) { 12345678 }
|
@@ -90,15 +140,16 @@ describe 'Job Model' do
|
|
90
140
|
end
|
91
141
|
|
92
142
|
it 'calls a given block in every wait_interval second' do
|
93
|
-
|
94
|
-
|
95
|
-
allow(
|
143
|
+
# Let's try disable stubbing #sleep for now
|
144
|
+
# now = 1_400_000_000
|
145
|
+
# allow(self).to receive(:sleep){|arg| now += arg }
|
146
|
+
# allow(Process).to receive(:clock_gettime){ now }
|
96
147
|
expect { |b|
|
97
148
|
begin
|
98
149
|
thread = Thread.start {
|
99
|
-
job.wait(nil,
|
150
|
+
job.wait(nil, 0.1, &b)
|
100
151
|
}
|
101
|
-
sleep
|
152
|
+
sleep 0.3
|
102
153
|
change_job_status(Job::STATUS_SUCCESS)
|
103
154
|
thread.join(1)
|
104
155
|
expect(thread).to be_stop
|
@@ -30,6 +30,13 @@ describe 'Table API' do
|
|
30
30
|
expect(api.create_log_table(db_name, table_name)).to be true
|
31
31
|
end
|
32
32
|
|
33
|
+
it 'should create a new table with params' do
|
34
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e(table_name)}/log").
|
35
|
+
with(:body => {'include_v' => 'false'}).
|
36
|
+
to_return(:body => {'database' => db_name, 'table' => table_name, 'type' => 'log', 'include_v' => 'false'}.to_json)
|
37
|
+
expect(api.create_log_table(db_name, table_name, include_v: false)).to be true
|
38
|
+
end
|
39
|
+
|
33
40
|
it 'should return 400 error with invalid name' do
|
34
41
|
invalid_name = 'a'
|
35
42
|
err_msg = "Name must be 3 to 256 characters, got #{invalid_name.length} characters. name = '#{invalid_name}'"
|
@@ -52,6 +59,52 @@ describe 'Table API' do
|
|
52
59
|
end
|
53
60
|
end
|
54
61
|
|
62
|
+
describe "'create_log_table' client API" do
|
63
|
+
it 'should return 404 error if the database does not exist' do
|
64
|
+
err_msg = "Create log table failed: Couldn't find UserDatabase with name = #{db_name}"
|
65
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e(table_name)}/log").
|
66
|
+
to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
67
|
+
|
68
|
+
expect {
|
69
|
+
client.create_log_table(db_name, table_name)
|
70
|
+
}.to raise_error(TreasureData::NotFoundError, /#{err_msg}/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should create a new table if the database exists' do
|
74
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e(table_name)}/log").
|
75
|
+
to_return(:body => {'database' => db_name, 'table' => table_name, 'type' => 'log'}.to_json)
|
76
|
+
expect(client.create_log_table(db_name, table_name)).to be true
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should create a new table with params' do
|
80
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e(table_name)}/log").
|
81
|
+
with(:body => {'include_v' => 'false'}).
|
82
|
+
to_return(:body => {'database' => db_name, 'table' => table_name, 'type' => 'log', 'include_v' => 'false'}.to_json)
|
83
|
+
expect(client.create_log_table(db_name, table_name, include_v: false)).to be true
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should return 400 error with invalid name' do
|
87
|
+
invalid_name = 'a'
|
88
|
+
err_msg = "Name must be 3 to 256 characters, got #{invalid_name.length} characters. name = '#{invalid_name}'"
|
89
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e invalid_name}/log").
|
90
|
+
to_return(:status => 400, :body => {'message' => err_msg}.to_json)
|
91
|
+
|
92
|
+
expect {
|
93
|
+
client.create_log_table(db_name, invalid_name)
|
94
|
+
}.to raise_error(TreasureData::APIError, /#{err_msg}/)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should return 409 error with duplicated name' do
|
98
|
+
err_msg = "Table #{table_name} already exists"
|
99
|
+
stub_api_request(:post, "/v3/table/create/#{e db_name}/#{e table_name}/log").
|
100
|
+
to_return(:status => 409, :body => {'message' => err_msg}.to_json)
|
101
|
+
|
102
|
+
expect {
|
103
|
+
client.create_log_table(db_name, table_name)
|
104
|
+
}.to raise_error(TreasureData::AlreadyExistsError, /#{err_msg}/)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
55
108
|
describe "'list_tables' API" do
|
56
109
|
it 'should list the tables in a Hash whose values include type, count, created_at, updated_at, schema, ...' do
|
57
110
|
tables = [
|
@@ -179,6 +232,31 @@ describe 'Table API' do
|
|
179
232
|
end
|
180
233
|
end
|
181
234
|
|
235
|
+
describe 'handle include_v' do
|
236
|
+
it 'should set/unset include_v flag' do
|
237
|
+
stub_api_request(:get, '/v3/table/list/db').
|
238
|
+
to_return(:body => {'tables' => [
|
239
|
+
{'name' => 'table', 'type' => 'log', 'include_v' => true},
|
240
|
+
]}.to_json)
|
241
|
+
|
242
|
+
table = client.table('db', 'table')
|
243
|
+
expect(table.include_v).to eq true
|
244
|
+
|
245
|
+
stub_api_request(:get, '/v3/table/list/db').
|
246
|
+
to_return(:body => {'tables' => [
|
247
|
+
{'name' => 'table', 'type' => 'log', 'include_v' => false},
|
248
|
+
]}.to_json)
|
249
|
+
|
250
|
+
stub_api_request(:post, '/v3/table/update/db/table').
|
251
|
+
with(:body => {'include_v' => "false"}).
|
252
|
+
to_return(:body => {"database"=>"db","table"=>"table","type"=>"log"}.to_json)
|
253
|
+
api.update_table('db', 'table', include_v: "false")
|
254
|
+
|
255
|
+
table = client.table('db', 'table')
|
256
|
+
expect(table.include_v).to eq false
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
182
260
|
describe 'tail' do
|
183
261
|
let :packed do
|
184
262
|
s = StringIO.new
|
@@ -223,4 +301,43 @@ describe 'Table API' do
|
|
223
301
|
expect(r.read).to eq(%Q(parameter "to" and "from" no longer work\n))
|
224
302
|
end
|
225
303
|
end
|
304
|
+
|
305
|
+
describe 'change_database' do
|
306
|
+
it 'should change the database belonging to' do
|
307
|
+
stub_api_request(:post, "/v3/table/change_database/src_db/table").
|
308
|
+
with(:body => {'dest_database_name' => 'dst_db'}).
|
309
|
+
to_return(:body => {'database' => 'dst_db', 'table' => 'table', 'type' => 'log'}.to_json)
|
310
|
+
expect(api.change_database('src_db', 'table', 'dst_db')).to be true
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'should return 403 error if dest database is inaccessible' do
|
314
|
+
err_msg = 'Access denied for the destination'
|
315
|
+
stub_api_request(:post, "/v3/table/change_database/src_db/table").
|
316
|
+
with(:body => {'dest_database_name' => 'inaccessible_db'}).
|
317
|
+
to_return(:status => 403, :body => {'message' => err_msg}.to_json)
|
318
|
+
expect {
|
319
|
+
api.change_database('src_db', 'table', 'inaccessible_db')
|
320
|
+
}.to raise_error(TreasureData::ForbiddenError, /#{err_msg}/)
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'should return 403 error if there is a same name table in the dest database' do
|
324
|
+
err_msg = 'Table table already exists in the destination'
|
325
|
+
stub_api_request(:post, "/v3/table/change_database/src_db/table").
|
326
|
+
with(:body => {'dest_database_name' => 'dst_db'}).
|
327
|
+
to_return(:status => 403, :body => {'message' => err_msg}.to_json)
|
328
|
+
expect {
|
329
|
+
api.change_database('src_db', 'table', 'dst_db')
|
330
|
+
}.to raise_error(TreasureData::ForbiddenError, /#{err_msg}/)
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'should return 404 error if the dest database does not exist' do
|
334
|
+
err_msg = 'Destination database is not found'
|
335
|
+
stub_api_request(:post, "/v3/table/change_database/src_db/table").
|
336
|
+
with(:body => {'dest_database_name' => 'notexist_db'}).
|
337
|
+
to_return(:status => 404, :body => {'message' => err_msg}.to_json)
|
338
|
+
expect {
|
339
|
+
api.change_database('src_db', 'table', 'notexist_db')
|
340
|
+
}.to raise_error(TreasureData::NotFoundError, /#{err_msg}/)
|
341
|
+
end
|
342
|
+
end
|
226
343
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: td-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Treasure Data, Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -128,6 +128,20 @@ dependencies:
|
|
128
128
|
- - ">="
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: webrick
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
131
145
|
description: Treasure Data API library for Ruby
|
132
146
|
email: support@treasure-data.com
|
133
147
|
executables: []
|
@@ -138,7 +152,6 @@ files:
|
|
138
152
|
- lib/td-client.rb
|
139
153
|
- lib/td/client.rb
|
140
154
|
- lib/td/client/api.rb
|
141
|
-
- lib/td/client/api/access_control.rb
|
142
155
|
- lib/td/client/api/account.rb
|
143
156
|
- lib/td/client/api/bulk_import.rb
|
144
157
|
- lib/td/client/api/bulk_load.rb
|
@@ -158,7 +171,6 @@ files:
|
|
158
171
|
- lib/td/client/version.rb
|
159
172
|
- lib/td/core_ext/openssl/ssl/sslcontext/set_params.rb
|
160
173
|
- spec/spec_helper.rb
|
161
|
-
- spec/td/client/access_control_api_spec.rb
|
162
174
|
- spec/td/client/account_api_spec.rb
|
163
175
|
- spec/td/client/api_error_spec.rb
|
164
176
|
- spec/td/client/api_spec.rb
|
@@ -182,9 +194,10 @@ files:
|
|
182
194
|
- spec/td/client_sched_spec.rb
|
183
195
|
- spec/td/client_spec.rb
|
184
196
|
homepage: http://treasuredata.com/
|
185
|
-
licenses:
|
197
|
+
licenses:
|
198
|
+
- Apache-2.0
|
186
199
|
metadata: {}
|
187
|
-
post_install_message:
|
200
|
+
post_install_message:
|
188
201
|
rdoc_options: []
|
189
202
|
require_paths:
|
190
203
|
- lib
|
@@ -199,31 +212,29 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
212
|
- !ruby/object:Gem::Version
|
200
213
|
version: '0'
|
201
214
|
requirements: []
|
202
|
-
|
203
|
-
|
204
|
-
signing_key:
|
215
|
+
rubygems_version: 3.0.9
|
216
|
+
signing_key:
|
205
217
|
specification_version: 4
|
206
218
|
summary: Treasure Data API library for Ruby
|
207
219
|
test_files:
|
208
|
-
- spec/td/
|
209
|
-
- spec/td/
|
210
|
-
- spec/td/client/
|
220
|
+
- spec/td/client_spec.rb
|
221
|
+
- spec/td/client_sched_spec.rb
|
222
|
+
- spec/td/client/partial_delete_api_spec.rb
|
211
223
|
- spec/td/client/api_spec.rb
|
212
|
-
- spec/td/client/api_ssl_connection_spec.rb
|
213
|
-
- spec/td/client/bulk_import_spec.rb
|
214
|
-
- spec/td/client/bulk_load_spec.rb
|
215
224
|
- spec/td/client/db_api_spec.rb
|
225
|
+
- spec/td/client/result_api_spec.rb
|
216
226
|
- spec/td/client/export_api_spec.rb
|
217
|
-
- spec/td/client/import_api_spec.rb
|
218
|
-
- spec/td/client/job_api_spec.rb
|
219
|
-
- spec/td/client/model_job_spec.rb
|
220
|
-
- spec/td/client/model_schedule_spec.rb
|
221
227
|
- spec/td/client/model_schema_spec.rb
|
222
|
-
- spec/td/client/
|
223
|
-
- spec/td/client/result_api_spec.rb
|
228
|
+
- spec/td/client/api_error_spec.rb
|
224
229
|
- spec/td/client/sched_api_spec.rb
|
225
|
-
- spec/td/client/server_status_api_spec.rb
|
226
230
|
- spec/td/client/table_api_spec.rb
|
231
|
+
- spec/td/client/bulk_load_spec.rb
|
232
|
+
- spec/td/client/api_ssl_connection_spec.rb
|
233
|
+
- spec/td/client/job_api_spec.rb
|
234
|
+
- spec/td/client/account_api_spec.rb
|
227
235
|
- spec/td/client/user_api_spec.rb
|
228
|
-
- spec/td/
|
229
|
-
- spec/td/
|
236
|
+
- spec/td/client/bulk_import_spec.rb
|
237
|
+
- spec/td/client/model_schedule_spec.rb
|
238
|
+
- spec/td/client/import_api_spec.rb
|
239
|
+
- spec/td/client/server_status_api_spec.rb
|
240
|
+
- spec/td/client/model_job_spec.rb
|
@@ -1,74 +0,0 @@
|
|
1
|
-
class TreasureData::API
|
2
|
-
module AccessControl
|
3
|
-
|
4
|
-
####
|
5
|
-
## Access Control API
|
6
|
-
##
|
7
|
-
|
8
|
-
# @param [String] subject
|
9
|
-
# @param [String] action
|
10
|
-
# @param [String] scope
|
11
|
-
# @param [Array] grant_option
|
12
|
-
# @return [true]
|
13
|
-
def grant_access_control(subject, action, scope, grant_option)
|
14
|
-
params = {'subject'=>subject, 'action'=>action, 'scope'=>scope, 'grant_option'=>grant_option.to_s}
|
15
|
-
code, body, res = post("/v3/acl/grant", params)
|
16
|
-
if code != "200"
|
17
|
-
raise_error("Granting access control failed", res)
|
18
|
-
end
|
19
|
-
return true
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param [String] subject
|
23
|
-
# @param [String] action
|
24
|
-
# @param [String] scope
|
25
|
-
# @return [true]
|
26
|
-
def revoke_access_control(subject, action, scope)
|
27
|
-
params = {'subject'=>subject, 'action'=>action, 'scope'=>scope}
|
28
|
-
code, body, res = post("/v3/acl/revoke", params)
|
29
|
-
if code != "200"
|
30
|
-
raise_error("Revoking access control failed", res)
|
31
|
-
end
|
32
|
-
return true
|
33
|
-
end
|
34
|
-
|
35
|
-
# @param [String] user
|
36
|
-
# @param [String] action
|
37
|
-
# @param [String] scope
|
38
|
-
# @return [Array]
|
39
|
-
def test_access_control(user, action, scope)
|
40
|
-
params = {'user'=>user, 'action'=>action, 'scope'=>scope}
|
41
|
-
code, body, res = get("/v3/acl/test", params)
|
42
|
-
if code != "200"
|
43
|
-
raise_error("Testing access control failed", res)
|
44
|
-
end
|
45
|
-
js = checked_json(body, %w[permission access_controls])
|
46
|
-
perm = js["permission"]
|
47
|
-
acl = js["access_controls"].map {|roleinfo|
|
48
|
-
subject = roleinfo['subject']
|
49
|
-
action = roleinfo['action']
|
50
|
-
scope = roleinfo['scope']
|
51
|
-
[name, action, scope]
|
52
|
-
}
|
53
|
-
return perm, acl
|
54
|
-
end
|
55
|
-
|
56
|
-
# @return [Array]
|
57
|
-
def list_access_controls
|
58
|
-
code, body, res = get("/v3/acl/list")
|
59
|
-
if code != "200"
|
60
|
-
raise_error("Listing access control failed", res)
|
61
|
-
end
|
62
|
-
js = checked_json(body, %w[access_controls])
|
63
|
-
acl = js["access_controls"].map {|roleinfo|
|
64
|
-
subject = roleinfo['subject']
|
65
|
-
action = roleinfo['action']
|
66
|
-
scope = roleinfo['scope']
|
67
|
-
grant_option = roleinfo['grant_option']
|
68
|
-
[subject, action, scope, grant_option]
|
69
|
-
}
|
70
|
-
return acl
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'td/client/spec_resources'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
describe 'Access Control API' do
|
6
|
-
include_context 'spec symbols'
|
7
|
-
include_context 'common helper'
|
8
|
-
|
9
|
-
let :api do
|
10
|
-
# no retry for GET
|
11
|
-
API.new(nil, {:max_cumul_retry_delay => -1})
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'all apis' do
|
15
|
-
it 'is deprecated' do
|
16
|
-
stub_api_request(:post, "/v3/acl/grant").to_return(:status => 500)
|
17
|
-
expect {
|
18
|
-
api.grant_access_control('subject', 'action', 'scope', [])
|
19
|
-
}.to raise_error(TreasureData::APIError)
|
20
|
-
|
21
|
-
stub_api_request(:post, "/v3/acl/revoke").to_return(:status => 500)
|
22
|
-
expect {
|
23
|
-
api.revoke_access_control('subject', 'action', 'scope')
|
24
|
-
}.to raise_error(TreasureData::APIError)
|
25
|
-
|
26
|
-
stub_api_request(:get, "/v3/acl/test", :query => {'user' => 'user', 'action' => 'action', 'scope' => 'scope'}).to_return(:status => 422)
|
27
|
-
expect {
|
28
|
-
api.test_access_control('user', 'action', 'scope')
|
29
|
-
}.to raise_error(TreasureData::APIError)
|
30
|
-
|
31
|
-
stub_api_request(:get, "/v3/acl/list").to_return(:status => 500)
|
32
|
-
expect {
|
33
|
-
api.list_access_controls
|
34
|
-
}.to raise_error(TreasureData::APIError)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|