azure 0.0.0 → 0.1.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.
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