azurex 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (299) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +11 -0
  4. data/ChangeLog.txt +40 -0
  5. data/Gemfile +16 -0
  6. data/README.md +606 -0
  7. data/Rakefile +125 -0
  8. data/azurex.gemspec +47 -0
  9. data/lib/azure.rb +52 -0
  10. data/lib/azure/base_management/affinity_group.rb +32 -0
  11. data/lib/azure/base_management/base_management_service.rb +238 -0
  12. data/lib/azure/base_management/location.rb +27 -0
  13. data/lib/azure/base_management/management_http_request.rb +244 -0
  14. data/lib/azure/base_management/serialization.rb +129 -0
  15. data/lib/azure/base_management/sql_management_http_request.rb +45 -0
  16. data/lib/azure/blob/blob.rb +32 -0
  17. data/lib/azure/blob/blob_service.rb +1424 -0
  18. data/lib/azure/blob/block.rb +31 -0
  19. data/lib/azure/blob/container.rb +32 -0
  20. data/lib/azure/blob/serialization.rb +285 -0
  21. data/lib/azure/cloud_service_management/cloud_service.rb +38 -0
  22. data/lib/azure/cloud_service_management/cloud_service_management_service.rb +361 -0
  23. data/lib/azure/cloud_service_management/configuration_set.rb +28 -0
  24. data/lib/azure/cloud_service_management/deployment.rb +64 -0
  25. data/lib/azure/cloud_service_management/input_endpoint.rb +29 -0
  26. data/lib/azure/cloud_service_management/instance_endpoint.rb +31 -0
  27. data/lib/azure/cloud_service_management/persistent_vm_downtime.rb +29 -0
  28. data/lib/azure/cloud_service_management/role.rb +30 -0
  29. data/lib/azure/cloud_service_management/role_instance.rb +40 -0
  30. data/lib/azure/cloud_service_management/serialization.rb +329 -0
  31. data/lib/azure/cloud_service_management/virtual_ip.rb +29 -0
  32. data/lib/azure/core.rb +39 -0
  33. data/lib/azure/core/auth/authorizer.rb +36 -0
  34. data/lib/azure/core/auth/shared_key.rb +110 -0
  35. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  36. data/lib/azure/core/auth/signer.rb +48 -0
  37. data/lib/azure/core/configuration.rb +211 -0
  38. data/lib/azure/core/error.rb +22 -0
  39. data/lib/azure/core/filtered_service.rb +44 -0
  40. data/lib/azure/core/http/debug_filter.rb +36 -0
  41. data/lib/azure/core/http/http_error.rb +88 -0
  42. data/lib/azure/core/http/http_filter.rb +53 -0
  43. data/lib/azure/core/http/http_request.rb +159 -0
  44. data/lib/azure/core/http/http_response.rb +140 -0
  45. data/lib/azure/core/http/retry_policy.rb +74 -0
  46. data/lib/azure/core/http/signer_filter.rb +34 -0
  47. data/lib/azure/core/service.rb +63 -0
  48. data/lib/azure/core/signed_service.rb +43 -0
  49. data/lib/azure/core/utility.rb +190 -0
  50. data/lib/azure/queue/message.rb +30 -0
  51. data/lib/azure/queue/queue.rb +29 -0
  52. data/lib/azure/queue/queue_service.rb +568 -0
  53. data/lib/azure/queue/serialization.rb +106 -0
  54. data/lib/azure/service/access_policy.rb +26 -0
  55. data/lib/azure/service/enumeration_results.rb +21 -0
  56. data/lib/azure/service/logging.rb +32 -0
  57. data/lib/azure/service/metrics.rb +31 -0
  58. data/lib/azure/service/retention_policy.rb +25 -0
  59. data/lib/azure/service/serialization.rb +240 -0
  60. data/lib/azure/service/signed_identifier.rb +30 -0
  61. data/lib/azure/service/storage_service.rb +79 -0
  62. data/lib/azure/service/storage_service_properties.rb +32 -0
  63. data/lib/azure/service_bus/action.rb +21 -0
  64. data/lib/azure/service_bus/auth/wrap_service.rb +89 -0
  65. data/lib/azure/service_bus/auth/wrap_signer.rb +69 -0
  66. data/lib/azure/service_bus/brokered_message.rb +124 -0
  67. data/lib/azure/service_bus/brokered_message_serializer.rb +159 -0
  68. data/lib/azure/service_bus/correlation_filter.rb +45 -0
  69. data/lib/azure/service_bus/empty_rule_action.rb +30 -0
  70. data/lib/azure/service_bus/false_filter.rb +38 -0
  71. data/lib/azure/service_bus/filter.rb +21 -0
  72. data/lib/azure/service_bus/interval.rb +104 -0
  73. data/lib/azure/service_bus/queue.rb +230 -0
  74. data/lib/azure/service_bus/resource.rb +109 -0
  75. data/lib/azure/service_bus/rule.rb +98 -0
  76. data/lib/azure/service_bus/rule_aspect.rb +34 -0
  77. data/lib/azure/service_bus/serialization.rb +160 -0
  78. data/lib/azure/service_bus/service_bus_service.rb +829 -0
  79. data/lib/azure/service_bus/sql_filter.rb +50 -0
  80. data/lib/azure/service_bus/sql_rule_action.rb +50 -0
  81. data/lib/azure/service_bus/subscription.rb +184 -0
  82. data/lib/azure/service_bus/topic.rb +187 -0
  83. data/lib/azure/service_bus/true_filter.rb +38 -0
  84. data/lib/azure/sql_database_management/serialization.rb +111 -0
  85. data/lib/azure/sql_database_management/sql_database.rb +31 -0
  86. data/lib/azure/sql_database_management/sql_database_management_service.rb +200 -0
  87. data/lib/azure/storage_management/serialization.rb +206 -0
  88. data/lib/azure/storage_management/storage_account.rb +47 -0
  89. data/lib/azure/storage_management/storage_management_service.rb +211 -0
  90. data/lib/azure/table/auth/shared_key.rb +92 -0
  91. data/lib/azure/table/auth/shared_key_lite.rb +44 -0
  92. data/lib/azure/table/batch.rb +330 -0
  93. data/lib/azure/table/batch_response.rb +118 -0
  94. data/lib/azure/table/edmtype.rb +127 -0
  95. data/lib/azure/table/entity.rb +31 -0
  96. data/lib/azure/table/guid.rb +24 -0
  97. data/lib/azure/table/query.rb +112 -0
  98. data/lib/azure/table/serialization.rb +108 -0
  99. data/lib/azure/table/table_service.rb +560 -0
  100. data/lib/azure/version.rb +31 -0
  101. data/lib/azure/virtual_machine_image_management/serialization.rb +52 -0
  102. data/lib/azure/virtual_machine_image_management/virtual_machine_disk.rb +25 -0
  103. data/lib/azure/virtual_machine_image_management/virtual_machine_image.rb +25 -0
  104. data/lib/azure/virtual_machine_image_management/virtual_machine_image_management_service.rb +66 -0
  105. data/lib/azure/virtual_machine_management/serialization.rb +450 -0
  106. data/lib/azure/virtual_machine_management/virtual_machine.rb +45 -0
  107. data/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +562 -0
  108. data/lib/azure/virtual_network_management/serialization.rb +192 -0
  109. data/lib/azure/virtual_network_management/virtual_network.rb +37 -0
  110. data/lib/azure/virtual_network_management/virtual_network_management_service.rb +109 -0
  111. data/test/fixtures/32px-fulls-black.jpg +0 -0
  112. data/test/fixtures/affinity_group.xml +33 -0
  113. data/test/fixtures/all_containers.xml +20 -0
  114. data/test/fixtures/all_tables.xml +22 -0
  115. data/test/fixtures/certificate.pem +21 -0
  116. data/test/fixtures/container_acl.xml +11 -0
  117. data/test/fixtures/create_sql_database_server.xml +2 -0
  118. data/test/fixtures/create_storage_desc_error.xml +5 -0
  119. data/test/fixtures/create_storage_extendedprop_error.xml +8 -0
  120. data/test/fixtures/create_storage_extendedpropname_error.xml +6 -0
  121. data/test/fixtures/create_storage_full_error.xml +6 -0
  122. data/test/fixtures/create_storage_label_error.xml +5 -0
  123. data/test/fixtures/create_storage_location_error.xml +5 -0
  124. data/test/fixtures/create_storage_name_error.xml +6 -0
  125. data/test/fixtures/create_table_response_entry.xml +15 -0
  126. data/test/fixtures/delete_storage_container_error.xml +5 -0
  127. data/test/fixtures/delete_storage_error.xml +5 -0
  128. data/test/fixtures/deployment_error.xml +5 -0
  129. data/test/fixtures/empty_xml_file +0 -0
  130. data/test/fixtures/get_deployment.xml +94 -0
  131. data/test/fixtures/get_deployment_existing.xml +94 -0
  132. data/test/fixtures/get_deployment_missing.xml +5 -0
  133. data/test/fixtures/get_storage_account_error.xml +5 -0
  134. data/test/fixtures/get_storage_account_properties.xml +32 -0
  135. data/test/fixtures/get_storage_account_properties_new.xml +32 -0
  136. data/test/fixtures/http_error.xml +5 -0
  137. data/test/fixtures/insert_entity_response_entry.xml +25 -0
  138. data/test/fixtures/list_affinity_groups.xml +22 -0
  139. data/test/fixtures/list_blobs.xml +121 -0
  140. data/test/fixtures/list_block_all_with_none_committed.xml +22 -0
  141. data/test/fixtures/list_blocks_all.xml +23 -0
  142. data/test/fixtures/list_blocks_committed.xml +13 -0
  143. data/test/fixtures/list_cloud_services.xml +39 -0
  144. data/test/fixtures/list_containers.xml +38 -0
  145. data/test/fixtures/list_firewall_management_endpoint.xml +27 -0
  146. data/test/fixtures/list_images.xml +110 -0
  147. data/test/fixtures/list_locations.xml +62 -0
  148. data/test/fixtures/list_page_ranges.xml +11 -0
  149. data/test/fixtures/list_sql_database.xml +36 -0
  150. data/test/fixtures/list_sql_server_firewall.xml +23 -0
  151. data/test/fixtures/list_storage_account_single.xml +25 -0
  152. data/test/fixtures/list_storage_accounts.xml +46 -0
  153. data/test/fixtures/list_virtual_networks.xml +92 -0
  154. data/test/fixtures/logging.xml +11 -0
  155. data/test/fixtures/management_certificate.pem +55 -0
  156. data/test/fixtures/messages.xml +12 -0
  157. data/test/fixtures/metrics.xml +10 -0
  158. data/test/fixtures/privatekey.key +28 -0
  159. data/test/fixtures/query_entities_empty_response.xml +7 -0
  160. data/test/fixtures/query_entities_response.xml +45 -0
  161. data/test/fixtures/queue_service_properties.xml +22 -0
  162. data/test/fixtures/queue_service_properties_original.xml +19 -0
  163. data/test/fixtures/queues.xml +16 -0
  164. data/test/fixtures/retention_policy.xml +5 -0
  165. data/test/fixtures/sb_default_create_queue_response.xml +23 -0
  166. data/test/fixtures/sb_default_create_topic_response.xml +18 -0
  167. data/test/fixtures/sb_get_access_token_response.txt +1 -0
  168. data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
  169. data/test/fixtures/storage_service_keys.xml +8 -0
  170. data/test/fixtures/storage_service_properties.xml +23 -0
  171. data/test/fixtures/update_storage_account.xml +16 -0
  172. data/test/fixtures/update_storage_error.xml +5 -0
  173. data/test/fixtures/updated_storage_accounts.xml +53 -0
  174. data/test/fixtures/virtual_machine.xml +115 -0
  175. data/test/fixtures/windows_virtual_machine.xml +106 -0
  176. data/test/integration/affinity_group/Affinity_test.rb +55 -0
  177. data/test/integration/affinity_group/Create_Affinity_test.rb +63 -0
  178. data/test/integration/affinity_group/Delete_Affinity_test.rb +56 -0
  179. data/test/integration/affinity_group/List_Affinity_test.rb +41 -0
  180. data/test/integration/affinity_group/Update_Affinity_test.rb +82 -0
  181. data/test/integration/blob/blob_gb18030_test.rb +199 -0
  182. data/test/integration/blob/blob_metadata_test.rb +75 -0
  183. data/test/integration/blob/blob_pages_test.rb +119 -0
  184. data/test/integration/blob/blob_properties_test.rb +77 -0
  185. data/test/integration/blob/block_blob_test.rb +254 -0
  186. data/test/integration/blob/container/container_acl_test.rb +69 -0
  187. data/test/integration/blob/container/container_metadata_test.rb +50 -0
  188. data/test/integration/blob/container/create_container_test.rb +60 -0
  189. data/test/integration/blob/container/delete_container_test.rb +39 -0
  190. data/test/integration/blob/container/get_container_properties_test.rb +48 -0
  191. data/test/integration/blob/container/list_containers_test.rb +79 -0
  192. data/test/integration/blob/container/root_container_test.rb +54 -0
  193. data/test/integration/blob/copy_blob_test.rb +113 -0
  194. data/test/integration/blob/create_blob_snapshot_test.rb +80 -0
  195. data/test/integration/blob/create_page_blob_test.rb +83 -0
  196. data/test/integration/blob/delete_blob_test.rb +159 -0
  197. data/test/integration/blob/get_blob_test.rb +65 -0
  198. data/test/integration/blob/informative_errors_test.rb +39 -0
  199. data/test/integration/blob/lease/acquire_lease_test.rb +36 -0
  200. data/test/integration/blob/lease/break_lease_test.rb +40 -0
  201. data/test/integration/blob/lease/release_lease_test.rb +40 -0
  202. data/test/integration/blob/lease/renew_lease_test.rb +42 -0
  203. data/test/integration/blob/list_blobs_test.rb +113 -0
  204. data/test/integration/cloud_service/Cloud_Create_test.rb +44 -0
  205. data/test/integration/cloud_service/Cloud_Delete_test.rb +44 -0
  206. data/test/integration/database/create_sql_server_firewall_test.rb +86 -0
  207. data/test/integration/database/create_sql_server_test.rb +53 -0
  208. data/test/integration/database/delete_sql_server_firewall_test.rb +70 -0
  209. data/test/integration/database/delete_sql_server_test.rb +58 -0
  210. data/test/integration/database/list_sql_server_firewall_test.rb +45 -0
  211. data/test/integration/database/list_sql_servers_test.rb +44 -0
  212. data/test/integration/database/reset_password_sql_server_test.rb +55 -0
  213. data/test/integration/location/Location_List_test.rb +39 -0
  214. data/test/integration/queue/clear_messages_test.rb +42 -0
  215. data/test/integration/queue/create_message_test.rb +75 -0
  216. data/test/integration/queue/create_queue_test.rb +50 -0
  217. data/test/integration/queue/delete_message_test.rb +67 -0
  218. data/test/integration/queue/delete_queue_test.rb +45 -0
  219. data/test/integration/queue/informative_errors_test.rb +42 -0
  220. data/test/integration/queue/list_messages_encoded_test.rb +79 -0
  221. data/test/integration/queue/list_messages_test.rb +79 -0
  222. data/test/integration/queue/list_queues_test.rb +44 -0
  223. data/test/integration/queue/peek_messages_test.rb +59 -0
  224. data/test/integration/queue/queue_gb18030_test.rb +131 -0
  225. data/test/integration/queue/queue_metadata_test.rb +40 -0
  226. data/test/integration/queue/update_message_test.rb +74 -0
  227. data/test/integration/service_bus/informative_errors_test.rb +37 -0
  228. data/test/integration/service_bus/queues_scenario_test.rb +200 -0
  229. data/test/integration/service_bus/queues_test.rb +266 -0
  230. data/test/integration/service_bus/rules_test.rb +145 -0
  231. data/test/integration/service_bus/sb_queue_gb18030_test.rb +182 -0
  232. data/test/integration/service_bus/scenario_test.rb +101 -0
  233. data/test/integration/service_bus/subscriptions_test.rb +211 -0
  234. data/test/integration/service_bus/topics_scenario_test.rb +406 -0
  235. data/test/integration/service_bus/topics_test.rb +129 -0
  236. data/test/integration/storage_management/storage_management_test.rb +177 -0
  237. data/test/integration/table/create_table_test.rb +36 -0
  238. data/test/integration/table/delete_entity_batch_test.rb +107 -0
  239. data/test/integration/table/delete_entity_test.rb +94 -0
  240. data/test/integration/table/delete_table_test.rb +40 -0
  241. data/test/integration/table/get_table_test.rb +37 -0
  242. data/test/integration/table/informative_errors_test.rb +39 -0
  243. data/test/integration/table/insert_entity_batch_test.rb +100 -0
  244. data/test/integration/table/insert_entity_test.rb +88 -0
  245. data/test/integration/table/insert_or_merge_entity_batch_test.rb +159 -0
  246. data/test/integration/table/insert_or_merge_entity_test.rb +143 -0
  247. data/test/integration/table/insert_or_replace_entity_batch_test.rb +152 -0
  248. data/test/integration/table/insert_or_replace_entity_test.rb +137 -0
  249. data/test/integration/table/merge_entity_batch_test.rb +128 -0
  250. data/test/integration/table/merge_entity_test.rb +113 -0
  251. data/test/integration/table/query_entities_test.rb +195 -0
  252. data/test/integration/table/query_tables_test.rb +43 -0
  253. data/test/integration/table/query_test.rb +251 -0
  254. data/test/integration/table/table_acl_test.rb +52 -0
  255. data/test/integration/table/table_gb18030_test.rb +355 -0
  256. data/test/integration/table/update_entity_batch_test.rb +149 -0
  257. data/test/integration/table/update_entity_test.rb +131 -0
  258. data/test/integration/test_helper.rb +42 -0
  259. data/test/integration/vm/VM_Create_test.rb +260 -0
  260. data/test/integration/vm/VM_Delete_test.rb +53 -0
  261. data/test/integration/vm/VM_Operations_test.rb +172 -0
  262. data/test/integration/vm_image/virtual_machine_disk_test.rb +37 -0
  263. data/test/integration/vm_image/virtual_machine_image_test.rb +37 -0
  264. data/test/integration/vnet/Virtual_Network_Create_test.rb +116 -0
  265. data/test/integration/vnet/Virtual_Network_list_test.rb +48 -0
  266. data/test/support/env.rb +19 -0
  267. data/test/support/fixtures.rb +36 -0
  268. data/test/support/name_generator.rb +160 -0
  269. data/test/support/stubs.rb +42 -0
  270. data/test/support/virtual_machine_name_generator.rb +102 -0
  271. data/test/support/virtual_network_helper.rb +73 -0
  272. data/test/test_helper.rb +53 -0
  273. data/test/unit/affinity_group/affinity_group_test.rb +192 -0
  274. data/test/unit/affinity_group/serialization_test.rb +88 -0
  275. data/test/unit/base_management/location_test.rb +57 -0
  276. data/test/unit/blob/blob_service_test.rb +1947 -0
  277. data/test/unit/cloud_service_management/cloud_service_management_service_test.rb +248 -0
  278. data/test/unit/cloud_service_management/serialization_test.rb +169 -0
  279. data/test/unit/core/auth/shared_key_lite_test.rb +51 -0
  280. data/test/unit/core/auth/shared_key_test.rb +58 -0
  281. data/test/unit/core/auth/signer_test.rb +30 -0
  282. data/test/unit/core/http/http_error_test.rb +57 -0
  283. data/test/unit/core/http/http_request_test.rb +66 -0
  284. data/test/unit/core/http/http_response_test.rb +45 -0
  285. data/test/unit/core/http/retry_policy_test.rb +23 -0
  286. data/test/unit/database/serialization_test.rb +97 -0
  287. data/test/unit/database/sql_database_server_service_test.rb +288 -0
  288. data/test/unit/service/serialization_test.rb +502 -0
  289. data/test/unit/service/storage_service_test.rb +291 -0
  290. data/test/unit/storage_management/serialization_test.rb +245 -0
  291. data/test/unit/storage_management/storage_management_service_test.rb +261 -0
  292. data/test/unit/table/edmtype_test.rb +108 -0
  293. data/test/unit/virtual_machine_image_management/serialization_test.rb +35 -0
  294. data/test/unit/virtual_machine_image_management/virtual_machine_image_management_service_test.rb +65 -0
  295. data/test/unit/virtual_machine_management/serialization_test.rb +256 -0
  296. data/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +442 -0
  297. data/test/unit/vnet/serialization_test.rb +187 -0
  298. data/test/unit/vnet/virtual_network_management_service_test.rb +131 -0
  299. metadata +471 -0
