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.
- data/Gemfile +3 -0
- data/Gemfile.lock +36 -0
- data/README.md +3 -0
- data/Rakefile +81 -0
- data/azure.gemspec +20 -9
- data/lib/azure.rb +4 -0
- data/lib/azure/atom.rb +170 -0
- data/lib/azure/auth.rb +29 -0
- data/lib/azure/blobs.rb +620 -0
- data/lib/azure/blobs/blob.rb +360 -0
- data/lib/azure/blobs/container.rb +209 -0
- data/lib/azure/blobs/service.rb +396 -0
- data/lib/azure/blobs/shared_access_signature.rb +84 -0
- data/lib/azure/blobs/uri.rb +60 -0
- data/lib/azure/configuration.rb +121 -0
- data/lib/azure/core/auth/shared_key.rb +95 -0
- data/lib/azure/core/auth/shared_key_lite.rb +34 -0
- data/lib/azure/core/collection.rb +118 -0
- data/lib/azure/core/service.rb +43 -0
- data/lib/azure/core/signer.rb +32 -0
- data/lib/azure/core/utils/interval.rb +97 -0
- data/lib/azure/core/utils/queryable.rb +74 -0
- data/lib/azure/core/utils/storage_service_properties.rb +83 -0
- data/lib/azure/core/utils/string.rb +59 -0
- data/lib/azure/error.rb +72 -0
- data/lib/azure/queues.rb +272 -0
- data/lib/azure/queues/message.rb +174 -0
- data/lib/azure/queues/queue.rb +187 -0
- data/lib/azure/queues/service.rb +263 -0
- data/lib/azure/queues/service_properties.rb +152 -0
- data/lib/azure/queues/uri.rb +78 -0
- data/lib/azure/request.rb +102 -0
- data/lib/azure/response.rb +93 -0
- data/lib/azure/service_bus.rb +4 -0
- data/lib/azure/service_bus/auth/authorizer.rb +22 -0
- data/lib/azure/service_bus/auth/uri.rb +52 -0
- data/lib/azure/service_bus/auth/wrap.rb +37 -0
- data/lib/azure/service_bus/auth/wrap_service.rb +76 -0
- data/lib/azure/service_bus/auth/wrap_token.rb +45 -0
- data/lib/azure/service_bus/auth/wrap_token_manager.rb +46 -0
- data/lib/azure/service_bus/brokered_message.rb +139 -0
- data/lib/azure/service_bus/brokered_message_serializer.rb +113 -0
- data/lib/azure/service_bus/queues.rb +194 -0
- data/lib/azure/service_bus/queues/queue.rb +100 -0
- data/lib/azure/service_bus/queues/queue_serializer.rb +51 -0
- data/lib/azure/service_bus/queues/service.rb +154 -0
- data/lib/azure/service_bus/queues/uri.rb +80 -0
- data/lib/azure/service_bus/rules.rb +110 -0
- data/lib/azure/service_bus/rules/rule.rb +97 -0
- data/lib/azure/service_bus/rules/service.rb +122 -0
- data/lib/azure/service_bus/rules/uri.rb +39 -0
- data/lib/azure/service_bus/service_bus_service.rb +22 -0
- data/lib/azure/service_bus/subscriptions.rb +170 -0
- data/lib/azure/service_bus/subscriptions/service.rb +133 -0
- data/lib/azure/service_bus/subscriptions/subscription.rb +164 -0
- data/lib/azure/service_bus/subscriptions/subscription_serializer.rb +74 -0
- data/lib/azure/service_bus/subscriptions/uri.rb +71 -0
- data/lib/azure/service_bus/topics.rb +120 -0
- data/lib/azure/service_bus/topics/service.rb +98 -0
- data/lib/azure/service_bus/topics/topic.rb +122 -0
- data/lib/azure/service_bus/topics/topic_serializer.rb +44 -0
- data/lib/azure/service_bus/topics/uri.rb +58 -0
- data/lib/azure/service_runtime/client/goal_state_pipe_monitor.rb +21 -0
- data/lib/azure/service_runtime/client/goal_state_protocol.rb +18 -0
- data/lib/azure/service_runtime/client/runtime_client.rb +135 -0
- data/lib/azure/service_runtime/deployment.rb +24 -0
- data/lib/azure/service_runtime/local_resource.rb +15 -0
- data/lib/azure/service_runtime/role.rb +17 -0
- data/lib/azure/service_runtime/role_environment.rb +206 -0
- data/lib/azure/service_runtime/role_environment_change.rb +32 -0
- data/lib/azure/service_runtime/role_instance.rb +35 -0
- data/lib/azure/service_runtime/role_instance_endpoint.rb +14 -0
- data/lib/azure/tables.rb +215 -0
- data/lib/azure/tables/auth/shared_key.rb +71 -0
- data/lib/azure/tables/auth/shared_key_lite.rb +30 -0
- data/lib/azure/tables/entities_collection.rb +66 -0
- data/lib/azure/tables/entity.rb +127 -0
- data/lib/azure/tables/service.rb +211 -0
- data/lib/azure/tables/table.rb +129 -0
- data/lib/azure/tables/tables_collection.rb +62 -0
- data/lib/azure/tables/types.rb +65 -0
- data/lib/azure/tables/uri.rb +62 -0
- data/test/fixtures/32px-fulls-black.jpg +0 -0
- data/test/fixtures/all_containers.xml +20 -0
- data/test/fixtures/all_tables.xml +22 -0
- data/test/fixtures/create_table_response_entry.xml +15 -0
- data/test/fixtures/error.xml +5 -0
- data/test/fixtures/insert_entity_response_entry.xml +25 -0
- data/test/fixtures/messages.xml +12 -0
- data/test/fixtures/query_entities_empty_response.xml +7 -0
- data/test/fixtures/query_entities_response.xml +45 -0
- data/test/fixtures/queue_service_properties.xml +22 -0
- data/test/fixtures/queue_service_properties_original.xml +19 -0
- data/test/fixtures/queues.xml +16 -0
- data/test/fixtures/sb_default_create_queue_response.xml +23 -0
- data/test/fixtures/sb_default_create_topic_response.xml +18 -0
- data/test/fixtures/sb_get_access_token_response.txt +1 -0
- data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
- data/test/integration/blobs/auth_test.rb +19 -0
- data/test/integration/blobs/blob_test.rb +61 -0
- data/test/integration/blobs/clear_page_range_test.rb +19 -0
- data/test/integration/blobs/copy_test.rb +33 -0
- data/test/integration/blobs/create_blobs_test.rb +51 -0
- data/test/integration/blobs/create_container_test.rb +13 -0
- data/test/integration/blobs/create_snapshot_test.rb +17 -0
- data/test/integration/blobs/delete_blob_snapshots_test.rb +19 -0
- data/test/integration/blobs/delete_blobs_test.rb +25 -0
- data/test/integration/blobs/delete_container_test.rb +24 -0
- data/test/integration/blobs/delete_snapshot_test.rb +17 -0
- data/test/integration/blobs/get_blob_snapshot_test.rb +18 -0
- data/test/integration/blobs/get_blobs_test.rb +31 -0
- data/test/integration/blobs/get_page_range_test.rb +19 -0
- data/test/integration/blobs/list_blobs_test.rb +39 -0
- data/test/integration/blobs/list_containers_test.rb +28 -0
- data/test/integration/blobs/manage_blob_leases_test.rb +45 -0
- data/test/integration/blobs/manage_blob_metadata_test.rb +51 -0
- data/test/integration/blobs/manage_blob_properties_test.rb +25 -0
- data/test/integration/blobs/manage_blob_service_properties_test.rb +38 -0
- data/test/integration/blobs/manage_container_metadata_test.rb +46 -0
- data/test/integration/blobs/manage_container_permissions_test.rb +17 -0
- data/test/integration/blobs/update_page_range_test.rb +20 -0
- data/test/integration/queues/clear_messages_test.rb +22 -0
- data/test/integration/queues/create_queue_test.rb +13 -0
- data/test/integration/queues/delete_message_test.rb +42 -0
- data/test/integration/queues/delete_queue_test.rb +24 -0
- data/test/integration/queues/get_messages_test.rb +39 -0
- data/test/integration/queues/list_queues_test.rb +43 -0
- data/test/integration/queues/manage_queue_metadata_test.rb +45 -0
- data/test/integration/queues/manage_queue_service_properties_test.rb +27 -0
- data/test/integration/queues/peek_messages_test.rb +55 -0
- data/test/integration/queues/put_message_test.rb +31 -0
- data/test/integration/queues/update_message_test.rb +46 -0
- data/test/integration/service_bus/auth_test.rb +18 -0
- data/test/integration/service_bus/queues/create_queue_test.rb +25 -0
- data/test/integration/service_bus/queues/delete_message_from_queue_test.rb +29 -0
- data/test/integration/service_bus/queues/delete_queue_test.rb +25 -0
- data/test/integration/service_bus/queues/get_queue_test.rb +23 -0
- data/test/integration/service_bus/queues/list_queues_test.rb +39 -0
- data/test/integration/service_bus/queues/peek_message_from_queue_test.rb +34 -0
- data/test/integration/service_bus/queues/read_and_delete_message_from_queue_test.rb +31 -0
- data/test/integration/service_bus/queues/send_message_to_queue_test.rb +22 -0
- data/test/integration/service_bus/queues/unlock_message_from_queue_test.rb +36 -0
- data/test/integration/service_bus/rules/create_rule_test.rb +19 -0
- data/test/integration/service_bus/rules/delete_rule_test.rb +17 -0
- data/test/integration/service_bus/rules/get_rule_test.rb +21 -0
- data/test/integration/service_bus/rules/list_rules_test.rb +24 -0
- data/test/integration/service_bus/rules/rule_test.rb +16 -0
- data/test/integration/service_bus/subscriptions/create_subscription_test.rb +25 -0
- data/test/integration/service_bus/subscriptions/delete_message_from_subscription_test.rb +31 -0
- data/test/integration/service_bus/subscriptions/delete_subscription_test.rb +30 -0
- data/test/integration/service_bus/subscriptions/fetch_subscription_test.rb +28 -0
- data/test/integration/service_bus/subscriptions/list_subscriptions_test.rb +23 -0
- data/test/integration/service_bus/subscriptions/peek_lock_message_from_subscription_test.rb +42 -0
- data/test/integration/service_bus/subscriptions/read_delete_message_from_subscription_test.rb +36 -0
- data/test/integration/service_bus/subscriptions/subscription_test.rb +31 -0
- data/test/integration/service_bus/subscriptions/unlock_message_from_subscription_test.rb +43 -0
- data/test/integration/service_bus/topics/create_topic_test.rb +25 -0
- data/test/integration/service_bus/topics/delete_topic_test.rb +25 -0
- data/test/integration/service_bus/topics/get_topic_test.rb +23 -0
- data/test/integration/service_bus/topics/list_topics_test.rb +39 -0
- data/test/integration/service_bus/topics/send_message_to_topic_test.rb +23 -0
- data/test/integration/tables/auth_test.rb +29 -0
- data/test/integration/tables/creating_tables_test.rb +16 -0
- data/test/integration/tables/delete_entity_test.rb +39 -0
- data/test/integration/tables/deleting_table_test.rb +22 -0
- data/test/integration/tables/insert_entity_test.rb +23 -0
- data/test/integration/tables/merge_entity_test.rb +28 -0
- data/test/integration/tables/query_entities_test.rb +131 -0
- data/test/integration/tables/query_tables_test.rb +63 -0
- data/test/integration/tables/update_entity_test.rb +54 -0
- data/test/integration/test_helper.rb +14 -0
- data/test/support/blobs.rb +12 -0
- data/test/support/env.rb +5 -0
- data/test/support/fixtures.rb +22 -0
- data/test/support/stubs.rb +28 -0
- data/test/support/table_names.rb +44 -0
- data/test/test_helper.rb +10 -0
- data/test/unit/atom_test.rb +58 -0
- data/test/unit/auth_test.rb +24 -0
- data/test/unit/blobs/blob_test.rb +5 -0
- data/test/unit/blobs/container_test.rb +67 -0
- data/test/unit/blobs/service_test.rb +17 -0
- data/test/unit/blobs/shared_access_signature_test.rb +66 -0
- data/test/unit/blobs_test.rb +156 -0
- data/test/unit/core/service_test.rb +57 -0
- data/test/unit/core/utils/interval_test.rb +70 -0
- data/test/unit/core/utils/queryable_test.rb +69 -0
- data/test/unit/core/utils/storage_service_properties_test.rb +66 -0
- data/test/unit/error_test.rb +39 -0
- data/test/unit/queues/message_test.rb +40 -0
- data/test/unit/queues/queue_test.rb +64 -0
- data/test/unit/queues/service_properties.rb +35 -0
- data/test/unit/request_test.rb +38 -0
- data/test/unit/response_test.rb +43 -0
- data/test/unit/service_bus/auth/authorizer_test.rb +27 -0
- data/test/unit/service_bus/auth/wrap_token_test.rb +28 -0
- data/test/unit/service_bus/queues/queue_test.rb +38 -0
- data/test/unit/service_bus/topics/topic_test.rb +33 -0
- data/test/unit/service_runtime/data/goalstate.xml +9 -0
- data/test/unit/service_runtime/data/roleenvironmentdata.xml +29 -0
- data/test/unit/service_runtime/data/runtime.xml +6 -0
- data/test/unit/service_runtime/role_environment_test.rb +144 -0
- data/test/unit/tables/auth/shared_key_lite_test.rb +39 -0
- data/test/unit/tables/auth/shared_key_test.rb +45 -0
- data/test/unit/tables/entities_collection_test.rb +39 -0
- data/test/unit/tables/entity_test.rb +72 -0
- data/test/unit/tables/table_test.rb +57 -0
- data/test/unit/tables_test.rb +302 -0
- data/test/unit/types_test.rb +67 -0
- metadata +310 -47
- data/LICENSE +0 -0
- 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
|