azure 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +36 -0
  3. data/README.md +3 -0
  4. data/Rakefile +81 -0
  5. data/azure.gemspec +20 -9
  6. data/lib/azure.rb +4 -0
  7. data/lib/azure/atom.rb +170 -0
  8. data/lib/azure/auth.rb +29 -0
  9. data/lib/azure/blobs.rb +620 -0
  10. data/lib/azure/blobs/blob.rb +360 -0
  11. data/lib/azure/blobs/container.rb +209 -0
  12. data/lib/azure/blobs/service.rb +396 -0
  13. data/lib/azure/blobs/shared_access_signature.rb +84 -0
  14. data/lib/azure/blobs/uri.rb +60 -0
  15. data/lib/azure/configuration.rb +121 -0
  16. data/lib/azure/core/auth/shared_key.rb +95 -0
  17. data/lib/azure/core/auth/shared_key_lite.rb +34 -0
  18. data/lib/azure/core/collection.rb +118 -0
  19. data/lib/azure/core/service.rb +43 -0
  20. data/lib/azure/core/signer.rb +32 -0
  21. data/lib/azure/core/utils/interval.rb +97 -0
  22. data/lib/azure/core/utils/queryable.rb +74 -0
  23. data/lib/azure/core/utils/storage_service_properties.rb +83 -0
  24. data/lib/azure/core/utils/string.rb +59 -0
  25. data/lib/azure/error.rb +72 -0
  26. data/lib/azure/queues.rb +272 -0
  27. data/lib/azure/queues/message.rb +174 -0
  28. data/lib/azure/queues/queue.rb +187 -0
  29. data/lib/azure/queues/service.rb +263 -0
  30. data/lib/azure/queues/service_properties.rb +152 -0
  31. data/lib/azure/queues/uri.rb +78 -0
  32. data/lib/azure/request.rb +102 -0
  33. data/lib/azure/response.rb +93 -0
  34. data/lib/azure/service_bus.rb +4 -0
  35. data/lib/azure/service_bus/auth/authorizer.rb +22 -0
  36. data/lib/azure/service_bus/auth/uri.rb +52 -0
  37. data/lib/azure/service_bus/auth/wrap.rb +37 -0
  38. data/lib/azure/service_bus/auth/wrap_service.rb +76 -0
  39. data/lib/azure/service_bus/auth/wrap_token.rb +45 -0
  40. data/lib/azure/service_bus/auth/wrap_token_manager.rb +46 -0
  41. data/lib/azure/service_bus/brokered_message.rb +139 -0
  42. data/lib/azure/service_bus/brokered_message_serializer.rb +113 -0
  43. data/lib/azure/service_bus/queues.rb +194 -0
  44. data/lib/azure/service_bus/queues/queue.rb +100 -0
  45. data/lib/azure/service_bus/queues/queue_serializer.rb +51 -0
  46. data/lib/azure/service_bus/queues/service.rb +154 -0
  47. data/lib/azure/service_bus/queues/uri.rb +80 -0
  48. data/lib/azure/service_bus/rules.rb +110 -0
  49. data/lib/azure/service_bus/rules/rule.rb +97 -0
  50. data/lib/azure/service_bus/rules/service.rb +122 -0
  51. data/lib/azure/service_bus/rules/uri.rb +39 -0
  52. data/lib/azure/service_bus/service_bus_service.rb +22 -0
  53. data/lib/azure/service_bus/subscriptions.rb +170 -0
  54. data/lib/azure/service_bus/subscriptions/service.rb +133 -0
  55. data/lib/azure/service_bus/subscriptions/subscription.rb +164 -0
  56. data/lib/azure/service_bus/subscriptions/subscription_serializer.rb +74 -0
  57. data/lib/azure/service_bus/subscriptions/uri.rb +71 -0
  58. data/lib/azure/service_bus/topics.rb +120 -0
  59. data/lib/azure/service_bus/topics/service.rb +98 -0
  60. data/lib/azure/service_bus/topics/topic.rb +122 -0
  61. data/lib/azure/service_bus/topics/topic_serializer.rb +44 -0
  62. data/lib/azure/service_bus/topics/uri.rb +58 -0
  63. data/lib/azure/service_runtime/client/goal_state_pipe_monitor.rb +21 -0
  64. data/lib/azure/service_runtime/client/goal_state_protocol.rb +18 -0
  65. data/lib/azure/service_runtime/client/runtime_client.rb +135 -0
  66. data/lib/azure/service_runtime/deployment.rb +24 -0
  67. data/lib/azure/service_runtime/local_resource.rb +15 -0
  68. data/lib/azure/service_runtime/role.rb +17 -0
  69. data/lib/azure/service_runtime/role_environment.rb +206 -0
  70. data/lib/azure/service_runtime/role_environment_change.rb +32 -0
  71. data/lib/azure/service_runtime/role_instance.rb +35 -0
  72. data/lib/azure/service_runtime/role_instance_endpoint.rb +14 -0
  73. data/lib/azure/tables.rb +215 -0
  74. data/lib/azure/tables/auth/shared_key.rb +71 -0
  75. data/lib/azure/tables/auth/shared_key_lite.rb +30 -0
  76. data/lib/azure/tables/entities_collection.rb +66 -0
  77. data/lib/azure/tables/entity.rb +127 -0
  78. data/lib/azure/tables/service.rb +211 -0
  79. data/lib/azure/tables/table.rb +129 -0
  80. data/lib/azure/tables/tables_collection.rb +62 -0
  81. data/lib/azure/tables/types.rb +65 -0
  82. data/lib/azure/tables/uri.rb +62 -0
  83. data/test/fixtures/32px-fulls-black.jpg +0 -0
  84. data/test/fixtures/all_containers.xml +20 -0
  85. data/test/fixtures/all_tables.xml +22 -0
  86. data/test/fixtures/create_table_response_entry.xml +15 -0
  87. data/test/fixtures/error.xml +5 -0
  88. data/test/fixtures/insert_entity_response_entry.xml +25 -0
  89. data/test/fixtures/messages.xml +12 -0
  90. data/test/fixtures/query_entities_empty_response.xml +7 -0
  91. data/test/fixtures/query_entities_response.xml +45 -0
  92. data/test/fixtures/queue_service_properties.xml +22 -0
  93. data/test/fixtures/queue_service_properties_original.xml +19 -0
  94. data/test/fixtures/queues.xml +16 -0
  95. data/test/fixtures/sb_default_create_queue_response.xml +23 -0
  96. data/test/fixtures/sb_default_create_topic_response.xml +18 -0
  97. data/test/fixtures/sb_get_access_token_response.txt +1 -0
  98. data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
  99. data/test/integration/blobs/auth_test.rb +19 -0
  100. data/test/integration/blobs/blob_test.rb +61 -0
  101. data/test/integration/blobs/clear_page_range_test.rb +19 -0
  102. data/test/integration/blobs/copy_test.rb +33 -0
  103. data/test/integration/blobs/create_blobs_test.rb +51 -0
  104. data/test/integration/blobs/create_container_test.rb +13 -0
  105. data/test/integration/blobs/create_snapshot_test.rb +17 -0
  106. data/test/integration/blobs/delete_blob_snapshots_test.rb +19 -0
  107. data/test/integration/blobs/delete_blobs_test.rb +25 -0
  108. data/test/integration/blobs/delete_container_test.rb +24 -0
  109. data/test/integration/blobs/delete_snapshot_test.rb +17 -0
  110. data/test/integration/blobs/get_blob_snapshot_test.rb +18 -0
  111. data/test/integration/blobs/get_blobs_test.rb +31 -0
  112. data/test/integration/blobs/get_page_range_test.rb +19 -0
  113. data/test/integration/blobs/list_blobs_test.rb +39 -0
  114. data/test/integration/blobs/list_containers_test.rb +28 -0
  115. data/test/integration/blobs/manage_blob_leases_test.rb +45 -0
  116. data/test/integration/blobs/manage_blob_metadata_test.rb +51 -0
  117. data/test/integration/blobs/manage_blob_properties_test.rb +25 -0
  118. data/test/integration/blobs/manage_blob_service_properties_test.rb +38 -0
  119. data/test/integration/blobs/manage_container_metadata_test.rb +46 -0
  120. data/test/integration/blobs/manage_container_permissions_test.rb +17 -0
  121. data/test/integration/blobs/update_page_range_test.rb +20 -0
  122. data/test/integration/queues/clear_messages_test.rb +22 -0
  123. data/test/integration/queues/create_queue_test.rb +13 -0
  124. data/test/integration/queues/delete_message_test.rb +42 -0
  125. data/test/integration/queues/delete_queue_test.rb +24 -0
  126. data/test/integration/queues/get_messages_test.rb +39 -0
  127. data/test/integration/queues/list_queues_test.rb +43 -0
  128. data/test/integration/queues/manage_queue_metadata_test.rb +45 -0
  129. data/test/integration/queues/manage_queue_service_properties_test.rb +27 -0
  130. data/test/integration/queues/peek_messages_test.rb +55 -0
  131. data/test/integration/queues/put_message_test.rb +31 -0
  132. data/test/integration/queues/update_message_test.rb +46 -0
  133. data/test/integration/service_bus/auth_test.rb +18 -0
  134. data/test/integration/service_bus/queues/create_queue_test.rb +25 -0
  135. data/test/integration/service_bus/queues/delete_message_from_queue_test.rb +29 -0
  136. data/test/integration/service_bus/queues/delete_queue_test.rb +25 -0
  137. data/test/integration/service_bus/queues/get_queue_test.rb +23 -0
  138. data/test/integration/service_bus/queues/list_queues_test.rb +39 -0
  139. data/test/integration/service_bus/queues/peek_message_from_queue_test.rb +34 -0
  140. data/test/integration/service_bus/queues/read_and_delete_message_from_queue_test.rb +31 -0
  141. data/test/integration/service_bus/queues/send_message_to_queue_test.rb +22 -0
  142. data/test/integration/service_bus/queues/unlock_message_from_queue_test.rb +36 -0
  143. data/test/integration/service_bus/rules/create_rule_test.rb +19 -0
  144. data/test/integration/service_bus/rules/delete_rule_test.rb +17 -0
  145. data/test/integration/service_bus/rules/get_rule_test.rb +21 -0
  146. data/test/integration/service_bus/rules/list_rules_test.rb +24 -0
  147. data/test/integration/service_bus/rules/rule_test.rb +16 -0
  148. data/test/integration/service_bus/subscriptions/create_subscription_test.rb +25 -0
  149. data/test/integration/service_bus/subscriptions/delete_message_from_subscription_test.rb +31 -0
  150. data/test/integration/service_bus/subscriptions/delete_subscription_test.rb +30 -0
  151. data/test/integration/service_bus/subscriptions/fetch_subscription_test.rb +28 -0
  152. data/test/integration/service_bus/subscriptions/list_subscriptions_test.rb +23 -0
  153. data/test/integration/service_bus/subscriptions/peek_lock_message_from_subscription_test.rb +42 -0
  154. data/test/integration/service_bus/subscriptions/read_delete_message_from_subscription_test.rb +36 -0
  155. data/test/integration/service_bus/subscriptions/subscription_test.rb +31 -0
  156. data/test/integration/service_bus/subscriptions/unlock_message_from_subscription_test.rb +43 -0
  157. data/test/integration/service_bus/topics/create_topic_test.rb +25 -0
  158. data/test/integration/service_bus/topics/delete_topic_test.rb +25 -0
  159. data/test/integration/service_bus/topics/get_topic_test.rb +23 -0
  160. data/test/integration/service_bus/topics/list_topics_test.rb +39 -0
  161. data/test/integration/service_bus/topics/send_message_to_topic_test.rb +23 -0
  162. data/test/integration/tables/auth_test.rb +29 -0
  163. data/test/integration/tables/creating_tables_test.rb +16 -0
  164. data/test/integration/tables/delete_entity_test.rb +39 -0
  165. data/test/integration/tables/deleting_table_test.rb +22 -0
  166. data/test/integration/tables/insert_entity_test.rb +23 -0
  167. data/test/integration/tables/merge_entity_test.rb +28 -0
  168. data/test/integration/tables/query_entities_test.rb +131 -0
  169. data/test/integration/tables/query_tables_test.rb +63 -0
  170. data/test/integration/tables/update_entity_test.rb +54 -0
  171. data/test/integration/test_helper.rb +14 -0
  172. data/test/support/blobs.rb +12 -0
  173. data/test/support/env.rb +5 -0
  174. data/test/support/fixtures.rb +22 -0
  175. data/test/support/stubs.rb +28 -0
  176. data/test/support/table_names.rb +44 -0
  177. data/test/test_helper.rb +10 -0
  178. data/test/unit/atom_test.rb +58 -0
  179. data/test/unit/auth_test.rb +24 -0
  180. data/test/unit/blobs/blob_test.rb +5 -0
  181. data/test/unit/blobs/container_test.rb +67 -0
  182. data/test/unit/blobs/service_test.rb +17 -0
  183. data/test/unit/blobs/shared_access_signature_test.rb +66 -0
  184. data/test/unit/blobs_test.rb +156 -0
  185. data/test/unit/core/service_test.rb +57 -0
  186. data/test/unit/core/utils/interval_test.rb +70 -0
  187. data/test/unit/core/utils/queryable_test.rb +69 -0
  188. data/test/unit/core/utils/storage_service_properties_test.rb +66 -0
  189. data/test/unit/error_test.rb +39 -0
  190. data/test/unit/queues/message_test.rb +40 -0
  191. data/test/unit/queues/queue_test.rb +64 -0
  192. data/test/unit/queues/service_properties.rb +35 -0
  193. data/test/unit/request_test.rb +38 -0
  194. data/test/unit/response_test.rb +43 -0
  195. data/test/unit/service_bus/auth/authorizer_test.rb +27 -0
  196. data/test/unit/service_bus/auth/wrap_token_test.rb +28 -0
  197. data/test/unit/service_bus/queues/queue_test.rb +38 -0
  198. data/test/unit/service_bus/topics/topic_test.rb +33 -0
  199. data/test/unit/service_runtime/data/goalstate.xml +9 -0
  200. data/test/unit/service_runtime/data/roleenvironmentdata.xml +29 -0
  201. data/test/unit/service_runtime/data/runtime.xml +6 -0
  202. data/test/unit/service_runtime/role_environment_test.rb +144 -0
  203. data/test/unit/tables/auth/shared_key_lite_test.rb +39 -0
  204. data/test/unit/tables/auth/shared_key_test.rb +45 -0
  205. data/test/unit/tables/entities_collection_test.rb +39 -0
  206. data/test/unit/tables/entity_test.rb +72 -0
  207. data/test/unit/tables/table_test.rb +57 -0
  208. data/test/unit/tables_test.rb +302 -0
  209. data/test/unit/types_test.rb +67 -0
  210. metadata +310 -47
  211. data/LICENSE +0 -0
  212. data/README +0 -0
