azure 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +36 -0
  3. data/README.md +3 -0
  4. data/Rakefile +81 -0
  5. data/azure.gemspec +20 -9
  6. data/lib/azure.rb +4 -0
  7. data/lib/azure/atom.rb +170 -0
  8. data/lib/azure/auth.rb +29 -0
  9. data/lib/azure/blobs.rb +620 -0
  10. data/lib/azure/blobs/blob.rb +360 -0
  11. data/lib/azure/blobs/container.rb +209 -0
  12. data/lib/azure/blobs/service.rb +396 -0
  13. data/lib/azure/blobs/shared_access_signature.rb +84 -0
  14. data/lib/azure/blobs/uri.rb +60 -0
  15. data/lib/azure/configuration.rb +121 -0
  16. data/lib/azure/core/auth/shared_key.rb +95 -0
  17. data/lib/azure/core/auth/shared_key_lite.rb +34 -0
  18. data/lib/azure/core/collection.rb +118 -0
  19. data/lib/azure/core/service.rb +43 -0
  20. data/lib/azure/core/signer.rb +32 -0
  21. data/lib/azure/core/utils/interval.rb +97 -0
  22. data/lib/azure/core/utils/queryable.rb +74 -0
  23. data/lib/azure/core/utils/storage_service_properties.rb +83 -0
  24. data/lib/azure/core/utils/string.rb +59 -0
  25. data/lib/azure/error.rb +72 -0
  26. data/lib/azure/queues.rb +272 -0
  27. data/lib/azure/queues/message.rb +174 -0
  28. data/lib/azure/queues/queue.rb +187 -0
  29. data/lib/azure/queues/service.rb +263 -0
  30. data/lib/azure/queues/service_properties.rb +152 -0
  31. data/lib/azure/queues/uri.rb +78 -0
  32. data/lib/azure/request.rb +102 -0
  33. data/lib/azure/response.rb +93 -0
  34. data/lib/azure/service_bus.rb +4 -0
  35. data/lib/azure/service_bus/auth/authorizer.rb +22 -0
  36. data/lib/azure/service_bus/auth/uri.rb +52 -0
  37. data/lib/azure/service_bus/auth/wrap.rb +37 -0
  38. data/lib/azure/service_bus/auth/wrap_service.rb +76 -0
  39. data/lib/azure/service_bus/auth/wrap_token.rb +45 -0
  40. data/lib/azure/service_bus/auth/wrap_token_manager.rb +46 -0
  41. data/lib/azure/service_bus/brokered_message.rb +139 -0
  42. data/lib/azure/service_bus/brokered_message_serializer.rb +113 -0
  43. data/lib/azure/service_bus/queues.rb +194 -0
  44. data/lib/azure/service_bus/queues/queue.rb +100 -0
  45. data/lib/azure/service_bus/queues/queue_serializer.rb +51 -0
  46. data/lib/azure/service_bus/queues/service.rb +154 -0
  47. data/lib/azure/service_bus/queues/uri.rb +80 -0
  48. data/lib/azure/service_bus/rules.rb +110 -0
  49. data/lib/azure/service_bus/rules/rule.rb +97 -0
  50. data/lib/azure/service_bus/rules/service.rb +122 -0
  51. data/lib/azure/service_bus/rules/uri.rb +39 -0
  52. data/lib/azure/service_bus/service_bus_service.rb +22 -0
  53. data/lib/azure/service_bus/subscriptions.rb +170 -0
  54. data/lib/azure/service_bus/subscriptions/service.rb +133 -0
  55. data/lib/azure/service_bus/subscriptions/subscription.rb +164 -0
  56. data/lib/azure/service_bus/subscriptions/subscription_serializer.rb +74 -0
  57. data/lib/azure/service_bus/subscriptions/uri.rb +71 -0
  58. data/lib/azure/service_bus/topics.rb +120 -0
  59. data/lib/azure/service_bus/topics/service.rb +98 -0
  60. data/lib/azure/service_bus/topics/topic.rb +122 -0
  61. data/lib/azure/service_bus/topics/topic_serializer.rb +44 -0
  62. data/lib/azure/service_bus/topics/uri.rb +58 -0
  63. data/lib/azure/service_runtime/client/goal_state_pipe_monitor.rb +21 -0
  64. data/lib/azure/service_runtime/client/goal_state_protocol.rb +18 -0
  65. data/lib/azure/service_runtime/client/runtime_client.rb +135 -0
  66. data/lib/azure/service_runtime/deployment.rb +24 -0
  67. data/lib/azure/service_runtime/local_resource.rb +15 -0
  68. data/lib/azure/service_runtime/role.rb +17 -0
  69. data/lib/azure/service_runtime/role_environment.rb +206 -0
  70. data/lib/azure/service_runtime/role_environment_change.rb +32 -0
  71. data/lib/azure/service_runtime/role_instance.rb +35 -0
  72. data/lib/azure/service_runtime/role_instance_endpoint.rb +14 -0
  73. data/lib/azure/tables.rb +215 -0
  74. data/lib/azure/tables/auth/shared_key.rb +71 -0
  75. data/lib/azure/tables/auth/shared_key_lite.rb +30 -0
  76. data/lib/azure/tables/entities_collection.rb +66 -0
  77. data/lib/azure/tables/entity.rb +127 -0
  78. data/lib/azure/tables/service.rb +211 -0
  79. data/lib/azure/tables/table.rb +129 -0
  80. data/lib/azure/tables/tables_collection.rb +62 -0
  81. data/lib/azure/tables/types.rb +65 -0
  82. data/lib/azure/tables/uri.rb +62 -0
  83. data/test/fixtures/32px-fulls-black.jpg +0 -0
  84. data/test/fixtures/all_containers.xml +20 -0
  85. data/test/fixtures/all_tables.xml +22 -0
  86. data/test/fixtures/create_table_response_entry.xml +15 -0
  87. data/test/fixtures/error.xml +5 -0
  88. data/test/fixtures/insert_entity_response_entry.xml +25 -0
  89. data/test/fixtures/messages.xml +12 -0
  90. data/test/fixtures/query_entities_empty_response.xml +7 -0
  91. data/test/fixtures/query_entities_response.xml +45 -0
  92. data/test/fixtures/queue_service_properties.xml +22 -0
  93. data/test/fixtures/queue_service_properties_original.xml +19 -0
  94. data/test/fixtures/queues.xml +16 -0
  95. data/test/fixtures/sb_default_create_queue_response.xml +23 -0
  96. data/test/fixtures/sb_default_create_topic_response.xml +18 -0
  97. data/test/fixtures/sb_get_access_token_response.txt +1 -0
  98. data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
  99. data/test/integration/blobs/auth_test.rb +19 -0
  100. data/test/integration/blobs/blob_test.rb +61 -0
  101. data/test/integration/blobs/clear_page_range_test.rb +19 -0
  102. data/test/integration/blobs/copy_test.rb +33 -0
  103. data/test/integration/blobs/create_blobs_test.rb +51 -0
  104. data/test/integration/blobs/create_container_test.rb +13 -0
  105. data/test/integration/blobs/create_snapshot_test.rb +17 -0
  106. data/test/integration/blobs/delete_blob_snapshots_test.rb +19 -0
  107. data/test/integration/blobs/delete_blobs_test.rb +25 -0
  108. data/test/integration/blobs/delete_container_test.rb +24 -0
  109. data/test/integration/blobs/delete_snapshot_test.rb +17 -0
  110. data/test/integration/blobs/get_blob_snapshot_test.rb +18 -0
  111. data/test/integration/blobs/get_blobs_test.rb +31 -0
  112. data/test/integration/blobs/get_page_range_test.rb +19 -0
  113. data/test/integration/blobs/list_blobs_test.rb +39 -0
  114. data/test/integration/blobs/list_containers_test.rb +28 -0
  115. data/test/integration/blobs/manage_blob_leases_test.rb +45 -0
  116. data/test/integration/blobs/manage_blob_metadata_test.rb +51 -0
  117. data/test/integration/blobs/manage_blob_properties_test.rb +25 -0
  118. data/test/integration/blobs/manage_blob_service_properties_test.rb +38 -0
  119. data/test/integration/blobs/manage_container_metadata_test.rb +46 -0
  120. data/test/integration/blobs/manage_container_permissions_test.rb +17 -0
  121. data/test/integration/blobs/update_page_range_test.rb +20 -0
  122. data/test/integration/queues/clear_messages_test.rb +22 -0
  123. data/test/integration/queues/create_queue_test.rb +13 -0
  124. data/test/integration/queues/delete_message_test.rb +42 -0
  125. data/test/integration/queues/delete_queue_test.rb +24 -0
  126. data/test/integration/queues/get_messages_test.rb +39 -0
  127. data/test/integration/queues/list_queues_test.rb +43 -0
  128. data/test/integration/queues/manage_queue_metadata_test.rb +45 -0
  129. data/test/integration/queues/manage_queue_service_properties_test.rb +27 -0
  130. data/test/integration/queues/peek_messages_test.rb +55 -0
  131. data/test/integration/queues/put_message_test.rb +31 -0
  132. data/test/integration/queues/update_message_test.rb +46 -0
  133. data/test/integration/service_bus/auth_test.rb +18 -0
  134. data/test/integration/service_bus/queues/create_queue_test.rb +25 -0
  135. data/test/integration/service_bus/queues/delete_message_from_queue_test.rb +29 -0
  136. data/test/integration/service_bus/queues/delete_queue_test.rb +25 -0
  137. data/test/integration/service_bus/queues/get_queue_test.rb +23 -0
  138. data/test/integration/service_bus/queues/list_queues_test.rb +39 -0
  139. data/test/integration/service_bus/queues/peek_message_from_queue_test.rb +34 -0
  140. data/test/integration/service_bus/queues/read_and_delete_message_from_queue_test.rb +31 -0
  141. data/test/integration/service_bus/queues/send_message_to_queue_test.rb +22 -0
  142. data/test/integration/service_bus/queues/unlock_message_from_queue_test.rb +36 -0
  143. data/test/integration/service_bus/rules/create_rule_test.rb +19 -0
  144. data/test/integration/service_bus/rules/delete_rule_test.rb +17 -0
  145. data/test/integration/service_bus/rules/get_rule_test.rb +21 -0
  146. data/test/integration/service_bus/rules/list_rules_test.rb +24 -0
  147. data/test/integration/service_bus/rules/rule_test.rb +16 -0
  148. data/test/integration/service_bus/subscriptions/create_subscription_test.rb +25 -0
  149. data/test/integration/service_bus/subscriptions/delete_message_from_subscription_test.rb +31 -0
  150. data/test/integration/service_bus/subscriptions/delete_subscription_test.rb +30 -0
  151. data/test/integration/service_bus/subscriptions/fetch_subscription_test.rb +28 -0
  152. data/test/integration/service_bus/subscriptions/list_subscriptions_test.rb +23 -0
  153. data/test/integration/service_bus/subscriptions/peek_lock_message_from_subscription_test.rb +42 -0
  154. data/test/integration/service_bus/subscriptions/read_delete_message_from_subscription_test.rb +36 -0
  155. data/test/integration/service_bus/subscriptions/subscription_test.rb +31 -0
  156. data/test/integration/service_bus/subscriptions/unlock_message_from_subscription_test.rb +43 -0
  157. data/test/integration/service_bus/topics/create_topic_test.rb +25 -0
  158. data/test/integration/service_bus/topics/delete_topic_test.rb +25 -0
  159. data/test/integration/service_bus/topics/get_topic_test.rb +23 -0
  160. data/test/integration/service_bus/topics/list_topics_test.rb +39 -0
  161. data/test/integration/service_bus/topics/send_message_to_topic_test.rb +23 -0
  162. data/test/integration/tables/auth_test.rb +29 -0
  163. data/test/integration/tables/creating_tables_test.rb +16 -0
  164. data/test/integration/tables/delete_entity_test.rb +39 -0
  165. data/test/integration/tables/deleting_table_test.rb +22 -0
  166. data/test/integration/tables/insert_entity_test.rb +23 -0
  167. data/test/integration/tables/merge_entity_test.rb +28 -0
  168. data/test/integration/tables/query_entities_test.rb +131 -0
  169. data/test/integration/tables/query_tables_test.rb +63 -0
  170. data/test/integration/tables/update_entity_test.rb +54 -0
  171. data/test/integration/test_helper.rb +14 -0
  172. data/test/support/blobs.rb +12 -0
  173. data/test/support/env.rb +5 -0
  174. data/test/support/fixtures.rb +22 -0
  175. data/test/support/stubs.rb +28 -0
  176. data/test/support/table_names.rb +44 -0
  177. data/test/test_helper.rb +10 -0
  178. data/test/unit/atom_test.rb +58 -0
  179. data/test/unit/auth_test.rb +24 -0
  180. data/test/unit/blobs/blob_test.rb +5 -0
  181. data/test/unit/blobs/container_test.rb +67 -0
  182. data/test/unit/blobs/service_test.rb +17 -0
  183. data/test/unit/blobs/shared_access_signature_test.rb +66 -0
  184. data/test/unit/blobs_test.rb +156 -0
  185. data/test/unit/core/service_test.rb +57 -0
  186. data/test/unit/core/utils/interval_test.rb +70 -0
  187. data/test/unit/core/utils/queryable_test.rb +69 -0
  188. data/test/unit/core/utils/storage_service_properties_test.rb +66 -0
  189. data/test/unit/error_test.rb +39 -0
  190. data/test/unit/queues/message_test.rb +40 -0
  191. data/test/unit/queues/queue_test.rb +64 -0
  192. data/test/unit/queues/service_properties.rb +35 -0
  193. data/test/unit/request_test.rb +38 -0
  194. data/test/unit/response_test.rb +43 -0
  195. data/test/unit/service_bus/auth/authorizer_test.rb +27 -0
  196. data/test/unit/service_bus/auth/wrap_token_test.rb +28 -0
  197. data/test/unit/service_bus/queues/queue_test.rb +38 -0
  198. data/test/unit/service_bus/topics/topic_test.rb +33 -0
  199. data/test/unit/service_runtime/data/goalstate.xml +9 -0
  200. data/test/unit/service_runtime/data/roleenvironmentdata.xml +29 -0
  201. data/test/unit/service_runtime/data/runtime.xml +6 -0
  202. data/test/unit/service_runtime/role_environment_test.rb +144 -0
  203. data/test/unit/tables/auth/shared_key_lite_test.rb +39 -0
  204. data/test/unit/tables/auth/shared_key_test.rb +45 -0
  205. data/test/unit/tables/entities_collection_test.rb +39 -0
  206. data/test/unit/tables/entity_test.rb +72 -0
  207. data/test/unit/tables/table_test.rb +57 -0
  208. data/test/unit/tables_test.rb +302 -0
  209. data/test/unit/types_test.rb +67 -0
  210. metadata +310 -47
  211. data/LICENSE +0 -0
  212. data/README +0 -0
