tablestore-ruby-sdk 0.0.0

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.
@@ -0,0 +1,21 @@
1
+ require 'tablestore/crc8_auto'
2
+
3
+ class PlainBufferCrc8
4
+ class << self
5
+ def crc_string(crc, bytes)
6
+ Digest::CRC8Auto.new.crc8(crc, bytes.to_s).checksum
7
+ end
8
+
9
+ def crc_int8(crc, byte)
10
+ Digest::CRC8Auto.new.crc8(crc, [byte].pack('C*')).checksum
11
+ end
12
+
13
+ def crc_int32(crc, byte)
14
+ Digest::CRC8Auto.new.crc8(crc, [byte].pack('i')).checksum
15
+ end
16
+
17
+ def crc_int64(crc, byte)
18
+ Digest::CRC8Auto.new.crc8(crc, [byte].pack('q')).checksum
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,92 @@
1
+ require 'tablestore/error'
2
+
3
+ class PlainBufferInputStream
4
+ def initialize(data_buffer)
5
+ @buffer = data_buffer
6
+ @cur_pos = 0
7
+ @last_tag = 0
8
+ end
9
+
10
+ def is_at_end?
11
+ @buffer.length == @cur_pos
12
+ end
13
+
14
+ def read_tag
15
+ if is_at_end?
16
+ @last_tag = 0
17
+ return 0
18
+ end
19
+ @last_tag = read_raw_byte
20
+ @last_tag.ord
21
+ end
22
+
23
+ def check_last_tag_was(tag)
24
+ @last_tag.ord == tag
25
+ end
26
+
27
+ def get_last_tag
28
+ @last_tag.ord
29
+ end
30
+
31
+ def read_raw_byte
32
+ raise TableStoreClientError.new("Read raw byte encountered EOF.") if is_at_end?
33
+ pos = @cur_pos
34
+ @cur_pos += 1
35
+ if @buffer[pos].is_a?(Fixnum)
36
+ [@buffer[pos]].chr
37
+ else
38
+ @buffer[pos]
39
+ end
40
+ end
41
+
42
+ def read_raw_little_endian64
43
+ read_bytes(8).unpack('q<')[0]
44
+ end
45
+
46
+ def read_raw_little_endian32
47
+ read_bytes(4).unpack('i<')[0]
48
+ end
49
+
50
+ def read_boolean
51
+ read_bytes(1).unpack('C')[0] == 1
52
+ end
53
+
54
+ def read_double
55
+ read_bytes(8).unpack('q<')[0]
56
+ end
57
+
58
+ def read_int32
59
+ read_bytes(4).unpack('i<')[0]
60
+ end
61
+
62
+ def read_int64
63
+ read_bytes(8).unpack('q<')[0]
64
+ end
65
+
66
+ def read_bytes(size)
67
+ raise TableStoreClientError.new("Read bytes encountered EOF.") if @buffer.length - @cur_pos < size
68
+ tmp_pos = @cur_pos
69
+ @cur_pos += size
70
+ @buffer[tmp_pos, size]
71
+ end
72
+
73
+ def read_utf_string(size)
74
+ raise TableStoreClientError.new("Read bytes encountered EOF.") if @buffer.length - @cur_pos < size
75
+ utf_str = @buffer[@cur_pos, size]
76
+ @cur_pos += size
77
+ utf_str.encode('utf-8') if utf_str.is_a?(String)
78
+ utf_str
79
+ end
80
+
81
+ def last_tag
82
+ @last_tag
83
+ end
84
+
85
+ def cur_pos
86
+ @cur_pos
87
+ end
88
+
89
+ def buffer
90
+ @buffer
91
+ end
92
+ end
@@ -0,0 +1,59 @@
1
+ require 'tablestore/error'
2
+
3
+ class PlainBufferOutputStream
4
+ def initialize(capacity)
5
+ @buffer = []
6
+ @capacity = capacity
7
+ end
8
+
9
+ def is_full?
10
+ @capacity <= @buffer.length
11
+ end
12
+
13
+ def count
14
+ @buffer.length
15
+ end
16
+
17
+ def remain
18
+ @capacity - count
19
+ end
20
+
21
+ def clear
22
+ @buffer.clear
23
+ end
24
+
25
+ def write_raw_byte(value)
26
+ raise TableStoreClientError.new("The buffer is full") if is_full?
27
+ @buffer << [value].pack("C*")
28
+ end
29
+
30
+ def write_raw_little_endian32(value)
31
+ write_bytes([value].pack("i"))
32
+ end
33
+
34
+ def write_raw_little_endian64(value)
35
+ write_bytes([value].pack("q"))
36
+ end
37
+
38
+ def write_double(value)
39
+ write_bytes([value].pack("d"))
40
+ end
41
+
42
+ def write_boolean(value)
43
+ bool_value = value ? 1 : 0
44
+ write_bytes([bool_value].pack("C"))
45
+ end
46
+
47
+ def write_bytes(value)
48
+ raise TableStoreClientError.new("The buffer is full.") if @buffer.length + value.length > @capacity
49
+ bytes = ''
50
+ value.to_s.each_byte do |b|
51
+ bytes += [b].pack("C*")
52
+ end
53
+ @buffer << bytes
54
+ end
55
+
56
+ def get_buffer
57
+ @buffer
58
+ end
59
+ end
@@ -0,0 +1,161 @@
1
+ require 'base64'
2
+
3
+ class OTSProtocol
4
+ $api_version = '2015-12-31'
5
+ $user_agent = 'table-store-ruby'
6
+
7
+ encoder_class = OTSProtoBufferEncoder.new
8
+ decoder_class = OTSProtoBufferDecoder.new
9
+
10
+ $api_list = [
11
+ 'CreateTable',
12
+ 'ListTable',
13
+ 'DeleteTable',
14
+ 'DescribeTable',
15
+ 'UpdateTable',
16
+ 'GetRow',
17
+ 'PutRow',
18
+ 'UpdateRow',
19
+ 'DeleteRow',
20
+ 'BatchGetRow',
21
+ 'BatchWriteRow',
22
+ 'GetRange'
23
+ ]
24
+
25
+ def initialize(user_id, user_key, sts_token, instance_name, encoding, logger)
26
+ @user_id = user_id
27
+ @user_key = user_key
28
+ @sts_token = sts_token
29
+ @instance_name = instance_name
30
+ @encoding = encoding
31
+ @encoder = encoder_class(encoding)
32
+ @decoder = decoder_class(encoding)
33
+ @logger = logger
34
+ end
35
+
36
+ def make_headers_string(headers)
37
+ headers.map{|k,v| "#{k.downcase}:#{v.strip}" if k.include?('x-ots-') and k != 'x-ots-signature'}.sort.join('\n')
38
+ end
39
+
40
+ def call_signature_method(signature_string)
41
+ salt = Digest::SHA1.digest(signature_string)
42
+ Base64.encode64(HMAC::SHA1.digest(UserSecret, salt)).strip
43
+ end
44
+
45
+ def make_request_signature(query, headers)
46
+ signature_string = query + '\n' + 'POST' + '\n\n'
47
+
48
+ headers_string = make_headers_string(headers)
49
+ signature_string += headers_string + '\n'
50
+ call_signature_method(signature_string)
51
+ end
52
+
53
+ def make_headers(body, query)
54
+ md5 = Base64.encode64(Digest::MD5.new.digest(body)).gsub(/\n/, '')
55
+ date = Time.now.strftime('%Y-%m-%dT%H:%M:%S.000Z')
56
+
57
+ headers = {
58
+ 'x-ots-date': date,
59
+ 'x-ots-apiversion': $api_version,
60
+ 'x-ots-accesskeyid': @user_id,
61
+ 'x-ots-instancename': @instance_name,
62
+ 'x-ots-contentmd5': md5,
63
+ }
64
+
65
+ headers['x-ots-ststoken'] = @sts_token if @sts_token.present?
66
+
67
+ signature = make_request_signature(query, headers)
68
+ headers['x-ots-signature'] = signature
69
+ headers['User-Agent'] = $user_agent
70
+ headers
71
+ end
72
+
73
+ def make_response_signature(query, headers)
74
+ uri = query
75
+ headers_string = make_headers_string(headers)
76
+
77
+ signature_string = headers_string + '\n' + uri
78
+ signature = call_signature_method(signature_string)
79
+ signature
80
+ end
81
+
82
+ def check_headers(headers, body, status=nil)
83
+ # check the response headers and process response body if needed.
84
+
85
+ header_names = [
86
+ 'x-ots-contentmd5',
87
+ 'x-ots-requestid',
88
+ 'x-ots-date',
89
+ 'x-ots-contenttype',
90
+ ]
91
+
92
+ if status >= 200 and status < 300
93
+ header_names.each do |name|
94
+ raise TableStoreClientError.new("#{name} is missing in response header.") unless headers.include?name
95
+
96
+ if headers.include?'x-ots-contentmd5'
97
+ md5 = Base64.encode64(Digest::MD5.new.digest(body)).gsub(/\n/, '')
98
+ end
99
+ raise TableStoreClientError.new('MD5 mismatch in response.') if md5 != headers['x-ots-contentmd5']
100
+ end
101
+ end
102
+ end
103
+
104
+ def check_authorization(query, headers, status=nil)
105
+ auth = headers.get('authorization')
106
+ if auth.nil?
107
+ if status >= 200 and status < 300
108
+ raise TableStoreClientError.new('"Authorization" is missing in response header.')
109
+ else
110
+ return
111
+ end
112
+ end
113
+ # 1, check authorization
114
+ unless auth.include?('OTS ')
115
+ raise TableStoreClientError.new('Invalid Authorization in response.')
116
+ end
117
+ # 2, check accessid
118
+ access_id, signature = auth[4..-1].split(':')
119
+ if access_id != self.user_id
120
+ raise TableStoreClientError.new('Invalid accesskeyid in response.')
121
+ end
122
+ # 3, check signature
123
+ # decode the byte type
124
+ if signature != make_response_signature(query, headers)
125
+ raise TableStoreClientError.new('Invalid signature in response.')
126
+ end
127
+ end
128
+
129
+ def make_request(api_name)
130
+ raise TableStoreClientError("API #{api_name} is not supported.") if $api_list.exclude?api_name
131
+ body = encoder.encode_request(api_name, *args)
132
+ query = '/' + api_name
133
+ headers = make_headers(body, query)
134
+ return query, headers, body
135
+ end
136
+
137
+ def get_request_id_string(headers)
138
+ request_id = headers.get('x-ots-requestid')
139
+ request_id = "" if request_id.nil?
140
+ request_id
141
+ end
142
+
143
+ def parse_response(api_name, status, headers, body)
144
+ raise TableStoreClientError.new("API #{api_name} is not supported.") unless api_list.include?(api_name)
145
+ begin
146
+ hash, proto = decoder.decode_response(api_name, body)
147
+ rescue => e
148
+ request_id = get_request_id_string(headers)
149
+ error_message = "Response format is invalid, #{e}, RequestID: #{request_id}, " \
150
+ "HTTP status: #{status}, Body: #{body}."
151
+ self.logger.error(error_message)
152
+ raise TableStoreClientError.new(error_message, status)
153
+ end
154
+ hash
155
+ end
156
+
157
+ # def handle_error(api_name, query, status, reason, headers, body)
158
+ #
159
+ # end
160
+
161
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tablestore-ruby-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - seveninches
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-01-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: protobuf
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: digest-crc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: os
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ description: A simple tablestore gem
70
+ email: lijinghao333@aliyun.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/consts.rb
76
+ - lib/protobuf/ots.proto
77
+ - lib/protobuf/ots_filiter.proto
78
+ - lib/protobuf/ots_filiter_pb.rb
79
+ - lib/protobuf/ots_pb.rb
80
+ - lib/tablestore-ruby-sdk.rb
81
+ - lib/tablestore/connection.rb
82
+ - lib/tablestore/crc8_auto.rb
83
+ - lib/tablestore/error.rb
84
+ - lib/tablestore/main.rb
85
+ - lib/tablestore/metadata.rb
86
+ - lib/tablestore/ots.rb
87
+ - lib/tablestore/plain_buffer_coded_input_stream.rb
88
+ - lib/tablestore/plain_buffer_coded_output_stream.rb
89
+ - lib/tablestore/plain_buffer_crc8.rb
90
+ - lib/tablestore/plain_buffer_input_stream.rb
91
+ - lib/tablestore/plain_buffer_output_stream.rb
92
+ - lib/tablestore/protocol.rb
93
+ homepage: http://rubygems.org/gems/tablestore-ruby-sdk
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.6.10
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: tablestore
117
+ test_files: []