azure-storage 0.10.0.preview

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/lib/azure/storage.rb +58 -0
  3. data/lib/azure/storage/autoload.rb +71 -0
  4. data/lib/azure/storage/blob/append.rb +154 -0
  5. data/lib/azure/storage/blob/blob.rb +821 -0
  6. data/lib/azure/storage/blob/blob_service.rb +510 -0
  7. data/lib/azure/storage/blob/block.rb +264 -0
  8. data/lib/azure/storage/blob/container.rb +552 -0
  9. data/lib/azure/storage/blob/page.rb +380 -0
  10. data/lib/azure/storage/blob/serialization.rb +297 -0
  11. data/lib/azure/storage/client.rb +185 -0
  12. data/lib/azure/storage/configurable.rb +137 -0
  13. data/lib/azure/storage/core.rb +33 -0
  14. data/lib/azure/storage/core/auth/shared_access_signature.rb +27 -0
  15. data/lib/azure/storage/core/auth/shared_access_signature_generator.rb +194 -0
  16. data/lib/azure/storage/core/auth/shared_access_signature_signer.rb +49 -0
  17. data/lib/azure/storage/core/auth/shared_key.rb +125 -0
  18. data/lib/azure/storage/core/auth/shared_key_lite.rb +55 -0
  19. data/lib/azure/storage/core/auth/signer.rb +60 -0
  20. data/lib/azure/storage/core/autoload.rb +35 -0
  21. data/lib/azure/storage/core/client_options.rb +334 -0
  22. data/lib/azure/storage/core/client_options_error.rb +39 -0
  23. data/lib/azure/storage/core/constants.rb +1077 -0
  24. data/lib/azure/storage/core/error.rb +47 -0
  25. data/lib/azure/storage/core/filtered_service.rb +54 -0
  26. data/lib/azure/storage/core/http/debug_filter.rb +45 -0
  27. data/lib/azure/storage/core/http/http_error.rb +95 -0
  28. data/lib/azure/storage/core/http/http_filter.rb +62 -0
  29. data/lib/azure/storage/core/http/http_request.rb +182 -0
  30. data/lib/azure/storage/core/http/http_response.rb +105 -0
  31. data/lib/azure/storage/core/http/retry_policy.rb +83 -0
  32. data/lib/azure/storage/core/http/signer_filter.rb +42 -0
  33. data/lib/azure/storage/core/http_client.rb +63 -0
  34. data/lib/azure/storage/core/service.rb +55 -0
  35. data/lib/azure/storage/core/signed_service.rb +54 -0
  36. data/lib/azure/storage/core/sr.rb +83 -0
  37. data/lib/azure/storage/core/utility.rb +254 -0
  38. data/lib/azure/storage/queue/message.rb +39 -0
  39. data/lib/azure/storage/queue/queue.rb +37 -0
  40. data/lib/azure/storage/queue/queue_service.rb +580 -0
  41. data/lib/azure/storage/queue/serialization.rb +113 -0
  42. data/lib/azure/storage/service/access_policy.rb +35 -0
  43. data/lib/azure/storage/service/cors.rb +36 -0
  44. data/lib/azure/storage/service/cors_rule.rb +46 -0
  45. data/lib/azure/storage/service/enumeration_results.rb +30 -0
  46. data/lib/azure/storage/service/logging.rb +45 -0
  47. data/lib/azure/storage/service/metrics.rb +43 -0
  48. data/lib/azure/storage/service/retention_policy.rb +35 -0
  49. data/lib/azure/storage/service/serialization.rb +308 -0
  50. data/lib/azure/storage/service/signed_identifier.rb +39 -0
  51. data/lib/azure/storage/service/storage_service.rb +131 -0
  52. data/lib/azure/storage/service/storage_service_properties.rb +46 -0
  53. data/lib/azure/storage/table/auth/shared_key.rb +68 -0
  54. data/lib/azure/storage/table/auth/shared_key_lite.rb +53 -0
  55. data/lib/azure/storage/table/batch.rb +339 -0
  56. data/lib/azure/storage/table/batch_response.rb +127 -0
  57. data/lib/azure/storage/table/edmtype.rb +136 -0
  58. data/lib/azure/storage/table/entity.rb +40 -0
  59. data/lib/azure/storage/table/guid.rb +33 -0
  60. data/lib/azure/storage/table/query.rb +121 -0
  61. data/lib/azure/storage/table/serialization.rb +117 -0
  62. data/lib/azure/storage/table/table_service.rb +571 -0
  63. data/lib/azure/storage/version.rb +46 -0
  64. metadata +329 -0
