td-client 1.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/data/ca-bundle.crt +3448 -0
  3. data/lib/td-client.rb +1 -0
  4. data/lib/td/client.rb +606 -0
  5. data/lib/td/client/api.rb +707 -0
  6. data/lib/td/client/api/access_control.rb +74 -0
  7. data/lib/td/client/api/account.rb +45 -0
  8. data/lib/td/client/api/bulk_import.rb +184 -0
  9. data/lib/td/client/api/bulk_load.rb +172 -0
  10. data/lib/td/client/api/database.rb +50 -0
  11. data/lib/td/client/api/export.rb +38 -0
  12. data/lib/td/client/api/import.rb +38 -0
  13. data/lib/td/client/api/job.rb +390 -0
  14. data/lib/td/client/api/partial_delete.rb +27 -0
  15. data/lib/td/client/api/result.rb +46 -0
  16. data/lib/td/client/api/schedule.rb +120 -0
  17. data/lib/td/client/api/server_status.rb +21 -0
  18. data/lib/td/client/api/table.rb +132 -0
  19. data/lib/td/client/api/user.rb +134 -0
  20. data/lib/td/client/api_error.rb +37 -0
  21. data/lib/td/client/compat_gzip_reader.rb +22 -0
  22. data/lib/td/client/model.rb +816 -0
  23. data/lib/td/client/version.rb +5 -0
  24. data/lib/td/core_ext/openssl/ssl/sslcontext/set_params.rb +18 -0
  25. data/spec/spec_helper.rb +63 -0
  26. data/spec/td/client/access_control_api_spec.rb +37 -0
  27. data/spec/td/client/account_api_spec.rb +34 -0
  28. data/spec/td/client/api_error_spec.rb +77 -0
  29. data/spec/td/client/api_spec.rb +269 -0
  30. data/spec/td/client/api_ssl_connection_spec.rb +109 -0
  31. data/spec/td/client/bulk_import_spec.rb +199 -0
  32. data/spec/td/client/bulk_load_spec.rb +401 -0
  33. data/spec/td/client/db_api_spec.rb +123 -0
  34. data/spec/td/client/export_api_spec.rb +51 -0
  35. data/spec/td/client/import_api_spec.rb +148 -0
  36. data/spec/td/client/job_api_spec.rb +833 -0
  37. data/spec/td/client/model_job_spec.rb +136 -0
  38. data/spec/td/client/model_schedule_spec.rb +26 -0
  39. data/spec/td/client/model_schema_spec.rb +134 -0
  40. data/spec/td/client/partial_delete_api_spec.rb +58 -0
  41. data/spec/td/client/result_api_spec.rb +77 -0
  42. data/spec/td/client/sched_api_spec.rb +109 -0
  43. data/spec/td/client/server_status_api_spec.rb +25 -0
  44. data/spec/td/client/spec_resources.rb +99 -0
  45. data/spec/td/client/table_api_spec.rb +226 -0
  46. data/spec/td/client/user_api_spec.rb +118 -0
  47. data/spec/td/client_sched_spec.rb +79 -0
  48. data/spec/td/client_spec.rb +46 -0
  49. 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