td-client 1.0.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,5 @@
1
+ module TreasureData
2
+ class Client
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require 'openssl'
2
+ module OpenSSL
3
+ module SSL
4
+ class SSLContext
5
+
6
+ # For disabling SSLv3 connection in favor of POODLE Attack protection
7
+ #
8
+ # Allow 'options' customize through Thread local storage since
9
+ # Net::HTTP does not support 'options' configuration.
10
+ #
11
+ alias original_set_params set_params
12
+ def set_params(params={})
13
+ original_set_params(params)
14
+ self.options |= OP_NO_SSLv3 if Thread.current[:SET_SSL_OP_NO_SSLv3]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+
3
+ # XXX skip coverage setting if run appveyor. Because, fail to push coveralls in appveyor.
4
+ unless ENV['APPVEYOR']
5
+ begin
6
+ if defined?(:RUBY_ENGINE) && RUBY_ENGINE == 'ruby'
7
+ # SimpleCov officially supports MRI 1.9+ only for now
8
+ # https://github.com/colszowka/simplecov#ruby-version-compatibility
9
+
10
+ require 'simplecov'
11
+ require 'coveralls'
12
+
13
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
14
+ SimpleCov::Formatter::HTMLFormatter,
15
+ Coveralls::SimpleCov::Formatter
16
+ ])
17
+ SimpleCov.start("test_frameworks")
18
+ end
19
+ rescue NameError
20
+ # skip measuring coverage at Ruby 1.8
21
+ end
22
+ end
23
+
24
+ require 'rspec'
25
+ require 'webmock/rspec'
26
+ WebMock.disable_net_connect!(:allow_localhost => true)
27
+
28
+ include WebMock::API
29
+
30
+ $LOAD_PATH << File.dirname(__FILE__)+"../lib"
31
+ require 'td-client'
32
+ require 'msgpack'
33
+ require 'json'
34
+
35
+ include TreasureData
36
+
37
+ shared_context 'common helper' do
38
+ let :account_id do
39
+ 1
40
+ end
41
+
42
+ let :headers do
43
+ if RUBY_VERSION >= "2.0.0"
44
+ {'Accept' => '*/*', 'Accept-Encoding' => /gzip/, 'Date' => /.*/, 'User-Agent' => /Ruby/}
45
+ else
46
+ {'Accept' => '*/*', 'Date' => /.*/, 'User-Agent' => /Ruby/}
47
+ end
48
+ end
49
+
50
+ def stub_api_request(method, path, opts = nil)
51
+ scheme = 'https'
52
+ with_opts = {:headers => headers}
53
+ if opts
54
+ scheme = 'http' if opts[:ssl] == false
55
+ with_opts[:query] = opts[:query] if opts[:query]
56
+ end
57
+ stub_request(method, "#{scheme}://api.treasuredata.com#{path}").with(with_opts)
58
+ end
59
+
60
+ def e(s)
61
+ s.to_s.gsub(/[^*\-0-9A-Z_a-z]/){|x|'%%%02X' % x.ord}
62
+ end
63
+ end
@@ -0,0 +1,37 @@
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
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'td/client/spec_resources'
3
+ require 'json'
4
+
5
+ describe 'Account API' do
6
+ include_context 'spec symbols'
7
+ include_context 'common helper'
8
+
9
+ let :api do
10
+ API.new(nil)
11
+ end
12
+
13
+ describe 'show_account' do
14
+ it 'returns account properties' do
15
+ stub_api_request(:get, "/v3/account/show").
16
+ to_return(:body => {'account' => {'id' => 1, 'plan' => 0, 'storage_size' => 2, 'guaranteed_cores' => 3, 'maximum_cores' => 4, 'created_at' => '2014-12-14T17:24:00+0900'}}.to_json)
17
+ expect(api.show_account).to eq([1, 0, 2, 3, 4, "2014-12-14T17:24:00+0900"])
18
+ end
19
+ end
20
+
21
+ describe 'account_core_utilization' do
22
+ it 'returns core utilization' do
23
+ from = '2014-12-01T00:00:00+0900'
24
+ to = '2015-01-01T00:00:00+0900'
25
+ stub_api_request(:get, "/v3/account/core_utilization", :query => {'from' => from, 'to' => to}).
26
+ to_return(:body => {'from' => from, 'to' => to, 'interval' => 1, 'history' => ['dummy']}.to_json)
27
+ r = api.account_core_utilization(from, to)
28
+ expect(r[0]).to eq(Time.parse(from))
29
+ expect(r[1]).to eq(Time.parse(to))
30
+ expect(r[2]).to eq(1)
31
+ expect(r[3]).to eq(['dummy'])
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe APIError do
4
+ let (:message){ 'message' }
5
+ let (:api_backtrace){ double('api_backtrace') }
6
+ describe 'new' do
7
+ context '' do
8
+ it do
9
+ exc = APIError.new(message, api_backtrace)
10
+ expect(exc).to be_an(APIError)
11
+ expect(exc.message).to eq message
12
+ expect(exc.api_backtrace).to eq api_backtrace
13
+ end
14
+ end
15
+ context 'api_backtrace is ""' do
16
+ let (:api_backtrace){ '' }
17
+ it do
18
+ exc = APIError.new(message, api_backtrace)
19
+ expect(exc).to be_an(APIError)
20
+ expect(exc.message).to eq message
21
+ expect(exc.api_backtrace).to be_nil
22
+ end
23
+ end
24
+ context 'api_backtrace is nil' do
25
+ let (:api_backtrace){ nil }
26
+ it do
27
+ exc = APIError.new(message, api_backtrace)
28
+ expect(exc).to be_an(APIError)
29
+ expect(exc.message).to eq message
30
+ expect(exc.api_backtrace).to be_nil
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ describe AlreadyExistsError do
37
+ let (:message){ 'message' }
38
+ let (:api_backtrace){ double('api_backtrace') }
39
+ let (:conflicts_with){ '12345' }
40
+ describe 'new' do
41
+ context '' do
42
+ it do
43
+ exc = AlreadyExistsError.new(message, api_backtrace)
44
+ expect(exc).to be_an(AlreadyExistsError)
45
+ expect(exc.message).to eq message
46
+ expect(exc.api_backtrace).to eq api_backtrace
47
+ end
48
+ end
49
+ context 'api_backtrace is ""' do
50
+ let (:api_backtrace){ '' }
51
+ it do
52
+ exc = AlreadyExistsError.new(message, api_backtrace)
53
+ expect(exc).to be_an(AlreadyExistsError)
54
+ expect(exc.message).to eq message
55
+ expect(exc.api_backtrace).to be_nil
56
+ end
57
+ end
58
+ context 'api_backtrace is nil' do
59
+ let (:api_backtrace){ nil }
60
+ it do
61
+ exc = AlreadyExistsError.new(message, api_backtrace)
62
+ expect(exc).to be_an(AlreadyExistsError)
63
+ expect(exc.message).to eq message
64
+ expect(exc.api_backtrace).to be_nil
65
+ end
66
+ end
67
+ context 'conflict' do
68
+ it do
69
+ exc = AlreadyExistsError.new(message, api_backtrace, conflicts_with)
70
+ expect(exc).to be_an(AlreadyExistsError)
71
+ expect(exc.message).to eq message
72
+ expect(exc.api_backtrace).to eq api_backtrace
73
+ expect(exc.conflicts_with).to eq conflicts_with
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,269 @@
1
+ require 'spec_helper'
2
+
3
+ describe API do
4
+ it 'initialize should raise an error with invalid endpoint' do
5
+ expect {
6
+ API.new(nil, :endpoint => 'smtp://api.tester.com:1000')
7
+ }.to raise_error(RuntimeError, /Invalid endpoint:/)
8
+ end
9
+
10
+ VALID_NAMES = [
11
+ 'abc',
12
+ 'abc_cd',
13
+ '_abc_cd',
14
+ '_abc_',
15
+ 'ab0_',
16
+ 'ab0',
17
+ ]
18
+
19
+ INVALID_NAMES = {
20
+ 'a' => 'a__',
21
+ 'a'*257 => 'a'*253+'__',
22
+ 'abcD' => 'abcd',
23
+ 'a-b*' => 'a_b_',
24
+ }
25
+
26
+ describe 'normalizer' do
27
+ it 'normalized_msgpack should convert Bignum into String' do
28
+ h = {'key' => 1111111111111111111111111111111111}
29
+ unpacked = MessagePack.unpack(API.normalized_msgpack(h))
30
+ expect(unpacked['key']).to eq(h['key'].to_s)
31
+
32
+ h = {'key' => -1111111111111111111111111111111111}
33
+ unpacked = MessagePack.unpack(API.normalized_msgpack(h))
34
+ expect(unpacked['key']).to eq(h['key'].to_s)
35
+ end
36
+
37
+ it 'normalized_msgpack with out argument should convert Bignum into String' do
38
+ h = {'key' => 1111111111111111111111111111111111, 'key2' => -1111111111111111111111111111111111, 'key3' => 0}
39
+ out = ''
40
+ API.normalized_msgpack(h, out)
41
+ unpacked = MessagePack.unpack(out)
42
+ expect(unpacked['key']).to eq(h['key'].to_s)
43
+ expect(unpacked['key2']).to eq(h['key2'].to_s)
44
+ expect(unpacked['key3']).to eq(h['key3']) # don't touch non-too-big integer
45
+ end
46
+
47
+ it 'normalize_database_name should return normalized data' do
48
+ INVALID_NAMES.each_pair {|ng,ok|
49
+ expect(API.normalize_database_name(ng)).to eq(ok)
50
+ }
51
+ expect {
52
+ API.normalize_database_name('')
53
+ }.to raise_error(RuntimeError)
54
+ end
55
+
56
+ it 'normalize_table_name should return normalized data' do
57
+ INVALID_NAMES.each_pair {|ng,ok|
58
+ expect(API.normalize_table_name(ng)).to eq(ok)
59
+ }
60
+ # empty
61
+ expect {
62
+ API.normalize_table_name('')
63
+ }.to raise_error(RuntimeError)
64
+ end
65
+
66
+ it 'normalize_database_name should return valid data' do
67
+ VALID_NAMES.each {|ok|
68
+ expect(API.normalize_database_name(ok)).to eq(ok)
69
+ }
70
+ end
71
+ end
72
+
73
+ describe 'validator' do
74
+ describe "'validate_database_name'" do
75
+ it 'should raise a ParameterValidationError exceptions' do
76
+ INVALID_NAMES.each_pair {|ng,ok|
77
+ expect {
78
+ API.validate_database_name(ng)
79
+ }.to raise_error(ParameterValidationError)
80
+ }
81
+ # empty
82
+ expect {
83
+ API.validate_database_name('')
84
+ }.to raise_error(ParameterValidationError)
85
+ end
86
+
87
+ it 'should return valid data' do
88
+ VALID_NAMES.each {|ok|
89
+ expect(API.validate_database_name(ok)).to eq(ok)
90
+ }
91
+ end
92
+ end
93
+
94
+ describe "'validate_table_name'" do
95
+ it 'should raise a ParameterValidationError exception' do
96
+ INVALID_NAMES.each_pair {|ng,ok|
97
+ expect {
98
+ API.validate_table_name(ng)
99
+ }.to raise_error(ParameterValidationError)
100
+ }
101
+ expect {
102
+ API.validate_table_name('')
103
+ }.to raise_error(ParameterValidationError)
104
+ end
105
+
106
+ it 'should return valid data' do
107
+ VALID_NAMES.each {|ok|
108
+ expect(API.validate_database_name(ok)).to eq(ok)
109
+ }
110
+ end
111
+ end
112
+
113
+ describe "'validate_result_set_name'" do
114
+ it 'should raise a ParameterValidationError exception' do
115
+ INVALID_NAMES.each_pair {|ng,ok|
116
+ expect {
117
+ API.validate_result_set_name(ng)
118
+ }.to raise_error(ParameterValidationError)
119
+ }
120
+ # empty
121
+ expect {
122
+ API.validate_result_set_name('')
123
+ }.to raise_error(ParameterValidationError)
124
+ end
125
+
126
+ it 'should return valid data' do
127
+ VALID_NAMES.each {|ok|
128
+ expect(API.validate_result_set_name(ok)).to eq(ok)
129
+ }
130
+ end
131
+ end
132
+
133
+ describe "'validate_column_name'" do
134
+ it 'should raise a ParameterValidationError exception' do
135
+ [''].each { |ng|
136
+ expect {
137
+ API.validate_column_name(ng)
138
+ }.to raise_error(ParameterValidationError)
139
+ }
140
+ end
141
+
142
+ it 'should return valid data' do
143
+ VALID_NAMES.each {|ok|
144
+ expect(API.validate_column_name(ok)).to eq(ok)
145
+ }
146
+ ['a', 'a'*255].each {|ok|
147
+ expect(API.validate_column_name(ok)).to eq(ok)
148
+ }
149
+ end
150
+ end
151
+
152
+ describe "'validate_sql_alias_name'" do
153
+ it 'should raise a ParameterValidationError exception' do
154
+ [''].each { |ng|
155
+ expect{API.validate_sql_alias_name(ng)}.to raise_error(ParameterValidationError)
156
+ }
157
+ valid = ("a".."z").to_a.join<<("0".."9").to_a.join<<"_"
158
+ ("\x00".."\x7F").each { |ng|
159
+ next if valid.include?(ng)
160
+ expect{API.validate_sql_alias_name(ng)}.to raise_error(ParameterValidationError)
161
+ }
162
+ end
163
+
164
+ it 'should return valid data' do
165
+ VALID_NAMES.each {|ok|
166
+ expect(API.validate_sql_alias_name(ok)).to eq(ok)
167
+ }
168
+ ['a', '_a', 'a_', 'a'*512].each {|ok|
169
+ expect(API.validate_sql_alias_name(ok)).to eq(ok)
170
+ }
171
+ end
172
+ end
173
+
174
+ describe "'generic validate_name'" do
175
+ it 'should raise a ParameterValidationError exception' do
176
+ # wrong target
177
+ expect {
178
+ API.validate_name("", 3, 256, '')
179
+ }.to raise_error(ParameterValidationError)
180
+ INVALID_NAMES.each_pair {|ng,ok|
181
+ expect {
182
+ API.validate_name("generic", 3, 256, ng)
183
+ }.to raise_error(ParameterValidationError)
184
+ }
185
+ # empty
186
+ expect {
187
+ API.validate_name("generic", 3, 256, '')
188
+ }.to raise_error(ParameterValidationError)
189
+ # too short - one less than left limit
190
+ expect {
191
+ API.validate_name("generic", 3, 256, 'ab')
192
+ }.to raise_error(ParameterValidationError)
193
+ end
194
+
195
+ it 'should return valid data' do
196
+ VALID_NAMES.each {|ok|
197
+ expect(API.validate_name("generic", 3, 256, ok)).to eq(ok)
198
+ }
199
+ # esplore left boundary
200
+ expect(API.validate_name("generic", 2, 256, 'ab')).to eq('ab')
201
+ expect(API.validate_name("generic", 1, 256, 'a')).to eq('a')
202
+ # explore right boundary
203
+ expect(API.validate_name("generic", 3, 256, 'a' * 256)).to eq('a' * 256)
204
+ expect(API.validate_name("generic", 3, 128, 'a' * 128)).to eq('a' * 128)
205
+ end
206
+ end
207
+
208
+ describe 'checking GET API content length with ssl' do
209
+ include_context 'common helper'
210
+
211
+ let(:api) { API.new(nil, endpoint: endpoint) }
212
+ let :packed do
213
+ s = StringIO.new(String.new)
214
+ Zlib::GzipWriter.wrap(s) do |f|
215
+ f << ['hello', 'world'].to_json
216
+ end
217
+ s.string
218
+ end
219
+
220
+ before do
221
+ stub_api_request(:get, '/v3/job/result/12345', ssl: ssl).
222
+ with(:query => {'format' => 'json'}).
223
+ to_return(
224
+ :headers => {'Content-Encoding' => 'gzip'}.merge(content_length),
225
+ :body => packed
226
+ )
227
+ end
228
+
229
+ subject (:get_api_call) {
230
+ api.job_result_format(12345, 'json', StringIO.new(String.new))
231
+ }
232
+
233
+ context 'without ssl' do
234
+ let(:endpoint) { "http://#{API::DEFAULT_ENDPOINT}" }
235
+ let(:ssl) { false }
236
+ let(:content_length) { {'Content-Length' => packed.size} }
237
+
238
+ it 'not called #completed_body?' do
239
+ expect(api).not_to receive(:completed_body?)
240
+
241
+ get_api_call
242
+ end
243
+ end
244
+
245
+ context 'with ssl' do
246
+ let(:endpoint) { "https://#{API::DEFAULT_ENDPOINT}" }
247
+ let(:ssl) { true }
248
+
249
+ context 'without Content-Length' do
250
+ let(:content_length) { {} }
251
+
252
+ it 'api accuess succeded' do
253
+ expect { get_api_call }.not_to raise_error
254
+ end
255
+ end
256
+
257
+ context 'with Content-Length' do
258
+ context 'match Content-Length and body.size' do
259
+ let(:content_length) { {'Content-Length' => packed.size} }
260
+
261
+ it 'api accuess succeded' do
262
+ expect { get_api_call }.not_to raise_error
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end