juliusl-azure-sdk-for-ruby 0.7.0

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