td-client 1.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/data/ca-bundle.crt +3448 -0
- data/lib/td-client.rb +1 -0
- data/lib/td/client.rb +606 -0
- data/lib/td/client/api.rb +707 -0
- data/lib/td/client/api/access_control.rb +74 -0
- data/lib/td/client/api/account.rb +45 -0
- data/lib/td/client/api/bulk_import.rb +184 -0
- data/lib/td/client/api/bulk_load.rb +172 -0
- data/lib/td/client/api/database.rb +50 -0
- data/lib/td/client/api/export.rb +38 -0
- data/lib/td/client/api/import.rb +38 -0
- data/lib/td/client/api/job.rb +390 -0
- data/lib/td/client/api/partial_delete.rb +27 -0
- data/lib/td/client/api/result.rb +46 -0
- data/lib/td/client/api/schedule.rb +120 -0
- data/lib/td/client/api/server_status.rb +21 -0
- data/lib/td/client/api/table.rb +132 -0
- data/lib/td/client/api/user.rb +134 -0
- data/lib/td/client/api_error.rb +37 -0
- data/lib/td/client/compat_gzip_reader.rb +22 -0
- data/lib/td/client/model.rb +816 -0
- data/lib/td/client/version.rb +5 -0
- data/lib/td/core_ext/openssl/ssl/sslcontext/set_params.rb +18 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/td/client/access_control_api_spec.rb +37 -0
- data/spec/td/client/account_api_spec.rb +34 -0
- data/spec/td/client/api_error_spec.rb +77 -0
- data/spec/td/client/api_spec.rb +269 -0
- data/spec/td/client/api_ssl_connection_spec.rb +109 -0
- data/spec/td/client/bulk_import_spec.rb +199 -0
- data/spec/td/client/bulk_load_spec.rb +401 -0
- data/spec/td/client/db_api_spec.rb +123 -0
- data/spec/td/client/export_api_spec.rb +51 -0
- data/spec/td/client/import_api_spec.rb +148 -0
- data/spec/td/client/job_api_spec.rb +833 -0
- data/spec/td/client/model_job_spec.rb +136 -0
- data/spec/td/client/model_schedule_spec.rb +26 -0
- data/spec/td/client/model_schema_spec.rb +134 -0
- data/spec/td/client/partial_delete_api_spec.rb +58 -0
- data/spec/td/client/result_api_spec.rb +77 -0
- data/spec/td/client/sched_api_spec.rb +109 -0
- data/spec/td/client/server_status_api_spec.rb +25 -0
- data/spec/td/client/spec_resources.rb +99 -0
- data/spec/td/client/table_api_spec.rb +226 -0
- data/spec/td/client/user_api_spec.rb +118 -0
- data/spec/td/client_sched_spec.rb +79 -0
- data/spec/td/client_spec.rb +46 -0
- metadata +271 -0
@@ -0,0 +1,74 @@
|
|
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
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class TreasureData::API
|
2
|
+
module Account
|
3
|
+
|
4
|
+
####
|
5
|
+
## Account API
|
6
|
+
##
|
7
|
+
|
8
|
+
# @return [Array]
|
9
|
+
def show_account
|
10
|
+
code, body, res = get("/v3/account/show")
|
11
|
+
if code != "200"
|
12
|
+
raise_error("Show account failed", res)
|
13
|
+
end
|
14
|
+
js = checked_json(body, %w[account])
|
15
|
+
a = js["account"]
|
16
|
+
account_id = a['id'].to_i
|
17
|
+
plan = a['plan'].to_i
|
18
|
+
storage_size = a['storage_size'].to_i
|
19
|
+
guaranteed_cores = a['guaranteed_cores'].to_i
|
20
|
+
maximum_cores = a['maximum_cores'].to_i
|
21
|
+
created_at = a['created_at']
|
22
|
+
return [account_id, plan, storage_size, guaranteed_cores, maximum_cores, created_at]
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Fixnum] from
|
26
|
+
# @param [Fixnum] to
|
27
|
+
# @return [Array]
|
28
|
+
def account_core_utilization(from, to)
|
29
|
+
params = { }
|
30
|
+
params['from'] = from.to_s if from
|
31
|
+
params['to'] = to.to_s if to
|
32
|
+
code, body, res = get("/v3/account/core_utilization", params)
|
33
|
+
if code != "200"
|
34
|
+
raise_error("Show account failed", res)
|
35
|
+
end
|
36
|
+
js = checked_json(body, %w[from to interval history])
|
37
|
+
from = Time.parse(js['from']).utc
|
38
|
+
to = Time.parse(js['to']).utc
|
39
|
+
interval = js['interval'].to_i
|
40
|
+
history = js['history']
|
41
|
+
return [from, to, interval, history]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
class TreasureData::API
|
2
|
+
module BulkImport
|
3
|
+
|
4
|
+
####
|
5
|
+
## Bulk import API
|
6
|
+
##
|
7
|
+
|
8
|
+
# @param [String] name
|
9
|
+
# @param [String] db
|
10
|
+
# @param [String] table
|
11
|
+
# @param [Hash] opts
|
12
|
+
# @return [nil]
|
13
|
+
def create_bulk_import(name, db, table, opts={})
|
14
|
+
params = opts.dup
|
15
|
+
code, body, res = post("/v3/bulk_import/create/#{e name}/#{e db}/#{e table}", params)
|
16
|
+
if code != "200"
|
17
|
+
raise_error("Create bulk import failed", res)
|
18
|
+
end
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param [String] name
|
23
|
+
# @param [Hash] opts
|
24
|
+
# @return [nil]
|
25
|
+
def delete_bulk_import(name, opts={})
|
26
|
+
params = opts.dup
|
27
|
+
code, body, res = post("/v3/bulk_import/delete/#{e name}", params)
|
28
|
+
if code != "200"
|
29
|
+
raise_error("Delete bulk import failed", res)
|
30
|
+
end
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [String] name
|
35
|
+
# @return [Hash]
|
36
|
+
def show_bulk_import(name)
|
37
|
+
code, body, res = get("/v3/bulk_import/show/#{name}")
|
38
|
+
if code != "200"
|
39
|
+
raise_error("Show bulk import failed", res)
|
40
|
+
end
|
41
|
+
js = checked_json(body, %w[status])
|
42
|
+
return js
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [Hash] opts
|
46
|
+
# @return [Hash]
|
47
|
+
def list_bulk_imports(opts={})
|
48
|
+
params = opts.dup
|
49
|
+
code, body, res = get("/v3/bulk_import/list", params)
|
50
|
+
if code != "200"
|
51
|
+
raise_error("List bulk imports failed", res)
|
52
|
+
end
|
53
|
+
js = checked_json(body, %w[bulk_imports])
|
54
|
+
return js['bulk_imports']
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param [String] name
|
58
|
+
# @param [Hash] opts
|
59
|
+
# @return [nil]
|
60
|
+
def list_bulk_import_parts(name, opts={})
|
61
|
+
params = opts.dup
|
62
|
+
code, body, res = get("/v3/bulk_import/list_parts/#{e name}", params)
|
63
|
+
if code != "200"
|
64
|
+
raise_error("List bulk import parts failed", res)
|
65
|
+
end
|
66
|
+
js = checked_json(body, %w[parts])
|
67
|
+
return js['parts']
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [String] name
|
71
|
+
# @param [String] part_name
|
72
|
+
# @param [String, StringIO] stream
|
73
|
+
# @param [Fixnum] size
|
74
|
+
# @param [Hash] opts
|
75
|
+
# @return [nil]
|
76
|
+
def bulk_import_upload_part(name, part_name, stream, size, opts={})
|
77
|
+
code, body, res = put("/v3/bulk_import/upload_part/#{e name}/#{e part_name}", stream, size)
|
78
|
+
if code[0] != ?2
|
79
|
+
raise_error("Upload a part failed", res)
|
80
|
+
end
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
|
84
|
+
# @param [String] name
|
85
|
+
# @param [String] part_name
|
86
|
+
# @param [Hash] opts
|
87
|
+
# @return [nil]
|
88
|
+
def bulk_import_delete_part(name, part_name, opts={})
|
89
|
+
params = opts.dup
|
90
|
+
code, body, res = post("/v3/bulk_import/delete_part/#{e name}/#{e part_name}", params)
|
91
|
+
if code[0] != ?2
|
92
|
+
raise_error("Delete a part failed", res)
|
93
|
+
end
|
94
|
+
return nil
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [String] name
|
98
|
+
# @param [Hash] opts
|
99
|
+
# @return [nil]
|
100
|
+
def freeze_bulk_import(name, opts={})
|
101
|
+
params = opts.dup
|
102
|
+
code, body, res = post("/v3/bulk_import/freeze/#{e name}", params)
|
103
|
+
if code != "200"
|
104
|
+
raise_error("Freeze bulk import failed", res)
|
105
|
+
end
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# @param [String] name
|
110
|
+
# @param [Hash] opts
|
111
|
+
# @return [nil]
|
112
|
+
def unfreeze_bulk_import(name, opts={})
|
113
|
+
params = opts.dup
|
114
|
+
code, body, res = post("/v3/bulk_import/unfreeze/#{e name}", params)
|
115
|
+
if code != "200"
|
116
|
+
raise_error("Unfreeze bulk import failed", res)
|
117
|
+
end
|
118
|
+
return nil
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param [String] name
|
122
|
+
# @param [Hash] opts
|
123
|
+
# @return [String] job_id
|
124
|
+
def perform_bulk_import(name, opts={})
|
125
|
+
params = opts.dup
|
126
|
+
code, body, res = post("/v3/bulk_import/perform/#{e name}", params)
|
127
|
+
if code != "200"
|
128
|
+
raise_error("Perform bulk import failed", res)
|
129
|
+
end
|
130
|
+
js = checked_json(body, %w[job_id])
|
131
|
+
return js['job_id'].to_s
|
132
|
+
end
|
133
|
+
|
134
|
+
# @param [String] name
|
135
|
+
# @param [Hash] opts
|
136
|
+
# @return [nil]
|
137
|
+
def commit_bulk_import(name, opts={})
|
138
|
+
params = opts.dup
|
139
|
+
code, body, res = post("/v3/bulk_import/commit/#{e name}", params)
|
140
|
+
if code != "200"
|
141
|
+
raise_error("Commit bulk import failed", res)
|
142
|
+
end
|
143
|
+
return nil
|
144
|
+
end
|
145
|
+
|
146
|
+
# @param [String] name
|
147
|
+
# @param [Hash] opts
|
148
|
+
# @param [Proc] block
|
149
|
+
# @return [Array]
|
150
|
+
def bulk_import_error_records(name, opts={}, &block)
|
151
|
+
params = opts.dup
|
152
|
+
code, body, res = get("/v3/bulk_import/error_records/#{e name}", params)
|
153
|
+
if code != "200"
|
154
|
+
raise_error("Failed to get bulk import error records", res)
|
155
|
+
end
|
156
|
+
if body.nil? || body.empty?
|
157
|
+
if block
|
158
|
+
return nil
|
159
|
+
else
|
160
|
+
return []
|
161
|
+
end
|
162
|
+
end
|
163
|
+
require File.expand_path('../compat_gzip_reader', File.dirname(__FILE__))
|
164
|
+
u = MessagePack::Unpacker.new(Zlib::GzipReader.new(StringIO.new(body)))
|
165
|
+
if block
|
166
|
+
begin
|
167
|
+
u.each(&block)
|
168
|
+
rescue EOFError
|
169
|
+
end
|
170
|
+
nil
|
171
|
+
else
|
172
|
+
result = []
|
173
|
+
begin
|
174
|
+
u.each {|row|
|
175
|
+
result << row
|
176
|
+
}
|
177
|
+
rescue EOFError
|
178
|
+
end
|
179
|
+
return result
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
class TreasureData::API
|
2
|
+
module BulkLoad
|
3
|
+
|
4
|
+
####
|
5
|
+
## BulkLoad (Server-side Bulk loader) API
|
6
|
+
##
|
7
|
+
|
8
|
+
# 1. POST /v3/bulk_loads/guess - stateless non REST API to return guess result as BulkLoadSession [NEW]
|
9
|
+
# 2. POST /v3/bulk_loads/preview - stateless non REST API to return preview result as BulkLoadSession [NEW]
|
10
|
+
#
|
11
|
+
# 3. POST /v3/job/issue/:type/:database - create a job resource to run BulkLoadSession [EXTENDED]
|
12
|
+
# 4. POST /v3/job/kill/:id - kill the job [ALREADY EXISTS]
|
13
|
+
# 5. GET /v3/job/show/:id - get status of the job [ALREADY EXISTS]
|
14
|
+
# 6. GET /v3/job/result/:id - get result of the job [NOT NEEDED IN Q4] ... because backend feature is not yet implemented
|
15
|
+
#
|
16
|
+
# 7. GET /v3/bulk_loads - list BulkLoadSession resources [NEW]
|
17
|
+
# 8. POST /v3/bulk_loads - create BulkLoadSession [NEW]
|
18
|
+
# 9. GET /v3/bulk_loads/:name - get BulkLoadSession [NEW]
|
19
|
+
# 10. PUT /v3/bulk_loads/:name - update BulkLoadSession [NEW]
|
20
|
+
# 11. DELETE /v3/bulk_loads/:name - delete BulkLoadSession [NEW]
|
21
|
+
# 12. GET /v3/bulk_loads/:name/jobs - list BulkLoadSession job history [NEW]
|
22
|
+
# 13. POST /v3/bulk_loads/:name/jobs - run BulkLoadSession [NEW]
|
23
|
+
|
24
|
+
# The 'BulkLoadSession' resource in td-api is as follows;
|
25
|
+
# {
|
26
|
+
# "config": {
|
27
|
+
# "type": "s3",
|
28
|
+
# "access_key_id": s3 access key id,
|
29
|
+
# "secret_access_key": s3 secret key,
|
30
|
+
# "endpoint": s3 endpoint name,
|
31
|
+
# "bucket": s3 bucket name,
|
32
|
+
# "path_prefix": "a/prefix/of/files",
|
33
|
+
# "decoders": []
|
34
|
+
# },
|
35
|
+
# "name": account_wide_unique_name,
|
36
|
+
# "cron": cron_string,
|
37
|
+
# "timezone": timezone_string,
|
38
|
+
# "delay": delay_seconds,
|
39
|
+
# "database": database_name,
|
40
|
+
# "table": table_name
|
41
|
+
# }
|
42
|
+
|
43
|
+
LIST = '/v3/bulk_loads'
|
44
|
+
SESSION = LIST + '/%s'
|
45
|
+
JOB = SESSION + '/jobs'
|
46
|
+
|
47
|
+
# job: Hash -> Hash
|
48
|
+
def bulk_load_guess(job)
|
49
|
+
# retry_request = true
|
50
|
+
path = LIST + '/guess'
|
51
|
+
res = api { post(path, job.to_json) }
|
52
|
+
unless res.ok?
|
53
|
+
raise_error('BulkLoad configuration guess failed', res)
|
54
|
+
end
|
55
|
+
JSON.load(res.body)
|
56
|
+
end
|
57
|
+
|
58
|
+
# job: Hash -> Hash
|
59
|
+
def bulk_load_preview(job)
|
60
|
+
# retry_request = true
|
61
|
+
path = LIST + '/preview'
|
62
|
+
res = api { post(path, job.to_json) }
|
63
|
+
unless res.ok?
|
64
|
+
raise_error('BulkLoad job preview failed', res)
|
65
|
+
end
|
66
|
+
JSON.load(res.body)
|
67
|
+
end
|
68
|
+
|
69
|
+
# job: Hash -> String (job_id)
|
70
|
+
def bulk_load_issue(database, table, job)
|
71
|
+
type = 'bulkload'
|
72
|
+
job = job.dup
|
73
|
+
job['database'] = database
|
74
|
+
job['table'] = table
|
75
|
+
path = "/v3/job/issue/#{e type}/#{e database}"
|
76
|
+
res = api { post(path, job.to_json) }
|
77
|
+
unless res.ok?
|
78
|
+
raise_error('BulkLoad job issuing failed', res)
|
79
|
+
end
|
80
|
+
js = checked_json(res.body)
|
81
|
+
js['job_id'].to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
# nil -> [Hash]
|
85
|
+
def bulk_load_list
|
86
|
+
res = api { get(LIST) }
|
87
|
+
unless res.ok?
|
88
|
+
raise_error("BulkLoadSession list retrieve failed", res)
|
89
|
+
end
|
90
|
+
JSON.load(res.body)
|
91
|
+
end
|
92
|
+
|
93
|
+
# name: String, database: String, table: String, job: Hash -> Hash
|
94
|
+
def bulk_load_create(name, database, table, job, opts = {})
|
95
|
+
job = job.dup
|
96
|
+
job['name'] = name
|
97
|
+
[:cron, :timezone, :delay, :time_column].each do |prop|
|
98
|
+
job[prop.to_s] = opts[prop] if opts.key?(prop)
|
99
|
+
end
|
100
|
+
job['database'] = database
|
101
|
+
job['table'] = table
|
102
|
+
res = api { post(LIST, job.to_json) }
|
103
|
+
unless res.ok?
|
104
|
+
raise_error("BulkLoadSession: #{name} create failed", res)
|
105
|
+
end
|
106
|
+
JSON.load(res.body)
|
107
|
+
end
|
108
|
+
|
109
|
+
# name: String -> Hash
|
110
|
+
def bulk_load_show(name)
|
111
|
+
path = session_path(name)
|
112
|
+
res = api { get(path) }
|
113
|
+
unless res.ok?
|
114
|
+
raise_error("BulkLoadSession: #{name} retrieve failed", res)
|
115
|
+
end
|
116
|
+
JSON.load(res.body)
|
117
|
+
end
|
118
|
+
|
119
|
+
# name: String, settings: Hash -> Hash
|
120
|
+
def bulk_load_update(name, settings)
|
121
|
+
path = session_path(name)
|
122
|
+
res = api { put(path, settings.to_json) }
|
123
|
+
unless res.ok?
|
124
|
+
raise_error("BulkLoadSession: #{name} update failed", res)
|
125
|
+
end
|
126
|
+
JSON.load(res.body)
|
127
|
+
end
|
128
|
+
|
129
|
+
# name: String -> Hash
|
130
|
+
def bulk_load_delete(name)
|
131
|
+
path = session_path(name)
|
132
|
+
res = api { delete(path) }
|
133
|
+
unless res.ok?
|
134
|
+
raise_error("BulkLoadSession: #{name} delete failed", res)
|
135
|
+
end
|
136
|
+
JSON.load(res.body)
|
137
|
+
end
|
138
|
+
|
139
|
+
# name: String -> [Hash]
|
140
|
+
def bulk_load_history(name)
|
141
|
+
path = job_path(name)
|
142
|
+
res = api { get(path) }
|
143
|
+
unless res.ok?
|
144
|
+
raise_error("history of BulkLoadSession: #{name} retrieve failed", res)
|
145
|
+
end
|
146
|
+
JSON.load(res.body)
|
147
|
+
end
|
148
|
+
|
149
|
+
def bulk_load_run(name, scheduled_time = nil)
|
150
|
+
path = job_path(name)
|
151
|
+
opts = {}
|
152
|
+
opts[:scheduled_time] = scheduled_time.to_s unless scheduled_time.nil?
|
153
|
+
res = api { post(path, opts.to_json) }
|
154
|
+
unless res.ok?
|
155
|
+
raise_error("BulkLoadSession: #{name} job create failed", res)
|
156
|
+
end
|
157
|
+
js = checked_json(res.body)
|
158
|
+
js['job_id'].to_s
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def session_path(name)
|
164
|
+
SESSION % e(name)
|
165
|
+
end
|
166
|
+
|
167
|
+
def job_path(name)
|
168
|
+
JOB % e(name)
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|