@@ -0,0 +1,32 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+
16
+ module Azure
17
+ module Blob
18
+ class Blob
19
+
20
+ def initialize
21
+ @properties = {}
22
+ @metadata = {}
23
+ yield self if block_given?
24
+ end
25
+
26
+ attr_accessor :name
27
+ attr_accessor :snapshot
28
+ attr_accessor :properties
29
+ attr_accessor :metadata
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,1424 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/service/storage_service'
16
+ require 'azure/blob/serialization'
17
+ require 'base64'
18
+
19
+ module Azure
20
+ module Blob
21
+ class BlobService < Service::StorageService
22
+
23
+ def initialize
24
+ super()
25
+ @host = Azure.config.storage_blob_host
26
+ end
27
+
28
+ # Public: Get a list of Containers from the server
29
+ #
30
+ # ==== Attributes
31
+ #
32
+ # * +options+ - Hash. Optional parameters.
33
+ #
34
+ # ==== Options
35
+ #
36
+ # Accepted key/value pairs in options parameter are:
37
+ # * +:prefix+ - String. Filters the results to return only containers
38
+ # whose name begins with the specified prefix. (optional)
39
+ #
40
+ # * +:marker+ - String. An identifier the specifies the portion of the
41
+ # list to be returned. This value comes from the property
42
+ # Azure::Service::EnumerationResults.continuation_token when there
43
+ # are more containers available than were returned. The
44
+ # marker value may then be used here to request the next set
45
+ # of list items. (optional)
46
+ #
47
+ # * +:max_results+ - Integer. Specifies the maximum number of containers to return.
48
+ # If max_results is not specified, or is a value greater than
49
+ # 5,000, the server will return up to 5,000 items. If it is set
50
+ # to a value less than or equal to zero, the server will return
51
+ # status code 400 (Bad Request). (optional)
52
+ #
53
+ # * +:metadata+ - Boolean. Specifies whether or not to return the container metadata.
54
+ # (optional, Default=false)
55
+ #
56
+ # * +:timeout+ - Integer. A timeout in seconds.
57
+ #
58
+ # NOTE: Metadata requested with the :metadata parameter must have been stored in
59
+ # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob
60
+ # service. Beginning with that version, all metadata names must adhere to the naming
61
+ # conventions for C# identifiers.
62
+ #
63
+ # See: http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx
64
+ #
65
+ # Any metadata with invalid names which were previously stored, will be returned with the
66
+ # key "x-ms-invalid-name" in the metadata hash. This may contain multiple values and be an
67
+ # Array (vs a String if it only contains a single value).
68
+ #
69
+ # Returns an Azure::Service::EnumerationResults
70
+ def list_containers(options={})
71
+ query = { }
72
+ if options
73
+ query["prefix"] = options[:prefix] if options[:prefix]
74
+ query["marker"] = options[:marker] if options[:marker]
75
+ query["maxresults"] = options[:max_results].to_s if options[:max_results]
76
+ query["include"] = "metadata" if options[:metadata] == true
77
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
78
+ end
79
+
80
+ uri = containers_uri(query)
81
+ response = call(:get, uri)
82
+
83
+ Serialization.container_enumeration_results_from_xml(response.body)
84
+ end
85
+
86
+ # Public: Create a new container
87
+ #
88
+ # ==== Attributes
89
+ #
90
+ # * +name+ - String. The name of the container
91
+ # * +options+ - Hash. Optional parameters.
92
+ #
93
+ # ==== Options
94
+ #
95
+ # Accepted key/value pairs in options parameter are:
96
+ # * +:metadata+ - Hash. User defined metadata for the container (optional)
97
+ # * +:public_access_level+ - String. One of "container" or "blob" (optional)
98
+ # * +:timeout+ - Integer. A timeout in seconds.
99
+ #
100
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
101
+ #
102
+ # Returns a Container
103
+ def create_container(name, options={})
104
+ query = { }
105
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
106
+
107
+ uri = container_uri(name, query)
108
+
109
+ headers = { }
110
+
111
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
112
+
113
+ headers["x-ms-blob-public-access"] = options[:public_access_level].to_s if options[:public_access_level]
114
+
115
+ response = call(:put, uri, nil, headers)
116
+
117
+ container = Serialization.container_from_headers(response.headers)
118
+ container.name = name
119
+ container.metadata = options[:metadata]
120
+ container
121
+ end
122
+
123
+ # Public: Deletes a container
124
+ #
125
+ # ==== Attributes
126
+ #
127
+ # * +name+ - String. The name of the container
128
+ # * +options+ - Hash. Optional parameters.
129
+ #
130
+ # ==== Options
131
+ #
132
+ # Accepted key/value pairs in options parameter are:
133
+ # * +:timeout+ - Integer. A timeout in seconds.
134
+ #
135
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx
136
+ #
137
+ # Returns nil on success
138
+ def delete_container(name, options={})
139
+ query = { }
140
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
141
+
142
+ call(:delete, container_uri(name, query))
143
+ nil
144
+ end
145
+
146
+ # Public: Returns all properties and metadata on the container.
147
+ #
148
+ # ==== Attributes
149
+ #
150
+ # * +name+ - String. The name of the container
151
+ # * +options+ - Hash. Optional parameters.
152
+ #
153
+ # ==== Options
154
+ #
155
+ # Accepted key/value pairs in options parameter are:
156
+ # * +:timeout+ - Integer. A timeout in seconds.
157
+ #
158
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
159
+ #
160
+ # Returns a Container
161
+ def get_container_properties(name, options={})
162
+ query = { }
163
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
164
+
165
+ response = call(:get, container_uri(name, query))
166
+
167
+ container = Serialization.container_from_headers(response.headers)
168
+ container.name = name
169
+ container
170
+ end
171
+
172
+ # Public: Returns only user-defined metadata for the specified container.
173
+ #
174
+ # ==== Attributes
175
+ #
176
+ # * +name+ - String. The name of the container
177
+ # * +options+ - Hash. Optional parameters.
178
+ #
179
+ # ==== Options
180
+ #
181
+ # Accepted key/value pairs in options parameter are:
182
+ # * +:timeout+ - Integer. A timeout in seconds.
183
+ #
184
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx
185
+ #
186
+ # Returns a Container
187
+ def get_container_metadata(name, options={})
188
+ query = { "comp" => "metadata" }
189
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
190
+
191
+ response = call(:get, container_uri(name, query))
192
+
193
+ container = Serialization.container_from_headers(response.headers)
194
+ container.name = name
195
+ container
196
+ end
197
+
198
+ # Public: Gets the access control list (ACL) and any container-level access policies
199
+ # for the container.
200
+ #
201
+ # ==== Attributes
202
+ #
203
+ # * +name+ - String. The name of the container
204
+ # * +options+ - Hash. Optional parameters.
205
+ #
206
+ # ==== Options
207
+ #
208
+ # Accepted key/value pairs in options parameter are:
209
+ # * +:timeout+ - Integer. A timeout in seconds.
210
+ #
211
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
212
+ #
213
+ # Returns a tuple of (container, signed_identifiers)
214
+ # container - A Azure::Entity::Blob::Container instance
215
+ # signed_identifiers - A list of Azure::Entity::SignedIdentifier instances
216
+ #
217
+ def get_container_acl(name, options={})
218
+ query = { "comp" => "acl" }
219
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
220
+ response = call(:get, container_uri(name, query))
221
+
222
+ container = Serialization.container_from_headers(response.headers)
223
+ container.name = name
224
+
225
+ signed_identifiers = nil
226
+ signed_identifiers = Serialization.signed_identifiers_from_xml(response.body) if response.body != nil && response.body.length > 0
227
+
228
+ return container, signed_identifiers
229
+ end
230
+
231
+ # Public: Sets the ACL and any container-level access policies for the container.
232
+ #
233
+ # ==== Attributes
234
+ #
235
+ # * +name+ - String. The name of the container
236
+ # * +public_access_level+ - String. The container public access level
237
+ # * +options+ - Hash. Optional parameters.
238
+ #
239
+ # ==== Options
240
+ #
241
+ # Accepted key/value pairs in options parameter are:
242
+ # * +:signed_identifiers+ - Array. A list of Azure::Entity::SignedIdentifier instances (optional)
243
+ # * +:timeout+ - Integer. A timeout in seconds.
244
+ #
245
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
246
+ #
247
+ # Returns a tuple of (container, signed_identifiers)
248
+ # * +container+ - A Azure::Entity::Blob::Container instance
249
+ # * +signed_identifiers+ - A list of Azure::Entity::SignedIdentifier instances
250
+ #
251
+ def set_container_acl(name, public_access_level, options={})
252
+ query = { "comp" => "acl" }
253
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
254
+ uri =container_uri(name, query)
255
+
256
+ headers = { }
257
+ headers["x-ms-blob-public-access"] = public_access_level if public_access_level && public_access_level.to_s.length > 0
258
+
259
+ signed_identifiers = nil
260
+ signed_identifiers = options[:signed_identifiers] if options[:signed_identifiers]
261
+
262
+ body = nil
263
+ body = Serialization.signed_identifiers_to_xml(signed_identifiers) if signed_identifiers && headers["x-ms-blob-public-access"] == "container"
264
+
265
+ response = call(:put, uri, body, headers)
266
+
267
+ container = Serialization.container_from_headers(response.headers)
268
+ container.name = name
269
+ container.public_access_level = public_access_level
270
+
271
+ return container, signed_identifiers || []
272
+
273
+ end
274
+
275
+ # Public: Sets custom metadata for the container.
276
+ #
277
+ # ==== Attributes
278
+ #
279
+ # * +name+ - String. The name of the container
280
+ # * +metadata+ - Hash. A Hash of the metadata values
281
+ # * +options+ - Hash. Optional parameters.
282
+ #
283
+ # ==== Options
284
+ #
285
+ # Accepted key/value pairs in options parameter are:
286
+ # * +:timeout+ - Integer. A timeout in seconds.
287
+ #
288
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
289
+ #
290
+ # Returns nil on success
291
+ def set_container_metadata(name, metadata, options={})
292
+ query = { "comp" => "metadata" }
293
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
294
+
295
+ headers = { }
296
+ add_metadata_to_headers(metadata, headers) if metadata
297
+
298
+ call(:put, container_uri(name, query), nil, headers)
299
+ nil
300
+ end
301
+
302
+ # Public: Get a list of Blobs from the server
303
+ #
304
+ # ==== Attributes
305
+ #
306
+ # * +name+ - String. The name of the container to list blobs for.
307
+ # * +options+ - Hash. Optional parameters.
308
+ #
309
+ # ==== Options
310
+ #
311
+ # Accepted key/value pairs in options parameter are:
312
+ # * +:prefix+ - String. Filters the results to return only blobs
313
+ # whose name begins with the specified prefix. (optional)
314
+ # * +:delimiter+ - String. When the request includes this parameter, the operation
315
+ # returns a BlobPrefix element in the response body that acts as a
316
+ # placeholder for all blobs whose names begin with the same substring
317
+ # up to the appearance of the delimiter character. The delimiter may
318
+ # be a single character or a string.
319
+ # * +:marker+ - String. An identifier that specifies the portion of the
320
+ # list to be returned. This value comes from the property
321
+ # Azure::Service::EnumerationResults.continuation_token when
322
+ # there are more blobs available than were returned. The
323
+ # marker value may then be used here to request the next set
324
+ # of list items. (optional)
325
+ # * +:max_results+ - Integer. Specifies the maximum number of blobs to return.
326
+ # If max_results is not specified, or is a value greater than
327
+ # 5,000, the server will return up to 5,000 items. If it is set
328
+ # to a value less than or equal to zero, the server will return
329
+ # status code 400 (Bad Request). (optional)
330
+ # * +:metadata+ - Boolean. Specifies whether or not to return the blob metadata.
331
+ # (optional, Default=false)
332
+ # * +:snapshots+ - Boolean. Specifies that snapshots should be included in the
333
+ # enumeration. Snapshots are listed from oldest to newest in the
334
+ # response. (optional, Default=false)
335
+ # * +:uncomittedblobs+ - Boolean. Specifies that blobs for which blocks have been uploaded,
336
+ # but which have not been committed using put_block_list, be included
337
+ # in the response. (optional, Default=false)
338
+ # * +:copy+ - Boolean. Specifies that metadata related to any current or previous
339
+ # copy_blob operation should be included in the response.
340
+ # (optional, Default=false)
341
+ # * +:timeout+ - Integer. A timeout in seconds.
342
+ #
343
+ # NOTE: Metadata requested with the :metadata parameter must have been stored in
344
+ # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob
345
+ # service. Beginning with that version, all metadata names must adhere to the naming
346
+ # conventions for C# identifiers.
347
+ #
348
+ # See: http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
349
+ #
350
+ # Any metadata with invalid names which were previously stored, will be returned with the
351
+ # key "x-ms-invalid-name" in the metadata hash. This may contain multiple values and be an
352
+ # Array (vs a String if it only contains a single value).
353
+ #
354
+ # Returns an Azure::Service::EnumerationResults
355
+ def list_blobs(name, options={})
356
+ query = { "comp" => "list" }
357
+ query["prefix"] = options[:prefix].gsub(/\\/, "/") if options[:prefix]
358
+ query["delimiter"] = options[:delimiter] if options[:delimiter]
359
+ query["marker"] = options[:marker] if options[:marker]
360
+ query["maxresults"] = options[:max_results].to_s if options[:max_results]
361
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
362
+
363
+ included_datasets = []
364
+ included_datasets.push("metadata") if options[:metadata] == true
365
+ included_datasets.push("snapshots") if options[:snapshots] == true
366
+ included_datasets.push("uncommittedblobs") if options[:uncommittedblobs] == true
367
+ included_datasets.push("copy") if options[:copy] == true
368
+
369
+ query["include"] = included_datasets.join ',' if included_datasets.length > 0
370
+
371
+ uri = container_uri(name, query)
372
+ response = call(:get, uri)
373
+
374
+ Serialization.blob_enumeration_results_from_xml(response.body)
375
+ end
376
+
377
+ # Public: Creates a new page blob. Note that calling create_page_blob to create a page
378
+ # blob only initializes the blob. To add content to a page blob, call create_blob_pages method.
379
+ #
380
+ # ==== Attributes
381
+ #
382
+ # * +container+ - String. The container name.
383
+ # * +blob+ - String. The blob name.
384
+ # * +length+ - Integer. Specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary.
385
+ # * +options+ - Hash. Optional parameters.
386
+ #
387
+ # ==== Options
388
+ #
389
+ # Accepted key/value pairs in options parameter are:
390
+ # * +:content_type+ - String. Content type for the request. Will be saved with blob unless alternate value is provided in blob_content_type.
391
+ # * +:content_encoding+ - String. Content encoding for the request. Will be saved with blob unless alternate value is provided in blob_content_encoding.
392
+ # * +:content_language+ - String. Content language for the request. Will be saved with blob unless alternate value is provided in blob_content_language.
393
+ # * +:content_md5+ - String. Content MD5 for the request. Will be saved with blob unless alternate value is provided in blob_content_md5.
394
+ # * +:cache_control+ - String. Cache control for the request. Will be saved with blob unless alternate value is provided in blob_cache_control.
395
+ # * +:blob_content_type+ - String. Content type for the blob. Will be saved with blob.
396
+ # * +:blob_content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
397
+ # * +:blob_content_language+ - String. Content language for the blob. Will be saved with blob.
398
+ # * +:blob_content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
399
+ # * +:blob_cache_control+ - String. Cache control for the blob. Will be saved with blob.
400
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
401
+ # * +:sequence_number+ - Integer. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0.
402
+ # * +:timeout+ - Integer. A timeout in seconds.
403
+ #
404
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
405
+ #
406
+ # Returns a Blob
407
+ def create_page_blob(container, blob, length, options={})
408
+ query = { }
409
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
410
+
411
+ uri = blob_uri(container, blob, query)
412
+
413
+ headers = { }
414
+
415
+ # set x-ms-blob-type to PageBlob
416
+ headers["x-ms-blob-type"] = "PageBlob"
417
+
418
+ # ensure content-length is 0 and x-ms-blob-content-length is the blob length
419
+ headers["Content-Length"] = 0.to_s
420
+ headers["x-ms-blob-content-length"] = length.to_s
421
+
422
+ # set x-ms-sequence-number from options (or default to 0)
423
+ headers["x-ms-sequence-number"] = (options[:sequence_number] || 0).to_s
424
+
425
+ # set the rest of the optional headers
426
+ headers["Content-Type"] = options[:content_type] if options[:content_type]
427
+ headers["Content-Encoding"] = options[:content_encoding] if options[:content_encoding]
428
+ headers["Content-Language"] = options[:content_language] if options[:content_language]
429
+ headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
430
+ headers["Cache-Control"] = options[:cache_control] if options[:cache_control]
431
+
432
+ headers["x-ms-blob-content-type"] = options[:blob_content_type] if options[:blob_content_type]
433
+ headers["x-ms-blob-content-encoding"] = options[:blob_content_encoding] if options[:blob_content_encoding]
434
+ headers["x-ms-blob-content-language"] = options[:blob_content_language] if options[:blob_content_language]
435
+ headers["x-ms-blob-content-md5"] = options[:blob_content_md5] if options[:blob_content_md5]
436
+ headers["x-ms-blob-cache-control"] = options[:blob_cache_control] if options[:blob_cache_control]
437
+
438
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
439
+
440
+ # call PutBlob with empty body
441
+ response = call(:put, uri, nil, headers)
442
+
443
+ result = Serialization.blob_from_headers(response.headers)
444
+ result.name = blob
445
+
446
+ result
447
+ end
448
+
449
+ # Public: Creates a range of pages in a page blob.
450
+ #
451
+ # ==== Attributes
452
+ #
453
+ # * +container+ - String. Name of container
454
+ # * +blob+ - String. Name of blob
455
+ # * +start_range+ - Integer. Position of first byte of first page
456
+ # * +end_range+ - Integer. Position of last byte of of last page
457
+ # * +content+ - IO or String. Content to write. Length in bytes should equal end_range - start_range
458
+ # * +options+ - Hash. A collection of options.
459
+ #
460
+ # ==== Options
461
+ #
462
+ # Accepted key/value pairs in options parameter are:
463
+ # * +:if_sequence_number_le+ - If the blob's sequence number is less than or equal to the specified value, the request proceeds; otherwise it fails with the SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed).
464
+ # * +:if_sequence_number_lt+ - If the blob's sequence number is less than the specified value, the request proceeds; otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed).
465
+ # * +:if_sequence_number_eq+ - If the blob's sequence number is equal to the specified value, the request proceeds; otherwise it fails with SequenceNumberConditionNotMet error (HTTP status code 412 - Precondition Failed).
466
+ # * +:if_modified_since+ - A DateTime value. Specify this conditional header to write the page only if the blob has been modified since the specified date/time. If the blob has not been modified, the Blob service returns status code 412 (Precondition Failed).
467
+ # * +:if_unmodified_since+ - A DateTime value. Specify this conditional header to write the page only if the blob has not been modified since the specified date/time. If the blob has been modified, the Blob service returns status code 412 (Precondition Failed).
468
+ # * +:if_match+ - An ETag value. Specify an ETag value for this conditional header to write the page only if the blob's ETag value matches the value specified. If the values do not match, the Blob service returns status code 412 (Precondition Failed).
469
+ # * +:if_none_match+ - An ETag value. Specify an ETag value for this conditional header to write the page only if the blob's ETag value does not match the value specified. If the values are identical, the Blob service returns status code 412 (Precondition Failed).
470
+ # * +:timeout+ - Integer. A timeout in seconds.
471
+ #
472
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
473
+ #
474
+ # Returns Blob
475
+ def create_blob_pages(container, blob, start_range, end_range, content, options={})
476
+ query = { "comp" => "page" }
477
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
478
+
479
+ uri = blob_uri(container, blob, query)
480
+ headers = { }
481
+ headers["x-ms-range"] = "bytes=#{start_range}-#{end_range}"
482
+ headers["x-ms-page-write"] = "update"
483
+
484
+ # clear default content type
485
+ headers["Content-Type"] = ""
486
+
487
+ # set optional headers
488
+ unless options.empty?
489
+ headers["x-ms-if-sequence-number-le"] = options[:if_sequence_number_le] if options[:if_sequence_number_le]
490
+ headers["x-ms-if-sequence-number-lt"] = options[:if_sequence_number_lt] if options[:if_sequence_number_lt]
491
+ headers["x-ms-if-sequence-number-eq"] = options[:if_sequence_number_eq] if options[:if_sequence_number_eq]
492
+ headers["If-Modified-Since"] = options[:if_modified_since] if options[:if_modified_since]
493
+ headers["If-Unmodified-Since"] = options[:if_unmodified_since] if options[:if_unmodified_since]
494
+ headers["If-Match"] = options[:if_match] if options[:if_match]
495
+ headers["If-None-Match"] = options[:if_none_match] if options[:if_none_match]
496
+ end
497
+
498
+ response = call(:put, uri, content, headers)
499
+
500
+ result = Serialization.blob_from_headers(response.headers)
501
+ result.name = blob
502
+
503
+ result
504
+ end
505
+
506
+ # Public: Clears a range of pages from the blob.
507
+ #
508
+ # ==== Attributes
509
+ #
510
+ # * +container+ - String. Name of container.
511
+ # * +blob+ - String. Name of blob.
512
+ # * +start_range+ - Integer. Position of first byte of first page.
513
+ # * +end_range+ - Integer. Position of last byte of of last page.
514
+ # * +options+ - Hash. Optional parameters.
515
+ #
516
+ # ==== Options
517
+ #
518
+ # Accepted key/value pairs in options parameter are:
519
+ # * +:timeout+ - Integer. A timeout in seconds.
520
+ #
521
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
522
+ #
523
+ # Returns Blob
524
+ def clear_blob_pages(container, blob, start_range, end_range, options={})
525
+ query = { "comp" => "page" }
526
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
527
+
528
+ uri = blob_uri(container, blob, query)
529
+
530
+ headers = { }
531
+ headers["x-ms-range"] = "bytes=#{start_range}-#{end_range}"
532
+ headers["x-ms-page-write"] = "clear"
533
+
534
+ # clear default content type
535
+ headers["Content-Type"] = ""
536
+
537
+ response = call(:put, uri, nil, headers)
538
+
539
+ result = Serialization.blob_from_headers(response.headers)
540
+ result.name = blob
541
+
542
+ result
543
+ end
544
+
545
+ # Public: Creates a new block blob or updates the content of an existing block blob.
546
+ #
547
+ # Updating an existing block blob overwrites any existing metadata on the blob
548
+ # Partial updates are not supported with create_block_blob the content of the
549
+ # existing blob is overwritten with the content of the new blob. To perform a
550
+ # partial update of the content of a block blob, use the create_block_list
551
+ # method.
552
+ #
553
+ # Note that the default content type is application/octet-stream.
554
+ #
555
+ # ==== Attributes
556
+ #
557
+ # * +container+ - String. The container name.
558
+ # * +blob+ - String. The blob name.
559
+ # * +content+ - IO or String. The content of the blob.
560
+ # * +options+ - Hash. Optional parameters.
561
+ #
562
+ # ==== Options
563
+ #
564
+ # Accepted key/value pairs in options parameter are:
565
+ # * +:content_type+ - String. Content type for the request. Will be saved with blob unless alternate value is provided in blob_content_type.
566
+ # * +:content_encoding+ - String. Content encoding for the request. Will be saved with blob unless alternate value is provided in blob_content_encoding.
567
+ # * +:content_language+ - String. Content language for the request. Will be saved with blob unless alternate value is provided in blob_content_language.
568
+ # * +:content_md5+ - String. Content MD5 for the request. Will be saved with blob unless alternate value is provided in blob_content_md5.
569
+ # * +:cache_control+ - String. Cache control for the request. Will be saved with blob unless alternate value is provided in blob_cache_control.
570
+ # * +:blob_content_type+ - String. Content type for the blob. Will be saved with blob.
571
+ # * +:blob_content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
572
+ # * +:blob_content_language+ - String. Content language for the blob. Will be saved with blob.
573
+ # * +:blob_content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
574
+ # * +:blob_cache_control+ - String. Cache control for the blob. Will be saved with blob.
575
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
576
+ # * +:timeout+ - Integer. A timeout in seconds.
577
+ #
578
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
579
+ #
580
+ # Returns a Blob
581
+ def create_block_blob(container, blob, content, options={})
582
+ query = { }
583
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
584
+
585
+ uri = blob_uri(container, blob, query)
586
+
587
+ headers = { }
588
+
589
+ # set x-ms-blob-type to BlockBlob
590
+ headers["x-ms-blob-type"] = "BlockBlob"
591
+
592
+ # set the rest of the optional headers
593
+ headers["Content-Type"] = options[:content_type] || "application/octet-stream"
594
+ headers["Content-Encoding"] = options[:content_encoding] if options[:content_encoding]
595
+ headers["Content-Language"] = options[:content_language] if options[:content_language]
596
+ headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
597
+ headers["Cache-Control"] = options[:cache_control] if options[:cache_control]
598
+ headers["Keep-Alive"] = "timeout=#{options[:timeout]}" if options[:timeout]
599
+
600
+ headers["x-ms-blob-content-type"] = options[:blob_content_type] if options[:blob_content_type]
601
+ headers["x-ms-blob-content-encoding"] = options[:blob_content_encoding] if options[:blob_content_encoding]
602
+ headers["x-ms-blob-content-language"] = options[:blob_content_language] if options[:blob_content_language]
603
+ headers["x-ms-blob-content-md5"] = options[:blob_content_md5] if options[:blob_content_md5]
604
+ headers["x-ms-blob-cache-control"] = options[:blob_cache_control] if options[:blob_cache_control]
605
+
606
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
607
+
608
+ # call PutBlob with empty body
609
+ response = call(:put, uri, content, headers)
610
+
611
+ result = Serialization.blob_from_headers(response.headers)
612
+ result.name = blob
613
+
614
+ result
615
+ end
616
+
617
+ # Public: Creates a new block to be committed as part of a block blob.
618
+ #
619
+ # ==== Attributes
620
+ #
621
+ # * +container+ - String. The container name.
622
+ # * +blob+ - String. The blob name.
623
+ # * +block_id+ - String. The block id. Note: this should be the raw block id, not Base64 encoded.
624
+ # * +content+ - IO or String. The content of the blob.
625
+ # * +options+ - Hash. Optional parameters.
626
+ #
627
+ # ==== Options
628
+ #
629
+ # Accepted key/value pairs in options parameter are:
630
+ # * +:content_md5+ - String. Content MD5 for the request contents.
631
+ # * +:timeout+ - Integer. A timeout in seconds.
632
+ #
633
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
634
+ #
635
+ # Returns the MD5 of the uploaded block (as calculated by the server)
636
+ def create_blob_block(container, blob, block_id, content, options={})
637
+ query = { "comp" => "block" }
638
+ query["blockid"] = Base64.strict_encode64(block_id)
639
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
640
+
641
+ uri = blob_uri(container, blob, query)
642
+
643
+ headers = { }
644
+ headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
645
+
646
+ response = call(:put, uri, content, headers)
647
+
648
+ response.headers["Content-MD5"]
649
+ end
650
+
651
+ # Public: Commits existing blob blocks to a blob.
652
+ #
653
+ # This method writes a blob by specifying the list of block IDs that make up the
654
+ # blob. In order to be written as part of a blob, a block must have been
655
+ # successfully written to the server in a prior create_blob_block method.
656
+ #
657
+ # You can call Put Block List to update a blob by uploading only those blocks
658
+ # that have changed, then committing the new and existing blocks together.
659
+ # You can do this by specifying whether to commit a block from the committed
660
+ # block list or from the uncommitted block list, or to commit the most recently
661
+ # uploaded version of the block, whichever list it may belong to.
662
+ #
663
+ # ==== Attributes
664
+ #
665
+ # * +container+ - String. The container name.
666
+ # * +blob+ - String. The blob name.
667
+ # * +block_list+ - Array. A ordered list of lists in the following format:
668
+ # [ ["block_id1", :committed], ["block_id2", :uncommitted], ["block_id3"], ["block_id4", :committed]... ]
669
+ # The first element of the inner list is the block_id, the second is optional
670
+ # and can be either :committed or :uncommitted to indicate in which group of blocks
671
+ # the id should be looked for. If it is omitted, the latest of either group will be used.
672
+ # * +options+ - Hash. Optional parameters.
673
+ #
674
+ # ==== Options
675
+ #
676
+ # Accepted key/value pairs in options parameter are:
677
+ # * +:content_md5+ - String. Content MD5 for the request contents (not the blob contents!)
678
+ # * +:blob_content_type+ - String. Content type for the blob. Will be saved with blob.
679
+ # * +:blob_content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
680
+ # * +:blob_content_language+ - String. Content language for the blob. Will be saved with blob.
681
+ # * +:blob_content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
682
+ # * +:blob_cache_control+ - String. Cache control for the blob. Will be saved with blob.
683
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob.
684
+ # * +:timeout+ - Integer. A timeout in seconds.
685
+ #
686
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx
687
+ #
688
+ # Returns nil on success
689
+ def commit_blob_blocks(container, blob, block_list, options={})
690
+ query = { "comp" => "blocklist" }
691
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
692
+
693
+ uri = blob_uri(container, blob, query)
694
+
695
+ headers = { }
696
+ unless options.empty?
697
+ headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
698
+ headers["x-ms-blob-content-type"] = options[:blob_content_type] if options[:blob_content_type]
699
+ headers["x-ms-blob-content-encoding"] = options[:blob_content_encoding] if options[:blob_content_encoding]
700
+ headers["x-ms-blob-content-language"] = options[:blob_content_language] if options[:blob_content_language]
701
+ headers["x-ms-blob-content-md5"] = options[:blob_content_md5] if options[:blob_content_md5]
702
+ headers["x-ms-blob-cache-control"] = options[:blob_cache_control] if options[:blob_cache_control]
703
+
704
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
705
+ end
706
+
707
+ body = Serialization.block_list_to_xml(block_list)
708
+ call(:put, uri, body, headers)
709
+ nil
710
+ end
711
+
712
+ # Public: Retrieves the list of blocks that have been uploaded as part of a block blob.
713
+ #
714
+ # There are two block lists maintained for a blob:
715
+ # 1) Committed Block List: The list of blocks that have been successfully
716
+ # committed to a given blob with commitBlobBlocks.
717
+ # 2) Uncommitted Block List: The list of blocks that have been uploaded for a
718
+ # blob using Put Block (REST API), but that have not yet been committed.
719
+ # These blocks are stored in Windows Azure in association with a blob, but do
720
+ # not yet form part of the blob.
721
+ #
722
+ # ==== Attributes
723
+ #
724
+ # * +container+ - String. The container name.
725
+ # * +blob+ - String. The blob name.
726
+ # * +options+ - Hash. Optional parameters.
727
+ #
728
+ # ==== Options
729
+ #
730
+ # Accepted key/value pairs in options parameter are:
731
+ # * +:blocklist_type+ - Symbol. One of :all, :committed, :uncommitted. Defaults to :all (optional)
732
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
733
+ # retrieve information from. (optional)
734
+ # * +:timeout+ - Integer. A timeout in seconds.
735
+ #
736
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx
737
+ #
738
+ # Returns a list of Azure::Entity::Blob::Block instances
739
+ def list_blob_blocks(container, blob, options={})
740
+
741
+ options[:blocklist_type] = options[:blocklist_type] || :all
742
+
743
+ query = { "comp" => "blocklist" }
744
+ query["snapshot"] = options[:snapshot] if options[:snapshot]
745
+ query["blocklisttype"] = options[:blocklist_type].to_s if options[:blocklist_type]
746
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
747
+
748
+ uri = blob_uri(container, blob, query)
749
+
750
+ response = call(:get, uri)
751
+
752
+ Serialization.block_list_from_xml(response.body)
753
+ end
754
+
755
+ # Public: Returns all properties and metadata on the blob.
756
+ #
757
+ # ==== Attributes
758
+ #
759
+ # * +container+ - String. The container name.
760
+ # * +blob+ - String. The blob name.
761
+ # * +options+ - Hash. Optional parameters.
762
+ #
763
+ # ==== Options
764
+ #
765
+ # Accepted key/value pairs in options parameter are:
766
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
767
+ # retrieve information from.
768
+ # * +:timeout+ - Integer. A timeout in seconds.
769
+ #
770
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx
771
+ #
772
+ # Returns a Blob
773
+ def get_blob_properties(container, blob, options={})
774
+ query = { }
775
+ query["snapshot"] = options[:snapshot] if options[:snapshot]
776
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
777
+
778
+ uri = blob_uri(container, blob, query)
779
+
780
+ response = call(:head, uri)
781
+
782
+ result = Serialization.blob_from_headers(response.headers)
783
+
784
+ result.name = blob
785
+ result.snapshot = options[:snapshot]
786
+
787
+ result
788
+ end
789
+
790
+ # Public: Returns metadata on the blob.
791
+ #
792
+ # ==== Attributes
793
+ #
794
+ # * +container+ - String. The container name.
795
+ # * +blob+ - String. The blob name.
796
+ # * +options+ - Hash. Optional parameters.
797
+ #
798
+ # ==== Options
799
+ #
800
+ # Accepted key/value pairs in options parameter are:
801
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
802
+ # retrieve information from.
803
+ # * +:timeout+ - Integer. A timeout in seconds.
804
+ #
805
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx
806
+ #
807
+ # Returns a Blob
808
+ def get_blob_metadata(container, blob, options={})
809
+ query = {"comp"=>"metadata"}
810
+ query["snapshot"] = options[:snapshot] if options[:snapshot]
811
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
812
+
813
+ uri = blob_uri(container, blob, query)
814
+
815
+ response = call(:get, uri)
816
+
817
+ result = Serialization.blob_from_headers(response.headers)
818
+
819
+ result.name = blob
820
+ result.snapshot = options[:snapshot]
821
+
822
+ result
823
+ end
824
+
825
+ # Public: Returns a list of active page ranges for a page blob. Active page ranges are
826
+ # those that have been populated with data.
827
+ #
828
+ # ==== Attributes
829
+ #
830
+ # * +container+ - String. The container name.
831
+ # * +blob+ - String. The blob name.
832
+ # * +options+ - Hash. Optional parameters.
833
+ #
834
+ # ==== Options
835
+ #
836
+ # Accepted key/value pairs in options parameter are:
837
+ # * +:start_range+ - Integer. Position of first byte of first page. (optional)
838
+ # * +:end_range+ - Integer. Position of last byte of of last page. (optional)
839
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
840
+ # retrieve information from. (optional)
841
+ # * +:timeout+ - Integer. A timeout in seconds.
842
+ #
843
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx
844
+ #
845
+ # Returns a list of page ranges in the format [ [start, end], [start, end], ... ]
846
+ #
847
+ # eg. [ [0, 511], [512, 1024], ... ]
848
+ #
849
+ def list_page_blob_ranges(container, blob, options={})
850
+ query = {"comp"=>"pagelist"}
851
+ query.update({"snapshot" => options[:snapshot]}) if options[:snapshot]
852
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
853
+
854
+ uri = blob_uri(container, blob, query)
855
+
856
+ options[:start_range] = 0 if options[:end_range] and not options[:start_range]
857
+
858
+ headers = { }
859
+ headers = { "x-ms-range" => "bytes=#{options[:start_range]}-#{options[:end_range]}" } if options[:start_range]
860
+
861
+ response = call(:get, uri, nil, headers)
862
+
863
+ pagelist = Serialization.page_list_from_xml(response.body)
864
+ pagelist
865
+ end
866
+
867
+ # Public: Sets system properties defined for a blob.
868
+ #
869
+ # ==== Attributes
870
+ #
871
+ # * +container+ - String. The container name.
872
+ # * +blob+ - String. The blob name.
873
+ # * +options+ - Hash. Optional parameters.
874
+ #
875
+ # ==== Options
876
+ #
877
+ # Accepted key/value pairs in options parameter are:
878
+ # * +:content_type+ - String. Content type for the blob. Will be saved with blob.
879
+ # * +:content_encoding+ - String. Content encoding for the blob. Will be saved with blob.
880
+ # * +:content_language+ - String. Content language for the blob. Will be saved with blob.
881
+ # * +:content_md5+ - String. Content MD5 for the blob. Will be saved with blob.
882
+ # * +:cache_control+ - String. Cache control for the blob. Will be saved with blob.
883
+ # * +:content_length+ - Integer. Resizes a page blob to the specified size. If the specified
884
+ # value is less than the current size of the blob, then all pages above
885
+ # the specified value are cleared. This property cannot be used to change
886
+ # the size of a block blob. Setting this property for a block blob returns
887
+ # status code 400 (Bad Request).
888
+ # * +:sequence_number_action+ - Symbol. This property indicates how the service should modify the sequence
889
+ # number for the blob. Required if :sequence_number is used. This property
890
+ # applies to page blobs only.
891
+ #
892
+ # Specify one of the following options for this property:
893
+ #
894
+ # * +:max+ - Sets the sequence number to be the higher of the value included with
895
+ # the request and the value currently stored for the blob.
896
+ # * +:update+ - Sets the sequence number to the value included with the request.
897
+ # * +:increment+ - Increments the value of the sequence number by 1. If specifying this
898
+ # option, do not include the sequence_number option; doing so will return
899
+ # status code 400 (Bad Request).
900
+ # * +:sequence_number+ - Integer. This property sets the blob's sequence number. The sequence number is a
901
+ # user-controlled property that you can use to track requests and manage concurrency
902
+ # issues. Required if the :sequence_number_action option is set to :max or :update.
903
+ # This property applies to page blobs only.
904
+ #
905
+ # Use this together with the :sequence_number_action to update the blob's sequence
906
+ # number, either to the specified value or to the higher of the values specified with
907
+ # the request or currently stored with the blob.
908
+ #
909
+ # This header should not be specified if :sequence_number_action is set to :increment;
910
+ # in this case the service automatically increments the sequence number by one.
911
+ #
912
+ # To set the sequence number to a value of your choosing, this property must be specified
913
+ # together with :sequence_number_action
914
+ # * +:timeout+ - Integer. A timeout in seconds.
915
+ #
916
+ # Remarks:
917
+ #
918
+ # The semantics for updating a blob's properties are as follows:
919
+ #
920
+ # * A page blob's sequence number is updated only if the request meets either of the following conditions:
921
+ #
922
+ # * The :sequence_number_action property is set to :max or :update, and a value for :sequence_number is also set.
923
+ # * The :sequence_number_action property is set to :increment, indicating that the service should increment
924
+ # the sequence number by one.
925
+ #
926
+ # * The size of the page blob is modified only if a value for :content_length is specified.
927
+ #
928
+ # * If :sequence_number and/or :content_length are the only properties specified, then the other properties of the blob
929
+ # will NOT be modified.
930
+ #
931
+ # * If any one or more of the following properties are set, then all of these properties are set together. If a value is
932
+ # not provided for a given property when at least one of the properties listed below is set, then that property will be
933
+ # cleared for the blob.
934
+ #
935
+ # * :cache_control
936
+ # * :content_type
937
+ # * :content_md5
938
+ # * :content_encoding
939
+ # * :content_language
940
+ #
941
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx
942
+ #
943
+ # Returns nil on success.
944
+ def set_blob_properties(container, blob, options={})
945
+ query = { "comp" => "properties" }
946
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
947
+ uri = blob_uri(container, blob, query)
948
+
949
+ headers = { }
950
+
951
+ unless options.empty?
952
+ headers["x-ms-blob-content-type"] = options[:blob_content_type] if options[:blob_content_type]
953
+ headers["x-ms-blob-content-encoding"] = options[:blob_content_encoding] if options[:blob_content_encoding]
954
+ headers["x-ms-blob-content-language"] = options[:blob_content_language] if options[:blob_content_language]
955
+ headers["x-ms-blob-content-md5"] = options[:blob_content_md5] if options[:blob_content_md5]
956
+ headers["x-ms-blob-cache-control"] = options[:blob_cache_control] if options[:blob_cache_control]
957
+ headers["x-ms-blob-content-length"] = options[:blob_content_length].to_s if options[:blob_content_length]
958
+ headers["x-ms-blob-sequence-number-action"] = options[:sequence_number_action].to_s if options[:sequence_number_action]
959
+ headers["x-ms-blob-sequence-number"] = options[:sequence_number].to_s if options[:sequence_number]
960
+ end
961
+
962
+ call(:put, uri, nil, headers)
963
+ nil
964
+ end
965
+
966
+ # Public: Sets metadata headers on the blob.
967
+ #
968
+ # ==== Attributes
969
+ #
970
+ # * +container+ - String. The container name.
971
+ # * +blob+ - String. The blob name.
972
+ # * +metadata+ - Hash. The custom metadata.
973
+ # * +options+ - Hash. Optional parameters.
974
+ #
975
+ # ==== Options
976
+ #
977
+ # Accepted key/value pairs in options parameter are:
978
+ # * +:timeout+ - Integer. A timeout in seconds.
979
+ #
980
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx
981
+ #
982
+ # Returns nil on success.
983
+ def set_blob_metadata(container, blob, metadata, options={})
984
+ query = { "comp" => "metadata" }
985
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
986
+ uri = blob_uri(container, blob, query)
987
+
988
+ headers = { }
989
+
990
+ add_metadata_to_headers(metadata, headers) if metadata
991
+
992
+ call(:put, uri, nil, headers)
993
+ nil
994
+ end
995
+
996
+ # Public: Reads or downloads a blob from the system, including its metadata and properties.
997
+ #
998
+ # ==== Attributes
999
+ #
1000
+ # * +container+ - String. The container name.
1001
+ # * +blob+ - String. The blob name.
1002
+ # * +options+ - Hash. Optional parameters.
1003
+ #
1004
+ # ==== Options
1005
+ #
1006
+ # Accepted key/value pairs in options parameter are:
1007
+ # * +:start_range+ - Integer. Position of first byte of first page. (optional)
1008
+ # * +:end_range+ - Integer. Position of last byte of of last page. (optional)
1009
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
1010
+ # retrieve information from. (optional)
1011
+ # * +:get_content_md5+ - Boolean. Return the MD5 hash for the range. This option only valid if
1012
+ # start_range and end_range are specified. (optional)
1013
+ # * +:timeout+ - Integer. A timeout in seconds.
1014
+ #
1015
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
1016
+ #
1017
+ # Returns a blob and the blob body
1018
+ def get_blob(container, blob, options={})
1019
+ query = { }
1020
+ query["snapshot"] = options[:snapshot] if options[:snapshot]
1021
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1022
+ uri = blob_uri(container, blob, query)
1023
+
1024
+ headers = { }
1025
+ options[:start_range] = 0 if options[:end_range] and not options[:start_range]
1026
+ if options[:start_range]
1027
+ headers["x-ms-range"] = "bytes=#{options[:start_range]}-#{options[:end_range]}"
1028
+ headers["x-ms-range-get-content-md5"] = true if options[:get_content_md5]
1029
+ end
1030
+
1031
+ response = call(:get, uri, nil, headers)
1032
+ result = Serialization.blob_from_headers(response.headers)
1033
+ result.name = blob if not result.name
1034
+ return result, response.body
1035
+ end
1036
+
1037
+ # Public: Deletes a blob or blob snapshot.
1038
+ #
1039
+ # ==== Attributes
1040
+ #
1041
+ # * +container+ - String. The container name.
1042
+ # * +blob+ - String. The blob name.
1043
+ # * +options+ - Hash. Optional parameters.
1044
+ #
1045
+ # ==== Options
1046
+ #
1047
+ # Accepted key/value pairs in options parameter are:
1048
+ # * +:snapshot+ - String. An opaque DateTime value that specifies the blob snapshot to
1049
+ # retrieve information from. (optional)
1050
+ # * +:delete_snapshots+ - Symbol. Used to specify the scope of the delete operation for snapshots.
1051
+ # This parameter is ignored if a blob does not have snapshots, or if a
1052
+ # snapshot is specified in the snapshot parameter. (optional)
1053
+ #
1054
+ # Possible values include:
1055
+ # * +:only+ - Deletes only the snapshots for the blob, but leaves the blob
1056
+ # * +:include+ - Deletes the blob and all of the snapshots for the blob
1057
+ # * +:timeout+ - Integer. A timeout in seconds.
1058
+ #
1059
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
1060
+ #
1061
+ # Returns nil on success
1062
+ def delete_blob(container, blob, options={})
1063
+ query = { }
1064
+ query["snapshot"] = options[:snapshot] if options[:snapshot]
1065
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1066
+
1067
+ uri = blob_uri(container, blob, query)
1068
+
1069
+ options[:delete_snapshots] = :include if !options[:delete_snapshots]
1070
+
1071
+ headers = { }
1072
+ headers["x-ms-delete-snapshots"] = options[:delete_snapshots].to_s if options[:delete_snapshots] && options[:snapshot] == nil
1073
+
1074
+ call(:delete, uri, nil, headers)
1075
+ nil
1076
+ end
1077
+
1078
+ # Public: Creates a snapshot of a blob.
1079
+ #
1080
+ # ==== Attributes
1081
+ #
1082
+ # * +container+ - String. The container name.
1083
+ # * +blob+ - String. The blob name.
1084
+ # * +options+ - Hash. Optional parameters.
1085
+ #
1086
+ # ==== Options
1087
+ #
1088
+ # Accepted key/value pairs in options parameter are:
1089
+ # * +:metadata+ - Hash. Custom metadata values to store with the blob snapshot.
1090
+ # * +:if_modified_since+ - A DateTime value. Specify this option to write the page only if the blob has been
1091
+ # modified since the specified date/time. If the blob has not been modified, the
1092
+ # Blob service returns status code 412 (Precondition Failed).
1093
+ # * +:if_unmodified_since+ - A DateTime value. Specify this option to write the page only if the blob has not
1094
+ # been modified since the specified date/time. If the blob has been modified, the
1095
+ # Blob service returns status code 412 (Precondition Failed).
1096
+ # * +:if_match+ - An ETag value. Specify an ETag value to write the page only if the blob's ETag
1097
+ # value matches the value specified. If the values do not match, the Blob service
1098
+ # returns status code 412 (Precondition Failed).
1099
+ # * +:if_none_match+ - An ETag value. Specify an ETag value to write the page only if the blob's ETag
1100
+ # value does not match the value specified. If the values are identical, the Blob
1101
+ # service returns status code 412 (Precondition Failed).
1102
+ # * +:timeout+ - Integer. A timeout in seconds.
1103
+ #
1104
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx
1105
+ #
1106
+ # Returns the snapshot DateTime value
1107
+ def create_blob_snapshot(container, blob, options={})
1108
+ query = { "comp" => "snapshot" }
1109
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1110
+
1111
+ uri = blob_uri(container, blob, query)
1112
+
1113
+ headers = { }
1114
+ unless options.empty?
1115
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
1116
+
1117
+ headers["If-Modified-Since"] = options[:if_modified_since] if options[:if_modified_since]
1118
+ headers["If-Unmodified-Since"] = options[:if_unmodified_since] if options[:if_unmodified_since]
1119
+ headers["If-Match"] = options[:if_match] if options[:if_match]
1120
+ headers["If-None-Match"] = options[:if_none_match] if options[:if_none_match]
1121
+ end
1122
+
1123
+ response = call(:put, uri, nil, headers)
1124
+
1125
+ response.headers["x-ms-snapshot"]
1126
+ end
1127
+
1128
+ # Public: Copies a source blob to a destination blob within the same storage account.
1129
+ #
1130
+ # ==== Attributes
1131
+ #
1132
+ # * +source_container+ - String. The destination container name to copy to.
1133
+ # * +source_blob+ - String. The destination blob name to copy to.
1134
+ # * +destination_container+ - String. The source container name to copy from.
1135
+ # * +destination_blob+ - String. The source blob name to copy from.
1136
+ # * +options+ - Hash. Optional parameters.
1137
+ #
1138
+ # ==== Options
1139
+ #
1140
+ # Accepted key/value pairs in options parameter are:
1141
+ # * +:source_snapshot+ - String. A snapshot id for the source blob
1142
+ # * +:metadata+ - Hash. Custom metadata values to store with the copy. If this parameter is not
1143
+ # specified, the operation will copy the source blob metadata to the destination
1144
+ # blob. If this parameter is specified, the destination blob is created with the
1145
+ # specified metadata, and metadata is not copied from the source blob.
1146
+ # * +:source_if_modified_since+ - A DateTime value. Specify this option to write the page only if the source blob
1147
+ # has been modified since the specified date/time. If the blob has not been
1148
+ # modified, the Blob service returns status code 412 (Precondition Failed).
1149
+ # * +:source_if_unmodified_since+ - A DateTime value. Specify this option to write the page only if the source blob
1150
+ # has not been modified since the specified date/time. If the blob has been
1151
+ # modified, the Blob service returns status code 412 (Precondition Failed).
1152
+ # * +:source_if_match+ - An ETag value. Specify an ETag value to write the page only if the source blob's
1153
+ # ETag value matches the value specified. If the values do not match, the Blob
1154
+ # service returns status code 412 (Precondition Failed).
1155
+ # * +:source_if_none_match+ - An ETag value. Specify an ETag value to write the page only if the source blob's
1156
+ # ETag value does not match the value specified. If the values are identical, the
1157
+ # Blob service returns status code 412 (Precondition Failed).
1158
+ # * +:dest_if_modified_since+ - A DateTime value. Specify this option to write the page only if the destination
1159
+ # blob has been modified since the specified date/time. If the blob has not been
1160
+ # modified, the Blob service returns status code 412 (Precondition Failed).
1161
+ # * +:dest_if_unmodified_since+ - A DateTime value. Specify this option to write the page only if the destination
1162
+ # blob has not been modified since the specified date/time. If the blob has been
1163
+ # modified, the Blob service returns status code 412 (Precondition Failed).
1164
+ # * +:dest_if_match+ - An ETag value. Specify an ETag value to write the page only if the destination
1165
+ # blob's ETag value matches the value specified. If the values do not match, the
1166
+ # Blob service returns status code 412 (Precondition Failed).
1167
+ # * +:dest_if_none_match+ - An ETag value. Specify an ETag value to write the page only if the destination
1168
+ # blob's ETag value does not match the value specified. If the values are
1169
+ # identical, the Blob service returns status code 412 (Precondition Failed).
1170
+ # * +:timeout+ - Integer. A timeout in seconds.
1171
+ #
1172
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
1173
+ #
1174
+ # Returns a tuple of (copy_id, copy_status).
1175
+ #
1176
+ # * +copy_id+ - String identifier for this copy operation. Use with get_blob or get_blob_properties to check
1177
+ # the status of this copy operation, or pass to abort_copy_blob to abort a pending copy.
1178
+ # * +copy_status+ - String. The state of the copy operation, with these values:
1179
+ # "success" - The copy completed successfully.
1180
+ # "pending" - The copy is in progress.
1181
+ #
1182
+ def copy_blob(destination_container, destination_blob, source_container, source_blob, options={})
1183
+ query = { }
1184
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1185
+
1186
+ uri = blob_uri(destination_container, destination_blob, query)
1187
+ headers = { }
1188
+ headers["x-ms-copy-source"] = blob_uri(source_container, source_blob, options[:source_snapshot] ? { "snapshot" => options[:source_snapshot] } : {}).to_s
1189
+
1190
+ unless options.empty?
1191
+ headers["If-Modified-Since"] = options[:dest_if_modified_since] if options[:dest_if_modified_since]
1192
+ headers["If-Unmodified-Since"] = options[:dest_if_unmodified_since] if options[:dest_if_unmodified_since]
1193
+ headers["If-Match"] = options[:dest_if_match] if options[:dest_if_match]
1194
+ headers["If-None-Match"] = options[:dest_if_none_match] if options[:dest_if_none_match]
1195
+ headers["x-ms-source-if-modified-since"] = options[:source_if_modified_since] if options[:source_if_modified_since]
1196
+ headers["x-ms-source-if-unmodified-since"] = options[:source_if_unmodified_since] if options[:source_if_unmodified_since]
1197
+ headers["x-ms-source-if-match"] = options[:source_if_match] if options[:source_if_match]
1198
+ headers["x-ms-source-if-none-match"] = options[:source_if_none_match] if options[:source_if_none_match]
1199
+
1200
+ add_metadata_to_headers(options[:metadata], headers) if options[:metadata]
1201
+ end
1202
+
1203
+ response = call(:put, uri, nil, headers)
1204
+ return response.headers["x-ms-copy-id"], response.headers["x-ms-copy-status"]
1205
+ end
1206
+
1207
+ # Public: Establishes an exclusive one-minute write lock on a blob. To write to a locked
1208
+ # blob, a client must provide a lease ID.
1209
+ #
1210
+ # ==== Attributes
1211
+ #
1212
+ # * +container+ - String. The container name.
1213
+ # * +blob+ - String. The blob name.
1214
+ # * +options+ - Hash. Optional parameters.
1215
+ #
1216
+ # ==== Options
1217
+ #
1218
+ # Accepted key/value pairs in options parameter are:
1219
+ # * +:duration+ - Integer. Default -1. Specifies the duration of the lease, in seconds, or negative one (-1)
1220
+ # for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. (optional)
1221
+ # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request)
1222
+ # if the proposed lease ID is not in the correct format. (optional)
1223
+ # * +:timeout+ - Integer. A timeout in seconds.
1224
+ #
1225
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
1226
+ #
1227
+ # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request
1228
+ # to write to the blob, or to renew, change, or release the lease. A successful renew operation also returns the lease id
1229
+ # for the active lease.
1230
+ #
1231
+ def acquire_lease(container, blob, options={})
1232
+ query = { "comp" => "lease" }
1233
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1234
+
1235
+ uri = blob_uri(container, blob, query)
1236
+
1237
+ duration = -1
1238
+ duration = options[:duration] if options[:duration]
1239
+
1240
+ headers = { }
1241
+ headers["x-ms-lease-action"] = "acquire"
1242
+ headers["x-ms-lease-duration"] = duration.to_s if duration
1243
+ headers["x-ms-proposed-lease-id"] = options[:proposed_lease_id] if options[:proposed_lease_id]
1244
+
1245
+ response = call(:put, uri, nil, headers)
1246
+ response.headers["x-ms-lease-id"]
1247
+ end
1248
+
1249
+ # Public: Renews the lease. The lease can be renewed if the lease ID specified on the request matches that
1250
+ # associated with the blob. Note that the lease may be renewed even if it has expired as long as the blob
1251
+ # has not been modified or leased again since the expiration of that lease. When you renew a lease, the
1252
+ # lease duration clock resets.
1253
+ #
1254
+ # ==== Attributes
1255
+ #
1256
+ # * +container+ - String. The container name.
1257
+ # * +blob+ - String. The blob name.
1258
+ # * +lease+ - String. The lease id
1259
+ # * +options+ - Hash. Optional parameters.
1260
+ #
1261
+ # ==== Options
1262
+ #
1263
+ # Accepted key/value pairs in options parameter are:
1264
+ # * +:timeout+ - Integer. A timeout in seconds.
1265
+ #
1266
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
1267
+ #
1268
+ # Returns the renewed lease id
1269
+ def renew_lease(container, blob, lease, options={})
1270
+ query = { "comp" => "lease" }
1271
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1272
+
1273
+ uri = blob_uri(container, blob, query)
1274
+
1275
+ headers = { }
1276
+ headers["x-ms-lease-action"] = "renew"
1277
+ headers["x-ms-lease-id"] = lease
1278
+
1279
+ response = call(:put, uri, nil, headers)
1280
+ response.headers["x-ms-lease-id"]
1281
+ end
1282
+
1283
+ # Public: Releases the lease. The lease may be released if the lease ID specified on the request matches that
1284
+ # associated with the blob. Releasing the lease allows another client to immediately acquire the lease for
1285
+ # the blob as soon as the release is complete.
1286
+ #
1287
+ # ==== Attributes
1288
+ #
1289
+ # * +container+ - String. The container name.
1290
+ # * +blob+ - String. The blob name.
1291
+ # * +lease+ - String. The lease id.
1292
+ # * +options+ - Hash. Optional parameters.
1293
+ #
1294
+ # ==== Options
1295
+ #
1296
+ # Accepted key/value pairs in options parameter are:
1297
+ # * +:timeout+ - Integer. A timeout in seconds.
1298
+ #
1299
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
1300
+ #
1301
+ # Returns nil on success
1302
+ def release_lease(container, blob, lease, options={})
1303
+ query = { "comp" => "lease" }
1304
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1305
+
1306
+ uri = blob_uri(container, blob, query)
1307
+
1308
+ headers = { }
1309
+ headers["x-ms-lease-action"] = "release"
1310
+ headers["x-ms-lease-id"] = lease
1311
+
1312
+ call(:put, uri, nil, headers)
1313
+ nil
1314
+ end
1315
+
1316
+ # Public: Breaks the lease, if the blob has an active lease. Once a lease is broken, it cannot be renewed. Any
1317
+ # authorized request can break the lease; the request is not required to specify a matching lease ID. When a
1318
+ # lease is broken, the lease break period is allowed to elapse, during which time no lease operation except
1319
+ # break and release can be performed on the blob. When a lease is successfully broken, the response indicates
1320
+ # the interval in seconds until a new lease can be acquired.
1321
+ #
1322
+ # A lease that has been broken can also be released, in which case another client may immediately acquire the
1323
+ # lease on the blob.
1324
+ #
1325
+ # ==== Attributes
1326
+ #
1327
+ # * +container+ - String. The container name.
1328
+ # * +blob+ - String. The blob name.
1329
+ # * +options+ - Hash. Optional parameters.
1330
+ #
1331
+ # ==== Options
1332
+ #
1333
+ # Accepted key/value pairs in options parameter are:
1334
+ # * +:break_period+ - Integer. The proposed duration of seconds that the lease should continue before it is
1335
+ # broken, between 0 and 60 seconds. This break period is only used if it is shorter than
1336
+ # the time remaining on the lease. If longer, the time remaining on the lease is used. A
1337
+ # new lease will not be available before the break period has expired, but the lease may
1338
+ # be held for longer than the break period.
1339
+ #
1340
+ # If this option is not used, a fixed-duration lease breaks after the remaining lease
1341
+ # period elapses, and an infinite lease breaks immediately.
1342
+ # * +:timeout+ - Integer. A timeout in seconds.
1343
+ #
1344
+ # See http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
1345
+ #
1346
+ # Returns an Integer of the remaining lease time. This value is the approximate time remaining in the lease
1347
+ # period, in seconds. This header is returned only for a successful request to break the lease. If the break
1348
+ # is immediate, 0 is returned.
1349
+ def break_lease(container, blob, options={})
1350
+ query = { "comp" => "lease" }
1351
+ query["timeout"] = options[:timeout].to_s if options[:timeout]
1352
+
1353
+ uri = blob_uri(container, blob, query)
1354
+
1355
+ headers = { }
1356
+ headers["x-ms-lease-action"] = "break"
1357
+ headers["x-ms-lease-break-period"] = options[:break_period].to_s if options[:break_period]
1358
+
1359
+ response = call(:put, uri, nil, headers)
1360
+ response.headers["x-ms-lease-time"].to_i
1361
+ end
1362
+
1363
+ # Protected: Generate the URI for the collection of containers.
1364
+ #
1365
+ # ==== Attributes
1366
+ #
1367
+ # * +query+ - A Hash of key => value query parameters.
1368
+ # * +host+ - The host of the API.
1369
+ #
1370
+ # Returns a URI.
1371
+ protected
1372
+ def containers_uri(query={})
1373
+ query = { "comp" => "list" }.merge(query)
1374
+ generate_uri("/", query)
1375
+ end
1376
+
1377
+ # Protected: Generate the URI for a specific container.
1378
+ #
1379
+ # ==== Attributes
1380
+ #
1381
+ # * +name+ - The container name. If this is a URI, we just return this.
1382
+ # * +query+ - A Hash of key => value query parameters.
1383
+ # * +host+ - The host of the API.
1384
+ #
1385
+ # Returns a URI.
1386
+ protected
1387
+ def container_uri(name, query={})
1388
+ return name if name.kind_of? ::URI
1389
+ query = { "restype" => "container" }.merge(query)
1390
+ generate_uri(name, query)
1391
+ end
1392
+
1393
+ # Protected: Generate the URI for a specific Blob.
1394
+ #
1395
+ # ==== Attributes
1396
+ #
1397
+ # * +container_name+ - String representing the name of the container.
1398
+ # * +blob_name+ - String representing the name of the blob.
1399
+ # * +query+ - A Hash of key => value query parameters.
1400
+ # * +host+ - The host of the API.
1401
+ #
1402
+ # Returns a URI.
1403
+ protected
1404
+ def blob_uri(container_name, blob_name, query={})
1405
+ if container_name.nil? || container_name.empty?
1406
+ path = blob_name
1407
+ else
1408
+ path = File.join(container_name, blob_name)
1409
+ end
1410
+
1411
+ path = CGI.escape(path.encode('UTF-8'))
1412
+
1413
+ # Unencode the forward slashes to match what the server expects.
1414
+ path = path.gsub(/%2F/, '/')
1415
+ # Unencode the backward slashes to match what the server expects.
1416
+ path = path.gsub(/%5C/, '/')
1417
+ # Re-encode the spaces (encoded as space) to the % encoding.
1418
+ path = path.gsub(/\+/, '%20')
1419
+
1420
+ generate_uri(path, query)
1421
+ end
1422
+ end
1423
+ end
1424
+ end