@@ -0,0 +1,60 @@
1
+ require "azure/configuration"
2
+ require "uri"
3
+
4
+ module Azure
5
+ module Blobs
6
+ module URI
7
+ # Public: Generate the URI for the collection of containers.
8
+ #
9
+ # query - A Hash of key => value query parameters.
10
+ # host - The host of the API.
11
+ #
12
+ # Returns a URI.
13
+ def self.containers(query={}, host=Azure.config.blob_host)
14
+ query = { "comp" => "list" }.merge(query)
15
+ uri = join(host, "/")
16
+ uri.query = ::URI.encode_www_form(query)
17
+ uri
18
+ end
19
+
20
+ # Public: Generate the URI for a specific container.
21
+ #
22
+ # name - The container name. If this is a URI, we just return this.
23
+ # query - A Hash of key => value query parameters.
24
+ # host - The host of the API.
25
+ #
26
+ # Returns a URI.
27
+ def self.container(name, query={}, host=Azure.config.blob_host)
28
+ return name if name.kind_of? ::URI
29
+ query = { "restype" => "container" }.merge(query)
30
+ uri = join(host, name)
31
+ uri.query = ::URI.encode_www_form(query)
32
+ uri
33
+ end
34
+
35
+ # Public: Generate the URI for a specific Blob.
36
+ #
37
+ # container_name - String representing the name of the container.
38
+ # blob_name - String representing the name of the blob.
39
+ # query - A Hash of key => value query parameters.
40
+ # host - The host of the API.
41
+ #
42
+ # Returns a URI.
43
+ def self.blob(container_name, blob_name, query={}, host=Azure.config.blob_host)
44
+ uri = join(host, File.join(container_name, blob_name))
45
+ uri.query = ::URI.encode_www_form(query)
46
+ uri
47
+ end
48
+
49
+ # Utility method to generate the URI.
50
+ #
51
+ # host - A String with the URI's host.
52
+ # path - A String with the URI's path.
53
+ #
54
+ # Returns a URI.
55
+ def self.join(host, path)
56
+ ::URI.parse(File.join(host, path))
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,121 @@
1
+ require "singleton"
2
+
3
+ module Azure
4
+ # Public: Sugar to configure the services in a neatly wrapped DSL.
5
+ #
6
+ # Yields the Azure::Configuration instance.
7
+ #
8
+ # Example:
9
+ #
10
+ # Azure.configure do |config|
11
+ # config.account_name = ENV["AZURE_ACCOUNT_NAME"]
12
+ # end
13
+ #
14
+ # Returns nothing.
15
+ def self.configure
16
+ yield config
17
+ end
18
+
19
+ # Public: Access the service configuration.
20
+ #
21
+ # Returns the Azure::Configuration instance.
22
+ def self.config
23
+ Configuration.instance
24
+ end
25
+
26
+ # Singleton that keeps the configuration of the system.
27
+ class Configuration
28
+ include Singleton
29
+
30
+ # Public: Get/Set the Access Key for this service.
31
+ attr_accessor :access_key
32
+
33
+ # Public: Get/Set the Account Name for this service.
34
+ attr_accessor :account_name
35
+
36
+ # # Public: Get/Set the Access Control Namespace for this service.
37
+ # attr_accessor :acs_namespace
38
+
39
+ # Public: Get/Set the Service Bus Access Key (Issuer Secret) for this service.
40
+ attr_accessor :sb_access_key
41
+
42
+ # Public: Get/Set the Service Bus Issuer for this service.
43
+ attr_accessor :sb_issuer
44
+
45
+ # Public: Get/Set the ACS namespace for this service.
46
+ attr_accessor :acs_namespace
47
+
48
+ # Public: Set the host for the Table service. Only set this if you want
49
+ # something custom (like, for example, to point this to a LocalStorage
50
+ # emulator). This should be the complete host, including http:// at the
51
+ # start. When using the emulator, make sure to include your account name at
52
+ # the end.
53
+ #
54
+ # Example:
55
+ #
56
+ # config.table_host = "http://127.0.0.1:10002/devstoreaccount1"
57
+ attr_writer :table_host
58
+
59
+ # Public: Get the host for this service. If you set something using #host=,
60
+ # then we use that. Else we default to Windows Azure's default hosts, based
61
+ # on your account name.
62
+ def table_host
63
+ @table_host || default_host(:table)
64
+ end
65
+
66
+ # Public: Set the host for the Blob service. Only set this if you want
67
+ # something custom (like, for example, to point this to a LocalStorage
68
+ # emulator). This should be the complete host, including http:// at the
69
+ # start. When using the emulator, make sure to include your account name at
70
+ # the end.
71
+ #
72
+ # Example:
73
+ #
74
+ # config.blob_host = "http://127.0.0.1:10000/devstoreaccount1"
75
+ attr_writer :blob_host
76
+
77
+ # Public: Get the host for this service. If you set something using #host=,
78
+ # then we use that. Else we default to Windows Azure's default hosts, based
79
+ # on your account name.
80
+ def blob_host
81
+ @blob_host || default_host(:blob)
82
+ end
83
+
84
+ # Public: Set the host for the Queue service. Only set this if you want
85
+ # something custom (like, for example, to point this to a LocalStorage
86
+ # emulator). This should be the complete host, including http:// at the
87
+ # start. When using the emulator, make sure to include your account name at
88
+ # the end.
89
+ #
90
+ # Example:
91
+ #
92
+ # config.queue_host = "http://127.0.0.1:10001/devstoreaccount1"
93
+ attr_writer :queue_host
94
+
95
+ # Public: Get the host for this service. If you set something using #host=,
96
+ # then we use that. Else we default to Windows Azure's default hosts, based
97
+ # on your account name.
98
+ def queue_host
99
+ @queue_host || default_host(:queue)
100
+ end
101
+
102
+ # Public: Get the host for the ACS service.
103
+ def acs_host
104
+ "https://#{acs_namespace}-sb.accesscontrol.windows.net"
105
+ end
106
+
107
+ # Public: Get the host for the Service Bus service.
108
+ def service_bus_host
109
+ "https://#{acs_namespace}.servicebus.windows.net"
110
+ end
111
+
112
+ # Calculate the default host for a given service in the cloud.
113
+ #
114
+ # service - One of :table, :blob, :queue, etc.
115
+ #
116
+ # Returns a String with the hostname, including your account name.
117
+ def default_host(service)
118
+ "http://#{account_name}.#{service}.core.windows.net"
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,95 @@
1
+ require "cgi"
2
+ require "azure/configuration"
3
+ require "azure/core/signer"
4
+
5
+ module Azure
6
+ module Core
7
+ module Auth
8
+ class SharedKey < Signer
9
+ # The Azure account's name.
10
+ attr :account_name
11
+
12
+ # Public: Initialize the Signer.
13
+ #
14
+ # account_name - The Azure account name. Defaults to the one in the
15
+ # global configuration.
16
+ # access_key - The Azure access_key encoded in Base64. Defaults to the
17
+ # one in the global configuration.
18
+ def initialize(account_name=Azure.config.account_name, access_key=Azure.config.access_key)
19
+ @account_name = account_name
20
+ super(access_key)
21
+ end
22
+
23
+ # Public: The name of the strategy.
24
+ #
25
+ # Returns a String.
26
+ def name
27
+ "SharedKey"
28
+ end
29
+
30
+ # Public: Generate a request signature.
31
+ #
32
+ # verb - The HTTP request method.
33
+ # uri - The URI of the request we're signing.
34
+ # headers - A Hash of HTTP request headers.
35
+ #
36
+ # Returns a Base64 String signed with HMAC.
37
+ def sign(method, uri, headers)
38
+ super(signable_string(method, uri, headers))
39
+ end
40
+
41
+ # Generate the string to sign.
42
+ #
43
+ # verb - The HTTP request method.
44
+ # uri - The URI of the request we're signing.
45
+ # headers - A Hash of HTTP request headers.
46
+ #
47
+ # Returns a plain text string.
48
+ def signable_string(method, uri, headers)
49
+ [
50
+ method.to_s.upcase,
51
+ headers.fetch("Content-Encoding", ""),
52
+ headers.fetch("Content-Language", ""),
53
+ headers.fetch("Content-Length", ""),
54
+ headers.fetch("Content-MD5", ""),
55
+ headers.fetch("Content-Type", ""),
56
+ headers.fetch("Date", ""),
57
+ headers.fetch("If-Modified-Since", ""),
58
+ headers.fetch("If-Match", ""),
59
+ headers.fetch("If-None-Match", ""),
60
+ headers.fetch("If-Unmodified-Since", ""),
61
+ headers.fetch("Range", ""),
62
+ canonicalized_headers(headers),
63
+ canonicalized_resource(uri)
64
+ ].join("\n")
65
+ end
66
+
67
+ # Calculate the Canonicalized Headers string for a request.
68
+ #
69
+ # headers - A Hash of HTTP request headers.
70
+ #
71
+ # Returns a string with the canonicalized headers.
72
+ def canonicalized_headers(headers)
73
+ headers = headers.map { |k,v| [k.to_s.downcase, v] }
74
+ headers.select! { |k,v| k =~ /^x-ms-/ }
75
+ headers.sort_by! { |(k,v)| k }
76
+ headers.map! { |k,v| "%s:%s" % [k, v] }
77
+ headers.map! { |h| h.gsub(/\s+/, " ") }.join("\n")
78
+ end
79
+
80
+ # Calculate the Canonicalized Resource string for a request.
81
+ #
82
+ # uri - The request's URI.
83
+ #
84
+ # Returns a string with the canonicalized resource.
85
+ def canonicalized_resource(uri)
86
+ resource = "/" + account_name + (uri.path.empty? ? "/" : uri.path)
87
+ params = CGI.parse(uri.query.to_s).map { |k,v| [k.downcase, v] }
88
+ params.sort_by! { |k,v| k }
89
+ params.map! { |k,v| "%s:%s" % [k, v.map(&:strip).sort.join(",")] }
90
+ [resource, *params].join("\n")
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,34 @@
1
+ require "azure/core/auth/shared_key"
2
+
3
+ module Azure
4
+ module Core
5
+ module Auth
6
+ class SharedKeyLite < SharedKey
7
+ # Public: The name of the strategy.
8
+ #
9
+ # Returns a String.
10
+ def name
11
+ "SharedKeyLite"
12
+ end
13
+
14
+ # Generate the string to sign.
15
+ #
16
+ # verb - The HTTP request method.
17
+ # uri - The URI of the request we're signing.
18
+ # headers - A Hash of HTTP request headers.
19
+ #
20
+ # Returns a plain text string.
21
+ def signable_string(method, uri, headers)
22
+ [
23
+ method.to_s.upcase,
24
+ headers.fetch("Content-MD5", ""),
25
+ headers.fetch("Content-Type", ""),
26
+ headers.fetch("Date") { raise KeyError, "Headers must include Date" },
27
+ canonicalized_headers(uri).join("\n"),
28
+ canonicalized_resource(uri).join("\n")
29
+ ].join("\n")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,118 @@
1
+ require "delegate"
2
+
3
+ module Azure
4
+ module Core
5
+ # A collection serves two functions: it is an array of models, and at the
6
+ # same time serves as a proxy to certain services for the models in the
7
+ # array.
8
+ #
9
+ # A Collection belongs to a "parent" object; for example, a collection
10
+ # of mesages belongs to a queue.
11
+ #
12
+ # Examples
13
+ #
14
+ # # Get the collection
15
+ # queue.messages
16
+ #
17
+ # # Create a new message
18
+ # queue.messages.create("message text")
19
+ #
20
+ # # Fetch a single message
21
+ # message = queue.messages["some-message-id"]
22
+ #
23
+ # # Work with the messages
24
+ # queue.messages.each { |msg| ... }
25
+ class Collection < DelegateClass(Array)
26
+ include Azure::ErrorHandler
27
+
28
+ # Public: Initialize the collection.
29
+ #
30
+ # parent - The object that owns this collection.
31
+ # as - The name of the relationship between the collection's
32
+ # items and the parent.
33
+ # model_class - The class of the model this collection represents.
34
+ # service - The service that implements remote calls.
35
+ def initialize(parent, as, model_class, service)
36
+ @parent = parent
37
+ @as = as
38
+ @model_class = model_class
39
+ @service = service
40
+ end
41
+
42
+ # Public: Load the underlying collection from the server.
43
+ #
44
+ # Returns self.
45
+ def load!
46
+ collection = @service.all(@parent)
47
+ collection.each { |el| set_parent(el) }
48
+ __setobj__(collection)
49
+ self
50
+ end
51
+
52
+ # Public: Create a new model in this collection.
53
+ #
54
+ # *args - Any arguments that the model's constructor takes.
55
+ #
56
+ # Yields the model before being created for modification.
57
+ #
58
+ # Returns an instance of the model.
59
+ def create(*args, &block)
60
+ model = @model_class.new(*args, &block)
61
+ set_parent(model)
62
+ @service.create(model)
63
+ end
64
+
65
+ # Public: Fetch a model by its identifier(s).
66
+ #
67
+ # *ids - The identifier(s) of the model.
68
+ #
69
+ # Returns an instance of the model when it's a valid identifier.
70
+ # Returns nil when no model matches the identifier.
71
+ def [](*ids)
72
+ fetch(*ids) { nil }
73
+ end
74
+
75
+ # Public: Find a model by its identifier(s). If no model matches the
76
+ # provided identifier(s), execute the given block, or raise ArgumentError.
77
+ #
78
+ # *ids - The identifier(s) of the model.
79
+ #
80
+ # Yields the error returned by the server in case the model wasn't found.
81
+ #
82
+ # Returns an instance of the model.
83
+ # Raises ArgumentError if the model isn't found and no block is given.
84
+ def fetch(*ids, &block)
85
+ block ||= -> { raise ArgumentError, "can't find #{@model_class} identified by #{id.inspect}" }
86
+ model = @service.fetch(@parent, *ids)
87
+ model.valid? ? model : block.call(model.error)
88
+ end
89
+
90
+ # Internal: Get the underlying collection to which we delegate. If the
91
+ # collection wasn't already loaded, it loads it from the server.
92
+ #
93
+ # Returns an Array.
94
+ def __getobj__
95
+ load! unless defined?(@__delegated_list)
96
+ @__delegated_list
97
+ end
98
+
99
+ # Internal: Change the underlying collection to which we delegate.
100
+ #
101
+ # collection - An Array.
102
+ #
103
+ # Returns the collection.
104
+ def __setobj__(collection)
105
+ @__delegated_list = collection
106
+ end
107
+
108
+ # Internal: Change the parent object of the given model.
109
+ #
110
+ # object - A model in this collection.
111
+ #
112
+ # Returns the parent.
113
+ def set_parent(object)
114
+ object.send("#{@as}=", @parent)
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,43 @@
1
+ require "azure/request"
2
+ require "azure/auth"
3
+
4
+ module Azure
5
+ module Core
6
+ class Service
7
+ # Initialize the service.
8
+ #
9
+ # signer - The strategy to use to sign requests.
10
+ # auth - Authorizer object. Defaults to Azure::Auth.new
11
+ def initialize(signer, auth=Azure::Auth.new)
12
+ @signer = signer
13
+ @auth = auth
14
+ end
15
+
16
+ # Sign a request to include the necessary authorization header.
17
+ #
18
+ # request - An Azure::Request.
19
+ # signer - A signer strategy (defaults to Azure::Tables::Auth::SharedKey)
20
+ #
21
+ # Returns the signed request.
22
+ def sign_request(request)
23
+ @auth.sign(request, @signer)
24
+ end
25
+
26
+ # Invoke the service.
27
+ #
28
+ # method - The HTTP method.
29
+ # uri - The URI path for this service call.
30
+ # body - The request body, if any (defaults to nil).
31
+ #
32
+ # Yields the request before signing it.
33
+ #
34
+ # Returns the Response object.
35
+ def call(method, uri, body=nil, request_factory=Request)
36
+ request = request_factory.new(method, uri, body)
37
+ yield request if block_given?
38
+ sign_request(request)
39
+ request.request!
40
+ end
41
+ end
42
+ end
43
+ end