@@ -0,0 +1,39 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'azure/storage/service/access_policy'
25
+
26
+ module Azure::Storage
27
+ module Service
28
+ class SignedIdentifier
29
+
30
+ def initialize
31
+ @access_policy = AccessPolicy.new
32
+ yield self if block_given?
33
+ end
34
+
35
+ attr_accessor :id
36
+ attr_accessor :access_policy
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,131 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+
25
+ require 'azure/storage/core/signed_service'
26
+ require 'azure/storage/core'
27
+ require 'azure/storage/service/storage_service_properties'
28
+
29
+ module Azure::Storage
30
+ module Service
31
+ # A base class for StorageService implementations
32
+ class StorageService < Azure::Core::SignedService
33
+ # Create a new instance of the StorageService
34
+ #
35
+ # @param signer [Azure::Core::Auth::Signer] An implementation of Signer used for signing requests.
36
+ # (optional, Default=Azure::Storage::Auth::SharedKey.new)
37
+ # @param account_name [String] The account name (optional, Default=Azure.config.storage_account_name)
38
+ # @param options [Azure::Storage::Configurable] the client configuration context
39
+ def initialize(signer=Auth::SharedKey.new, account_name=nil, options = {})
40
+ super(signer, account_name, options)
41
+ end
42
+
43
+ def call(method, uri, body=nil, headers={})
44
+ super(method, uri, body, StorageService.service_properties_headers.merge(headers))
45
+ end
46
+
47
+ # Public: Get Storage Service properties
48
+ #
49
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452239
50
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452243
51
+ #
52
+ # Returns a Hash with the service properties or nil if the operation failed
53
+ def get_service_properties
54
+ uri = service_properties_uri
55
+ response = call(:get, uri)
56
+ Serialization.service_properties_from_xml response.body
57
+ end
58
+
59
+ # Public: Set Storage Service properties
60
+ #
61
+ # service_properties - An instance of Azure::Storage::Service::StorageServiceProperties
62
+ #
63
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452235
64
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452232
65
+ #
66
+ # Returns boolean indicating success.
67
+ def set_service_properties(service_properties)
68
+ body = Serialization.service_properties_to_xml service_properties
69
+ uri = service_properties_uri
70
+ call(:put, uri, body)
71
+ nil
72
+ end
73
+
74
+ # Public: Generate the URI for the service properties
75
+ #
76
+ # query - see Azure::Storage::Services::GetServiceProperties#call documentation.
77
+ #
78
+ # Returns a URI.
79
+ def service_properties_uri(query={})
80
+ query.update(restype: 'service', comp: 'properties')
81
+ generate_uri('', query)
82
+ end
83
+
84
+ class << self
85
+ # Adds metadata properties to header hash with required prefix
86
+ #
87
+ # metadata - A Hash of metadata name/value pairs
88
+ # headers - A Hash of HTTP headers
89
+ def add_metadata_to_headers(metadata, headers)
90
+ if metadata
91
+ metadata.each do |key, value|
92
+ headers["x-ms-meta-#{key}"] = value
93
+ end
94
+ end
95
+ end
96
+
97
+ # Adds a value to the Hash object
98
+ #
99
+ # object - A Hash object
100
+ # key - The key name
101
+ # value - The value
102
+ def with_value(object, key, value)
103
+ object[key] = value if value
104
+ end
105
+
106
+ # Adds a header with the value
107
+ #
108
+ # headers - A Hash of HTTP headers
109
+ # name - The header name
110
+ # value - The value
111
+ alias with_header with_value
112
+
113
+ # Adds a query parameter
114
+ #
115
+ # query - A Hash of HTTP query
116
+ # name - The parameter name
117
+ # value - The value
118
+ alias with_query with_value
119
+
120
+ # Declares a default hash object for request headers
121
+ def service_properties_headers
122
+ {
123
+ 'x-ms-version' => Azure::Storage::Default::STG_VERSION,
124
+ 'User-Agent' => Azure::Storage::Default::USER_AGENT
125
+ }
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,46 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'azure/storage/service/logging'
25
+ require 'azure/storage/service/metrics'
26
+ require 'azure/storage/service/cors'
27
+
28
+ module Azure::Storage
29
+ module Service
30
+ class StorageServiceProperties
31
+ def initialize
32
+ @logging = Logging.new
33
+ @hour_metrics = Metrics.new
34
+ @minute_metrics = Metrics.new
35
+ @cors = Cors.new
36
+ yield self if block_given?
37
+ end
38
+
39
+ attr_accessor :logging
40
+ attr_accessor :hour_metrics
41
+ attr_accessor :minute_metrics
42
+ attr_accessor :cors
43
+ attr_accessor :default_service_version
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'cgi'
25
+ require 'azure/storage/core/auth/signer'
26
+
27
+ module Azure::Storage
28
+ module Table
29
+ module Auth
30
+ class SharedKey < Azure::Storage::Auth::SharedKey
31
+ # The account name
32
+ attr :account_name
33
+
34
+ # Generate the string to sign.
35
+ #
36
+ # @param method [Symbol] The HTTP request method.
37
+ # @param uri [URI] The URI of the request we're signing.
38
+ # @param headers [Hash] The HTTP request headers.
39
+ #
40
+ # Returns a plain text string.
41
+ def signable_string(method, uri, headers)
42
+ [
43
+ method.to_s.upcase,
44
+ headers.fetch('Content-MD5', ''),
45
+ headers.fetch('Content-Type', ''),
46
+ headers.fetch('Date') { headers.fetch('x-ms-date') },
47
+ canonicalized_resource(uri)
48
+ ].join("\n")
49
+ end
50
+
51
+ # Calculate the Canonicalized Resource string for a request.
52
+ #
53
+ # @param uri [URI] The request's URI.
54
+ #
55
+ # @return [String] with the canonicalized resource.
56
+ def canonicalized_resource(uri)
57
+ resource = "/#{account_name}#{uri.path}"
58
+
59
+ comp = CGI.parse(uri.query.to_s).fetch('comp', nil)
60
+ resource = [resource, 'comp=' + comp[0]].join('?') if comp
61
+
62
+ resource
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,53 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'azure/storage/table/auth/shared_key'
25
+
26
+ module Azure::Storage
27
+ module Table
28
+ module Auth
29
+ class SharedKeyLite < SharedKey
30
+ # Public: The name of the strategy.
31
+ #
32
+ # Returns a String.
33
+ def name
34
+ 'SharedKeyLite'
35
+ end
36
+
37
+ # Generate the string to sign.
38
+ #
39
+ # verb - The HTTP request method.
40
+ # uri - The URI of the request we're signing.
41
+ # headers - A Hash of HTTP request headers.
42
+ #
43
+ # Returns a plain text string.
44
+ def signable_string(method, uri, headers)
45
+ [
46
+ headers.fetch('Date') { headers.fetch('x-ms-date') },
47
+ canonicalized_resource(uri)
48
+ ].join("\n")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,339 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'uuid'
25
+
26
+ require 'azure/storage/table/serialization'
27
+ require 'azure/storage/table/table_service'
28
+ require 'azure/storage/table/batch_response'
29
+ require 'azure/storage/core/http/http_error'
30
+
31
+ module Azure::Storage
32
+ module Table
33
+ # Represents a batch of table operations.
34
+ #
35
+ # Example usage (block syntax):
36
+ #
37
+ # results = Batch.new "table", "partition" do
38
+ # insert "row1", {"meta"=>"data"}
39
+ # insert "row2", {"meta"=>"data"}
40
+ # end.execute
41
+ #
42
+ # which is equivalent to (fluent syntax):
43
+ #
44
+ # results = Batch.new("table", "partition")
45
+ # .insert("row1", {"meta"=>"data"})
46
+ # .insert("row2", {"meta"=>"data"})
47
+ # .execute
48
+ #
49
+ # which is equivalent to (as class):
50
+ #
51
+ # svc = TableSerice.new
52
+ #
53
+ # batch = Batch.new "table", "partition"
54
+ # batch.insert "row1", {"meta"=>"data"}
55
+ # batch.insert "row2", {"meta"=>"data"}
56
+ #
57
+ # results = svc.execute_batch batch
58
+ #
59
+ class Batch
60
+ def initialize(table, partition, &block)
61
+ @table = table
62
+ @partition = partition
63
+ @operations = []
64
+ @entity_keys = []
65
+ @table_service = Azure::Storage::Table::TableService.new
66
+ uuid = UUID.new
67
+ @batch_id = "batch_" + uuid.generate
68
+ @changeset_id = "changeset_" + uuid.generate
69
+
70
+ self.instance_eval(&block) if block_given?
71
+ end
72
+
73
+ private
74
+ attr_reader :table
75
+ attr_reader :partition
76
+ attr_reader :table_service
77
+
78
+ attr_accessor :operations
79
+ attr_accessor :entity_keys
80
+ attr_accessor :changeset_id
81
+
82
+ public
83
+ attr_accessor :batch_id
84
+
85
+ protected
86
+ def execute
87
+ @table_service.execute_batch(self)
88
+ end
89
+
90
+ protected
91
+ class ResponseWrapper
92
+ def initialize(hash)
93
+ @hash = hash
94
+ end
95
+
96
+ def uri
97
+ @hash[:uri]
98
+ end
99
+
100
+ def status_code
101
+ @hash[:status_code].to_i
102
+ end
103
+
104
+ def body
105
+ @hash[:body]
106
+ end
107
+ end
108
+
109
+ protected
110
+ def add_operation(method, uri, body=nil, headers=nil)
111
+ op = {
112
+ :method => method,
113
+ :uri => uri,
114
+ :body => body,
115
+ :headers => headers
116
+ }
117
+ operations.push op
118
+ end
119
+
120
+ protected
121
+ def check_entity_key(key)
122
+ raise ArgumentError, "Only allowed to perform a single operation per entity, and there is already a operation registered in this batch for the key: #{key}." if entity_keys.include? key
123
+ entity_keys.push key
124
+ end
125
+
126
+ public
127
+ def parse_response(response)
128
+ responses = BatchResponse.parse response.body
129
+ new_responses = []
130
+
131
+ (0..responses.length-1).each { |index|
132
+ operation = operations[index]
133
+ response = responses[index]
134
+
135
+ if response[:status_code].to_i > 299
136
+ # failed
137
+ error = Azure::Core::Http::HTTPError.new(ResponseWrapper.new(response.merge({:uri=>operation[:uri]})))
138
+ error.description = response[:message] if (error.description || '').strip == ''
139
+ raise error
140
+ else
141
+ # success
142
+ case operation[:method]
143
+ when :post
144
+ # entity from body
145
+ result = Azure::Storage::Table::Serialization.hash_from_entry_xml(response[:body])
146
+
147
+ entity = Azure::Storage::Table::Entity.new
148
+ entity.table = table
149
+ entity.updated = result[:updated]
150
+ entity.etag = response[:headers]["etag"] || result[:etag]
151
+ entity.properties = result[:properties]
152
+
153
+ new_responses.push entity
154
+ when :put, :merge
155
+ # etag from headers
156
+ new_responses.push response[:headers]["etag"]
157
+ when :delete
158
+ # true
159
+ new_responses.push nil
160
+ end
161
+ end
162
+ }
163
+
164
+ new_responses
165
+ end
166
+
167
+ public
168
+ def to_body
169
+ body = ""
170
+ body.define_singleton_method(:add_line) do |a| self << (a||nil) + "\n" end
171
+
172
+ body.add_line "--#{batch_id}"
173
+ body.add_line "Content-Type: multipart/mixed; boundary=#{changeset_id}"
174
+ body.add_line ""
175
+
176
+ content_id = 1
177
+ operations.each { |op|
178
+ body.add_line "--#{changeset_id}"
179
+ body.add_line "Content-Type: application/http"
180
+ body.add_line "Content-Transfer-Encoding: binary"
181
+ body.add_line ""
182
+ body.add_line "#{op[:method].to_s.upcase} #{op[:uri]} HTTP/1.1"
183
+ body.add_line "Content-ID: #{content_id}"
184
+
185
+ if op[:headers]
186
+ op[:headers].each { |k,v|
187
+ body.add_line "#{k}: #{v}"
188
+ }
189
+ end
190
+
191
+ if op[:body]
192
+ body.add_line "Content-Type: application/atom+xml;type=entry"
193
+ body.add_line "Content-Length: #{op[:body].bytesize.to_s}"
194
+ body.add_line ""
195
+ body.add_line op[:body]
196
+ else
197
+ body.add_line ""
198
+ end
199
+
200
+ content_id += 1
201
+ }
202
+ body.add_line "--#{changeset_id}--"
203
+ body.add_line "--#{batch_id}--"
204
+ end
205
+
206
+ # Public: Inserts new entity to the table.
207
+ #
208
+ # ==== Attributes
209
+ #
210
+ # * +row_key+ - String. The row key
211
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
212
+ #
213
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179433
214
+ public
215
+ def insert(row_key, entity_values)
216
+ check_entity_key(row_key)
217
+
218
+ body = Azure::Storage::Table::Serialization.hash_to_entry_xml({
219
+ "PartitionKey" => partition,
220
+ "RowKey" => row_key
221
+ }.merge(entity_values) ).to_xml
222
+
223
+ add_operation(:post, @table_service.entities_uri(table), body)
224
+ self
225
+ end
226
+
227
+ # Public: Updates an existing entity in a table. The Update Entity operation replaces
228
+ # the entire entity and can be used to remove properties.
229
+ #
230
+ # ==== Attributes
231
+ #
232
+ # * +row_key+ - String. The row key
233
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
234
+ # * +options+ - Hash. Optional parameters.
235
+ #
236
+ # ==== Options
237
+ #
238
+ # Accepted key/value pairs in options parameter are:
239
+ # * :if_match - String. A matching condition which is required for update (optional, Default="*")
240
+ # * :create_if_not_exists - Boolean. If true, and partition_key and row_key do not reference and existing entity,
241
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
242
+ #
243
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179427
244
+ public
245
+ def update(row_key, entity_values, options={})
246
+ check_entity_key(row_key)
247
+
248
+ uri = @table_service.entities_uri(table, partition, row_key)
249
+
250
+ headers = {}
251
+ headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
252
+
253
+ body = Azure::Storage::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
254
+
255
+ add_operation(:put, uri, body, headers)
256
+ self
257
+ end
258
+
259
+ # Public: Updates an existing entity by updating the entity's properties. This operation
260
+ # does not replace the existing entity, as the update_entity operation does.
261
+ #
262
+ # ==== Attributes
263
+ #
264
+ # * +row_key+ - String. The row key
265
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
266
+ # * +options+ - Hash. Optional parameters.
267
+ #
268
+ # ==== Options
269
+ #
270
+ # Accepted key/value pairs in options parameter are:
271
+ # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
272
+ # * +create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
273
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
274
+ #
275
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179392
276
+ public
277
+ def merge(row_key, entity_values, options={})
278
+ check_entity_key(row_key)
279
+
280
+ uri = @table_service.entities_uri(table, partition, row_key)
281
+
282
+ headers = {}
283
+ headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
284
+
285
+ body = Azure::Storage::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
286
+
287
+ add_operation(:merge, uri, body, headers)
288
+ self
289
+ end
290
+
291
+ # Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
292
+ #
293
+ # ==== Attributes
294
+ #
295
+ # * +row_key+ - String. The row key
296
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
297
+ #
298
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452241
299
+ public
300
+ def insert_or_merge(row_key, entity_values)
301
+ merge(row_key, entity_values, { :create_if_not_exists => true })
302
+ self
303
+ end
304
+
305
+ # Public: Inserts or updates a new entity into a table.
306
+ #
307
+ # ==== Attributes
308
+ #
309
+ # * +row_key+ - String. The row key
310
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
311
+ #
312
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452242
313
+ public
314
+ def insert_or_replace(row_key, entity_values)
315
+ update(row_key, entity_values, { :create_if_not_exists => true })
316
+ self
317
+ end
318
+
319
+ # Public: Deletes an existing entity in the table.
320
+ #
321
+ # ==== Attributes
322
+ #
323
+ # * +row_key+ - String. The row key
324
+ # * +options+ - Hash. Optional parameters.
325
+ #
326
+ # ==== Options
327
+ #
328
+ # Accepted key/value pairs in options parameter are:
329
+ # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
330
+ #
331
+ # See http://msdn.microsoft.com/en-us/library/azure/dd135727
332
+ public
333
+ def delete(row_key, options={})
334
+ add_operation(:delete, @table_service.entities_uri(table, partition, row_key), nil, {"If-Match"=> options[:if_match] || "*"})
335
+ self
336
+ end
337
+ end
338
+ end
339
+ end