@@ -0,0 +1,396 @@
1
+ require "azure/core/service"
2
+ require "azure/configuration"
3
+ require "azure/core/auth/shared_key"
4
+ require "azure/blobs/uri"
5
+ require "mime/types"
6
+ require "uri"
7
+ require "nokogiri"
8
+
9
+ module Azure
10
+ module Blobs
11
+ class Service < Core::Service
12
+ def initialize(signer=Azure::Core::Auth::SharedKey.new)
13
+ super(signer)
14
+ end
15
+ end
16
+
17
+ module Services
18
+ # Get a list of all containers.
19
+ class ListContainers < Service
20
+ # Public: Invoke the service. For now, we force-include the metadata,
21
+ # since it doesn't seem to affect blobs.
22
+ #
23
+ # Returns a Response
24
+ def call
25
+ uri = Blobs::URI.containers("include" => "metadata")
26
+ super(:get, uri)
27
+ end
28
+ end
29
+
30
+ # Create a new container.
31
+ class CreateContainer < Service
32
+ # Public: Invoke the service.
33
+ #
34
+ # name - The name of the new container.
35
+ # metadata - User defined metadata for this container.
36
+ # visibility - Set the container visibility.
37
+ #
38
+ # Returns a Response
39
+ def call(name, metadata, visibility)
40
+ uri = Blobs::URI.container(name)
41
+
42
+ super(:put, uri) do |request|
43
+ metadata.each do |name, value|
44
+ request.headers["x-ms-meta-#{name}"] = value
45
+ end
46
+
47
+ if [Container::CONTAINER, Container::BLOB].include?(visibility)
48
+ request.headers["x-ms-blob-public-access"] = visibility.to_s
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ # Delete a new container.
55
+ class DeleteContainer < Service
56
+ # Public: Invoke the service.
57
+ #
58
+ # name - The name of the container we're deleting.
59
+ #
60
+ # Returns a Response.
61
+ def call(name)
62
+ uri = Blobs::URI.container(name)
63
+ super(:delete, uri)
64
+ end
65
+ end
66
+
67
+ # Get the metadata of a container.
68
+ class GetContainerMetadata < Service
69
+ # Public: Invoke the service.
70
+ #
71
+ # name - The name of the container.
72
+ #
73
+ # Returns a Response.
74
+ def call(name)
75
+ uri = Blobs::URI.container(name, "comp" => "metadata")
76
+ super(:head, uri)
77
+ end
78
+ end
79
+
80
+ # Set the metadata of a container.
81
+ class SetContainerMetadata < Service
82
+ # Public: Invoke the service.
83
+ #
84
+ # name - The name of the container.
85
+ # metadata - User defined metadata for this container.
86
+ #
87
+ # Returns a Response.
88
+ def call(name, metadata)
89
+ uri = Blobs::URI.container(name, "comp" => "metadata")
90
+
91
+ super(:put, uri) do |request|
92
+ metadata.each do |name, value|
93
+ request.headers["x-ms-meta-#{name}"] = value
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ # Creates a new Block Blob, or updates an existent one.
100
+ #
101
+ # container_name - String representing the container name.
102
+ # blob_name - String representing the blob name.
103
+ # filename - String representing a file in the file system.
104
+ # metadata - A Hash representing blob metadata as :name => value.
105
+ #
106
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd179451
107
+ #
108
+ # Returns a Response instance.
109
+ class CreateBlockBlob < Service
110
+ def call(container_name, blob_name, filename, metadata={}, file_class=File)
111
+
112
+ if filename
113
+ raise ArgumentError, "File exceeded 64Mb limit." if file_class.size(filename) > 65536
114
+ file_read = file_class.open(filename) {|f| f.read}
115
+ types = MIME::Types.type_for(filename)
116
+ else
117
+ file_read = nil
118
+ end
119
+
120
+ uri = Blobs::URI.blob(container_name, blob_name)
121
+
122
+ super(:put, uri, file_read) do |request|
123
+ request.headers["Content-Type"] = types.first.to_s if types
124
+ request.headers["x-ms-blob-type"] = "BlockBlob"
125
+ metadata.each do |name, value|
126
+ request.headers["x-ms-meta-#{name}"] = value
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Public: Update a Block Blob.
133
+ class UpdateBlockBlob < CreateBlockBlob; end
134
+
135
+ class PutBlock < Service
136
+ def call(container_name, blob_name, blockid, block_string, headers={})
137
+
138
+ if block_string.bytesize > 4 * 1024
139
+ raise ArgumentError, "block_string is bigger than 4 Mb"
140
+ end
141
+
142
+ uri = Blobs::URI.blob(container_name, blob_name, :comp => "block", :blockid => blockid)
143
+
144
+ super(:put, uri, block_string) do |request|
145
+ request.headers.merge! headers
146
+ request.headers["Content-Type"] = "application/octet-stream"
147
+ end
148
+ end
149
+ end
150
+
151
+ # Creates a new Page Blob, or updates an existent one.
152
+ #
153
+ # container_name - String representing the container name.
154
+ # blob_name - String representing the blob name.
155
+ # size - Size must be aligned to a 512-byte boundary. 1 TB max. (optional)
156
+ # metadata - A Hash representing blob metadata as :name => value. (optional)
157
+ # headers - A Hash to be passed as headers. (optional)
158
+ class CreatePageBlob < Service
159
+ def call(container_name, blob_name, size=1024, metadata={}, headers={})
160
+
161
+ size = 1024 if size.nil?
162
+
163
+ uri = Blobs::URI.blob(container_name, blob_name)
164
+
165
+ super(:put, uri, "") do |request|
166
+ request.headers.merge! headers
167
+ request.headers["x-ms-blob-content-length"] = size.to_s
168
+ request.headers["x-ms-blob-type"] = "PageBlob"
169
+ metadata.each do |name, value|
170
+ request.headers["x-ms-meta-#{name}"] = value
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ # Get Blob Properties
177
+ class GetBlobProperties < Service
178
+ def call(container_name, blob_name, headers)
179
+
180
+ uri = Blobs::URI.blob(container_name, blob_name)
181
+
182
+ super(:head, uri) do |request|
183
+ request.headers.merge! headers
184
+ end
185
+ end
186
+ end
187
+
188
+ # List Blobs.
189
+ #
190
+ # container_name - String representing conainer name.
191
+ class ListBlobs < Service
192
+ def call(container_name)
193
+ uri = Blobs::URI.container(container_name, comp: "list", include: "metadata")
194
+ super(:get, uri)
195
+ end
196
+ end
197
+
198
+ # Delete a Blob.
199
+ #
200
+ # container_name - String representing container name.
201
+ # blob_name - String representing blob name.
202
+ # snapshot_datetime - String datetime representing a snapshot.
203
+ # headers - Custom headers to be used with the request. (optional)
204
+ #
205
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd179413
206
+ class DeleteBlob < Service
207
+ def call(container_name, blob_name, snapshot_datetime, headers={})
208
+
209
+ uri = Blobs::URI.blob(container_name, blob_name)
210
+ uri.query = "snapshot=#{::URI.encode(snapshot_datetime)}" if snapshot_datetime
211
+
212
+ super(:delete, uri) do |request|
213
+ request.headers.merge! headers
214
+ end
215
+ end
216
+ end
217
+
218
+ # Get a Blob.
219
+ #
220
+ # container_name - String representing container name.
221
+ # blob_name - String representing blob name.
222
+ class GetBlob < Service
223
+ def call(container_name, blob_name, snapshot=nil)
224
+ uri = Blobs::URI.blob(container_name, blob_name)
225
+ uri.query = URI.encode("snapshot=#{snapshot}") if snapshot
226
+ super(:get, uri)
227
+ end
228
+ end
229
+
230
+ # Set Blob properties.
231
+ #
232
+ # container_name - String representing name of the blob container.
233
+ # blob_name - String representing name of teh blob.
234
+ # headers - A Hash with the following Optional values
235
+ #
236
+ # http://msdn.microsoft.com/en-us/library/windowsazure/ee691966
237
+ class SetBlobProperties < Service
238
+ def call(container_name, blob_name, headers)
239
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "properties")
240
+ super(:put, uri) do |request|
241
+ request.headers.merge! headers
242
+ end
243
+ end
244
+ end
245
+
246
+ # Set Blob Service Properties
247
+ class SetBlobServiceProperties < Service
248
+ def call(body)
249
+ uri = Blobs::URI.blob("", "", "restype" => "service", "comp" => "properties")
250
+ super(:put, uri, body)
251
+ end
252
+ end
253
+
254
+ # Get Blob Service Properties
255
+ class GetBlobServiceProperties < Service
256
+ def call
257
+ uri = Blobs::URI.blob("", "", "restype" => "service", "comp" => "properties")
258
+ super(:get, uri)
259
+ end
260
+ end
261
+
262
+ # Get Blob Metadata
263
+ #
264
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd179350
265
+ class GetBlobMetadata < Service
266
+ def call(container_name, blob_name, lease_id=nil)
267
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "metadata")
268
+ super(:head, uri) do |request|
269
+ request.headers["x-ms-lease-id"] = lease_id if lease_id
270
+ end
271
+ end
272
+ end
273
+
274
+ # Set Blob Metadata
275
+ #
276
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd179414
277
+ class SetBlobMetadata < Service
278
+ def call(container_name, blob_name, metadata, headers={})
279
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "metadata")
280
+
281
+ super(:put, uri) do |request|
282
+ request.headers.merge! headers
283
+
284
+ metadata.each do |name, value|
285
+ request.headers["x-ms-meta-#{name}"] = value
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ # Put Block List.
292
+ #
293
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd179467
294
+ class PutBlockList < Service
295
+ def call(container_name, blob_name, block_ids, headers={})
296
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "blocklist")
297
+
298
+ builder = Nokogiri::XML::Builder.new(:encoding => "utf-8") do |xml|
299
+ xml.BlockList {
300
+ block_ids.each do |id|
301
+ xml.Latest id
302
+ end
303
+ }
304
+ end
305
+
306
+ super(:put, uri, builder.to_xml.to_s) do |request|
307
+ request.headers.merge!(headers)
308
+ end
309
+ end
310
+ end
311
+
312
+ # Put Page.
313
+ #
314
+ # http://msdn.microsoft.com/en-us/library/windowsazure/ee691975
315
+ class PutPage < Service
316
+ def call(container_name, blob_name, start_byte, end_byte, stream=nil, headers={})
317
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "page")
318
+
319
+ body = stream.respond_to?(:read) ? stream.read : stream
320
+
321
+ super(:put, uri, body) do |request|
322
+ request.headers.merge!(headers)
323
+ request.headers["x-ms-range"] = "bytes=#{start_byte}-#{end_byte}"
324
+ request.headers["Content-Type"] = "application/octet-stream"
325
+ end
326
+ end
327
+ end
328
+
329
+ # Get Page.
330
+ #
331
+ # http://msdn.microsoft.com/en-us/library/windowsazure/ee691973
332
+ class GetPage < Service
333
+ def call(container_name, blob_name, start_byte=nil, end_byte=nil, headers={})
334
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "pagelist")
335
+
336
+ super(:get, uri) do |request|
337
+ request.headers.merge!(headers)
338
+
339
+ if !start_byte.nil? && !end_byte.nil?
340
+ request.headers["x-ms-range"] = "bytes=#{start_byte}-#{end_byte}"
341
+ end
342
+ end
343
+ end
344
+ end
345
+
346
+ # Create Snapshot.
347
+ #
348
+ # http://msdn.microsoft.com/en-us/library/windowsazure/ee691971
349
+ class CreateSnapshot < Service
350
+ def call(container_name, blob_name, metadata={}, headers={})
351
+ uri = Blobs::URI.blob(container_name, blob_name, "comp" => "snapshot")
352
+
353
+ super(:put, uri) do |request|
354
+ request.headers.merge!(headers)
355
+
356
+ metadata.each do |name, value|
357
+ request.headers["x-ms-meta-#{name}"] = value
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ # Copy a Blob.
364
+ #
365
+ # http://msdn.microsoft.com/en-us/library/windowsazure/dd894037
366
+ class CopyBlob < Service
367
+ def call(source_container_name, source_name, dest_container_name, dest_name, snapshot_id=nil, metadata={}, headers={})
368
+ destination_uri = Blobs::URI.blob(dest_container_name, dest_name)
369
+ source_uri = Blobs::URI.blob(source_container_name, source_name)
370
+
371
+ source_uri.query = ::URI.encode("snapshot=#{snapshot_id}") if snapshot_id
372
+
373
+ super(:put, destination_uri) do |request|
374
+ request.headers.merge!(headers)
375
+
376
+ metadata.each do |name, value|
377
+ request.headers["x-ms-meta-#{name}"] = value
378
+ end
379
+
380
+ request.headers["x-ms-copy-source"] = "/#{Azure.config.account_name}#{source_uri.path}"
381
+ end
382
+ end
383
+ end
384
+
385
+ class Lease < Service
386
+ def call(container_name, blob_name, action, lease_id)
387
+ uri = Blobs::URI.blob(container_name, blob_name, :comp => "lease")
388
+ super(:put, uri) do |request|
389
+ request.headers["x-ms-lease-id"] = lease_id if lease_id
390
+ request.headers["x-ms-lease-action"] = action.to_s
391
+ end
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end
@@ -0,0 +1,84 @@
1
+ require "azure/core/signer"
2
+ require "uri"
3
+
4
+ module Azure
5
+ module Blobs
6
+ class SharedAccessSignature
7
+ # Public: Build the signature generator.
8
+ #
9
+ # See this documentation link for further information on shared access
10
+ # signatures:
11
+ #
12
+ # http://msdn.microsoft.com/en-us/library/windowsazure/ee395415.aspx
13
+ #
14
+ # permissions - A valid permissions string.
15
+ # from - A Date or Time object in UTC.
16
+ # to - A Date or Time object in UTC.
17
+ # account_name - The name of the storage account (optional, defaults to
18
+ # the one specified in the configuration).
19
+ # signer - A signer object (optional).
20
+ def initialize(permissions, from, to, id=nil, account_name=Azure.config.account_name, signer=Core::Signer.new)
21
+ @permissions = permissions
22
+ @from = from.iso8601
23
+ @to = to.iso8601
24
+ @id = id
25
+ @account_name = account_name
26
+ @signer = signer
27
+ end
28
+
29
+ # Public: Build the URL for this resource including the shared access
30
+ # signature.
31
+ #
32
+ # resource - Either a container or a blob.
33
+ #
34
+ # Returns a URI.
35
+ def url(resource)
36
+ url = resource.url.dup
37
+ url.query = ::URI.encode_www_form(query_params(resource))
38
+ url
39
+ end
40
+
41
+ # Get the hash of query parameters to use this signature.
42
+ #
43
+ # resource - Either a container or a blob.
44
+ #
45
+ # Returns a Hash with the following keys:
46
+ # - st (start)
47
+ # - se (expiry)
48
+ # - sr (resource)
49
+ # - sp (permissions)
50
+ # - sig (signature)
51
+ # - si (identifier) (optional)
52
+ def query_params(resource)
53
+ params = {
54
+ "st" => @from,
55
+ "se" => @to,
56
+ "sr" => resource.resource_type,
57
+ "sp" => @permissions,
58
+ }
59
+ params["si"] = @id if @id
60
+ params["sig"] = signature(resource.url.path)
61
+ params
62
+ end
63
+
64
+ # Generate the signature for a given resource.
65
+ #
66
+ # resource_path - A String with the URI path to this resource.
67
+ #
68
+ # Returns a signed string.
69
+ def signature(resource_path)
70
+ canonicalized_resource = File.join("/", @account_name, resource_path)
71
+
72
+ string_to_sign = [
73
+ @permissions,
74
+ @from,
75
+ @to,
76
+ canonicalized_resource,
77
+ @id
78
+ ].join("\n")
79
+
80
+ @signer.sign(string_to_sign)
81
+ end
82
+ end
83
+ end
84
+ end