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,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