waz-storage 1.2.0 → 1.3.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/.gitignore +9 -9
- data/CHANGELOG.rdoc +72 -72
- data/Gemfile +4 -4
- data/Gemfile.lock +46 -40
- data/LICENSE +18 -18
- data/README.rdoc +310 -310
- data/lib/waz-blobs.rb +4 -4
- data/lib/waz-queues.rb +6 -6
- data/lib/waz-storage.rb +39 -39
- data/lib/waz-tables.rb +4 -4
- data/lib/waz/blobs/blob_object.rb +122 -122
- data/lib/waz/blobs/container.rb +172 -161
- data/lib/waz/blobs/exceptions.rb +10 -10
- data/lib/waz/blobs/service.rb +181 -156
- data/lib/waz/queues/exceptions.rb +28 -28
- data/lib/waz/queues/message.rb +64 -64
- data/lib/waz/queues/queue.rb +164 -164
- data/lib/waz/queues/service.rb +105 -105
- data/lib/waz/storage/base.rb +70 -70
- data/lib/waz/storage/exceptions.rb +33 -33
- data/lib/waz/storage/validation_rules.rb +25 -25
- data/lib/waz/tables/edm_type_helper.rb +44 -44
- data/lib/waz/tables/exceptions.rb +44 -44
- data/lib/waz/tables/service.rb +178 -178
- data/lib/waz/tables/table.rb +74 -74
- data/lib/waz/tables/table_array.rb +10 -10
- data/rakefile +8 -21
- data/{tests → spec}/configuration.rb +22 -22
- data/{tests/waz/blobs/blob_object_test.rb → spec/waz/blobs/blob_object_spec.rb} +80 -80
- data/{tests/waz/blobs/container_test.rb → spec/waz/blobs/container_spec.rb} +175 -162
- data/{tests/waz/blobs/service_test.rb → spec/waz/blobs/service_spec.rb} +336 -282
- data/{tests/waz/queues/message_test.rb → spec/waz/queues/message_spec.rb} +32 -32
- data/{tests/waz/queues/queue_test.rb → spec/waz/queues/queue_spec.rb} +205 -205
- data/{tests/waz/queues/service_test.rb → spec/waz/queues/service_spec.rb} +298 -298
- data/{tests → spec}/waz/storage/base_tests.rb +81 -81
- data/{tests/waz/storage/shared_key_core_service_test.rb → spec/waz/storage/shared_key_core_service_spec.rb} +141 -141
- data/{tests/waz/tables/service_test.rb → spec/waz/tables/service_spec.rb} +613 -613
- data/{tests/waz/tables/table_test.rb → spec/waz/tables/table_spec.rb} +97 -97
- data/waz-storage.gemspec +29 -27
- metadata +47 -26
data/lib/waz/queues/queue.rb
CHANGED
@@ -1,165 +1,165 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Queues
|
3
|
-
# This class represents a Queue on Windows Azure Queues API. These are the methods implemented from Microsoft's API description
|
4
|
-
# available on MSDN at http://msdn.microsoft.com/en-us/library/dd179363.aspx
|
5
|
-
#
|
6
|
-
# # list available queues
|
7
|
-
# WAZ::Queues::Queue.list
|
8
|
-
#
|
9
|
-
# # create a queue (here you can also send hashed metadata)
|
10
|
-
# WAZ::Queues::Queue.create('test-queue')
|
11
|
-
#
|
12
|
-
# # get a specific queue
|
13
|
-
# queue = WAZ::Queues::Queue.find('test-queue')
|
14
|
-
#
|
15
|
-
# # get queue properties (including default headers)
|
16
|
-
# queue.metadata #=> hash containing beautified metadata (:x_ms_meta_name)
|
17
|
-
#
|
18
|
-
# # set queue properties (should follow x-ms-meta to be persisted)
|
19
|
-
# # if you specify the optional parameter overwrite, existing metadata
|
20
|
-
# # will be deleted else merged with new one.
|
21
|
-
# queue.put_properties!(:x_ms_meta_MyProperty => "my value")
|
22
|
-
#
|
23
|
-
# # delete queue
|
24
|
-
# queue.destroy!
|
25
|
-
#
|
26
|
-
# # clear queue contents
|
27
|
-
# queue.clear
|
28
|
-
#
|
29
|
-
# # enqueue a message
|
30
|
-
# queue.enqueue!("payload of the message")
|
31
|
-
#
|
32
|
-
# # peek a message/s (do not alter visibility, it can't be deleted neither)
|
33
|
-
# # num_of_messages (1 to 32) to be peeked (default 1)
|
34
|
-
# message = queue.peek
|
35
|
-
#
|
36
|
-
# # lock a message/s.
|
37
|
-
# # num_of_messages (1 to 32) to be peeked (default 1)
|
38
|
-
# # visiblity_timeout (default 60 sec. max 7200 [2hrs])
|
39
|
-
# message = queue.lock
|
40
|
-
#
|
41
|
-
class Queue
|
42
|
-
class << self
|
43
|
-
# Returns an array of the queues (WAZ::Queues::Queue) existing on the current
|
44
|
-
# Windows Azure Storage account.
|
45
|
-
#
|
46
|
-
# include_metadata defines if the metadata is retrieved along with queue data.
|
47
|
-
def list(include_metadata = false)
|
48
|
-
options = include_metadata ? { :include => 'metadata' } : {}
|
49
|
-
service_instance.list_queues(options).map do |queue|
|
50
|
-
WAZ::Queues::Queue.new(queue)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Creates a queue on the current account. If provided the metadata hash will specify additional
|
55
|
-
# metadata to be stored on the queue. (Remember that metadata on the storage account must start with
|
56
|
-
# :x_ms_metadata_{yourCustomPropertyName}, if not it will not be persisted).
|
57
|
-
def create(queue_name, metadata = {})
|
58
|
-
raise WAZ::Storage::InvalidParameterValue, {:name => "name", :values => ["lower letters, numbers or - (hypen), and must not start or end with - (hyphen)"]} unless WAZ::Storage::ValidationRules.valid_name?(queue_name)
|
59
|
-
service_instance.create_queue(queue_name, metadata)
|
60
|
-
WAZ::Queues::Queue.new(:name => queue_name, :url => service_instance.generate_request_uri(queue_name))
|
61
|
-
end
|
62
|
-
|
63
|
-
# Finds a queue by it's name, in case that it isn't found on the current storage account it will
|
64
|
-
# return nil shilding the user from a ResourceNotFound exception.
|
65
|
-
def find(queue_name)
|
66
|
-
begin
|
67
|
-
metadata = service_instance.get_queue_metadata(queue_name)
|
68
|
-
WAZ::Queues::Queue.new(:name => queue_name, :url => service_instance.generate_request_uri(queue_name), :metadata => metadata)
|
69
|
-
rescue RestClient::ResourceNotFound
|
70
|
-
return nil
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Syntax's sugar for find(:queue_name) or create(:queue_name)
|
75
|
-
def ensure(queue_name)
|
76
|
-
return (self.find(queue_name) or self.create(queue_name))
|
77
|
-
end
|
78
|
-
|
79
|
-
# This method is internally used by this class. It's the way we keep a single instance of the
|
80
|
-
# service that wraps the calls the Windows Azure Queues API. It's initialized with the values
|
81
|
-
# from the default_connection on WAZ::Storage::Base initialized thru establish_connection!
|
82
|
-
def service_instance
|
83
|
-
options = WAZ::Storage::Base.default_connection.merge(:type_of_service => "queue")
|
84
|
-
(@service_instances ||= {})[options[:account_name]] ||= Service.new(options)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
attr_accessor :name, :url, :metadata
|
89
|
-
|
90
|
-
def initialize(options = {})
|
91
|
-
raise WAZ::Storage::InvalidOption, :name unless options.keys.include?(:name)
|
92
|
-
raise WAZ::Storage::InvalidOption, :url unless options.keys.include?(:url)
|
93
|
-
self.name = options[:name]
|
94
|
-
self.url = options[:url]
|
95
|
-
self.metadata = options[:metadata]
|
96
|
-
end
|
97
|
-
|
98
|
-
# Deletes the queue from the current storage account.
|
99
|
-
def destroy!
|
100
|
-
self.class.service_instance.delete_queue(self.name)
|
101
|
-
end
|
102
|
-
|
103
|
-
# Retrieves the metadata headers associated with the quere.
|
104
|
-
def metadata
|
105
|
-
metadata ||= self.class.service_instance.get_queue_metadata(self.name)
|
106
|
-
end
|
107
|
-
|
108
|
-
# Sets the metadata given on the new_metadata, when overwrite passed different
|
109
|
-
# than true it overrides the metadata for the queue (removing all existing metadata)
|
110
|
-
def put_properties!(new_metadata = {}, overwrite = false)
|
111
|
-
new_metadata.merge!(metadata.reject { |k, v| !k.to_s.start_with? "x_ms_meta"} ) unless overwrite
|
112
|
-
self.class.service_instance.set_queue_metadata(new_metadata)
|
113
|
-
end
|
114
|
-
|
115
|
-
# Enqueues a message on current queue. message is just a string that should be
|
116
|
-
# UTF-8 serializable and ttl specifies the time-to-live of the message in the queue
|
117
|
-
# (in seconds).
|
118
|
-
def enqueue!(message, ttl = 604800)
|
119
|
-
self.class.service_instance.enqueue(self.name, message, ttl)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Returns the approximated queue size.
|
123
|
-
def size
|
124
|
-
metadata[:x_ms_approximate_messages_count].to_i
|
125
|
-
end
|
126
|
-
|
127
|
-
# Since Windows Azure Queues implement a Peek-Lock pattern
|
128
|
-
# the method lock will lock a message preventing other users from
|
129
|
-
# picking/locking the current message from the queue.
|
130
|
-
#
|
131
|
-
# The API supports multiple message processing by specifiying num_of_messages (up to 32)
|
132
|
-
#
|
133
|
-
# The visibility_timeout parameter (optional) specifies for how long the message will be
|
134
|
-
# hidden from other users.
|
135
|
-
def lock(num_of_messages = 1, visibility_timeout = nil)
|
136
|
-
options = {}
|
137
|
-
options[:num_of_messages] = num_of_messages
|
138
|
-
options[:visiblity_timeout] = visibility_timeout unless visibility_timeout.nil?
|
139
|
-
messages = self.class.service_instance.get_messages(self.name, options).map do |raw_message|
|
140
|
-
WAZ::Queues::Message.new(raw_message.merge(:queue_name => self.name))
|
141
|
-
end
|
142
|
-
return messages.first() if num_of_messages == 1
|
143
|
-
return messages
|
144
|
-
end
|
145
|
-
|
146
|
-
# Returns top N (default 1, up to 32) message from the queue without performing
|
147
|
-
# any modification on the message. Since the message it's retrieved read-only
|
148
|
-
# users cannot delete the peeked message.
|
149
|
-
def peek(num_of_messages = 1)
|
150
|
-
options = {}
|
151
|
-
options[:num_of_messages] = num_of_messages
|
152
|
-
messages = self.class.service_instance.peek(self.name, options).map do |raw_message|
|
153
|
-
WAZ::Queues::Message.new(raw_message.merge(:queue_name => self.name))
|
154
|
-
end
|
155
|
-
return messages.first() if num_of_messages == 1
|
156
|
-
return messages
|
157
|
-
end
|
158
|
-
|
159
|
-
# Marks every message on the queue for deletion (to be later garbage collected).
|
160
|
-
def clear
|
161
|
-
self.class.service_instance.clear_queue(self.name)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Queues
|
3
|
+
# This class represents a Queue on Windows Azure Queues API. These are the methods implemented from Microsoft's API description
|
4
|
+
# available on MSDN at http://msdn.microsoft.com/en-us/library/dd179363.aspx
|
5
|
+
#
|
6
|
+
# # list available queues
|
7
|
+
# WAZ::Queues::Queue.list
|
8
|
+
#
|
9
|
+
# # create a queue (here you can also send hashed metadata)
|
10
|
+
# WAZ::Queues::Queue.create('test-queue')
|
11
|
+
#
|
12
|
+
# # get a specific queue
|
13
|
+
# queue = WAZ::Queues::Queue.find('test-queue')
|
14
|
+
#
|
15
|
+
# # get queue properties (including default headers)
|
16
|
+
# queue.metadata #=> hash containing beautified metadata (:x_ms_meta_name)
|
17
|
+
#
|
18
|
+
# # set queue properties (should follow x-ms-meta to be persisted)
|
19
|
+
# # if you specify the optional parameter overwrite, existing metadata
|
20
|
+
# # will be deleted else merged with new one.
|
21
|
+
# queue.put_properties!(:x_ms_meta_MyProperty => "my value")
|
22
|
+
#
|
23
|
+
# # delete queue
|
24
|
+
# queue.destroy!
|
25
|
+
#
|
26
|
+
# # clear queue contents
|
27
|
+
# queue.clear
|
28
|
+
#
|
29
|
+
# # enqueue a message
|
30
|
+
# queue.enqueue!("payload of the message")
|
31
|
+
#
|
32
|
+
# # peek a message/s (do not alter visibility, it can't be deleted neither)
|
33
|
+
# # num_of_messages (1 to 32) to be peeked (default 1)
|
34
|
+
# message = queue.peek
|
35
|
+
#
|
36
|
+
# # lock a message/s.
|
37
|
+
# # num_of_messages (1 to 32) to be peeked (default 1)
|
38
|
+
# # visiblity_timeout (default 60 sec. max 7200 [2hrs])
|
39
|
+
# message = queue.lock
|
40
|
+
#
|
41
|
+
class Queue
|
42
|
+
class << self
|
43
|
+
# Returns an array of the queues (WAZ::Queues::Queue) existing on the current
|
44
|
+
# Windows Azure Storage account.
|
45
|
+
#
|
46
|
+
# include_metadata defines if the metadata is retrieved along with queue data.
|
47
|
+
def list(include_metadata = false)
|
48
|
+
options = include_metadata ? { :include => 'metadata' } : {}
|
49
|
+
service_instance.list_queues(options).map do |queue|
|
50
|
+
WAZ::Queues::Queue.new(queue)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a queue on the current account. If provided the metadata hash will specify additional
|
55
|
+
# metadata to be stored on the queue. (Remember that metadata on the storage account must start with
|
56
|
+
# :x_ms_metadata_{yourCustomPropertyName}, if not it will not be persisted).
|
57
|
+
def create(queue_name, metadata = {})
|
58
|
+
raise WAZ::Storage::InvalidParameterValue, {:name => "name", :values => ["lower letters, numbers or - (hypen), and must not start or end with - (hyphen)"]} unless WAZ::Storage::ValidationRules.valid_name?(queue_name)
|
59
|
+
service_instance.create_queue(queue_name, metadata)
|
60
|
+
WAZ::Queues::Queue.new(:name => queue_name, :url => service_instance.generate_request_uri(queue_name))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Finds a queue by it's name, in case that it isn't found on the current storage account it will
|
64
|
+
# return nil shilding the user from a ResourceNotFound exception.
|
65
|
+
def find(queue_name)
|
66
|
+
begin
|
67
|
+
metadata = service_instance.get_queue_metadata(queue_name)
|
68
|
+
WAZ::Queues::Queue.new(:name => queue_name, :url => service_instance.generate_request_uri(queue_name), :metadata => metadata)
|
69
|
+
rescue RestClient::ResourceNotFound
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Syntax's sugar for find(:queue_name) or create(:queue_name)
|
75
|
+
def ensure(queue_name)
|
76
|
+
return (self.find(queue_name) or self.create(queue_name))
|
77
|
+
end
|
78
|
+
|
79
|
+
# This method is internally used by this class. It's the way we keep a single instance of the
|
80
|
+
# service that wraps the calls the Windows Azure Queues API. It's initialized with the values
|
81
|
+
# from the default_connection on WAZ::Storage::Base initialized thru establish_connection!
|
82
|
+
def service_instance
|
83
|
+
options = WAZ::Storage::Base.default_connection.merge(:type_of_service => "queue")
|
84
|
+
(@service_instances ||= {})[options[:account_name]] ||= Service.new(options)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
attr_accessor :name, :url, :metadata
|
89
|
+
|
90
|
+
def initialize(options = {})
|
91
|
+
raise WAZ::Storage::InvalidOption, :name unless options.keys.include?(:name)
|
92
|
+
raise WAZ::Storage::InvalidOption, :url unless options.keys.include?(:url)
|
93
|
+
self.name = options[:name]
|
94
|
+
self.url = options[:url]
|
95
|
+
self.metadata = options[:metadata]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Deletes the queue from the current storage account.
|
99
|
+
def destroy!
|
100
|
+
self.class.service_instance.delete_queue(self.name)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Retrieves the metadata headers associated with the quere.
|
104
|
+
def metadata
|
105
|
+
metadata ||= self.class.service_instance.get_queue_metadata(self.name)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Sets the metadata given on the new_metadata, when overwrite passed different
|
109
|
+
# than true it overrides the metadata for the queue (removing all existing metadata)
|
110
|
+
def put_properties!(new_metadata = {}, overwrite = false)
|
111
|
+
new_metadata.merge!(metadata.reject { |k, v| !k.to_s.start_with? "x_ms_meta"} ) unless overwrite
|
112
|
+
self.class.service_instance.set_queue_metadata(new_metadata)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Enqueues a message on current queue. message is just a string that should be
|
116
|
+
# UTF-8 serializable and ttl specifies the time-to-live of the message in the queue
|
117
|
+
# (in seconds).
|
118
|
+
def enqueue!(message, ttl = 604800)
|
119
|
+
self.class.service_instance.enqueue(self.name, message, ttl)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns the approximated queue size.
|
123
|
+
def size
|
124
|
+
metadata[:x_ms_approximate_messages_count].to_i
|
125
|
+
end
|
126
|
+
|
127
|
+
# Since Windows Azure Queues implement a Peek-Lock pattern
|
128
|
+
# the method lock will lock a message preventing other users from
|
129
|
+
# picking/locking the current message from the queue.
|
130
|
+
#
|
131
|
+
# The API supports multiple message processing by specifiying num_of_messages (up to 32)
|
132
|
+
#
|
133
|
+
# The visibility_timeout parameter (optional) specifies for how long the message will be
|
134
|
+
# hidden from other users.
|
135
|
+
def lock(num_of_messages = 1, visibility_timeout = nil)
|
136
|
+
options = {}
|
137
|
+
options[:num_of_messages] = num_of_messages
|
138
|
+
options[:visiblity_timeout] = visibility_timeout unless visibility_timeout.nil?
|
139
|
+
messages = self.class.service_instance.get_messages(self.name, options).map do |raw_message|
|
140
|
+
WAZ::Queues::Message.new(raw_message.merge(:queue_name => self.name))
|
141
|
+
end
|
142
|
+
return messages.first() if num_of_messages == 1
|
143
|
+
return messages
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns top N (default 1, up to 32) message from the queue without performing
|
147
|
+
# any modification on the message. Since the message it's retrieved read-only
|
148
|
+
# users cannot delete the peeked message.
|
149
|
+
def peek(num_of_messages = 1)
|
150
|
+
options = {}
|
151
|
+
options[:num_of_messages] = num_of_messages
|
152
|
+
messages = self.class.service_instance.peek(self.name, options).map do |raw_message|
|
153
|
+
WAZ::Queues::Message.new(raw_message.merge(:queue_name => self.name))
|
154
|
+
end
|
155
|
+
return messages.first() if num_of_messages == 1
|
156
|
+
return messages
|
157
|
+
end
|
158
|
+
|
159
|
+
# Marks every message on the queue for deletion (to be later garbage collected).
|
160
|
+
def clear
|
161
|
+
self.class.service_instance.clear_queue(self.name)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
165
|
end
|
data/lib/waz/queues/service.rb
CHANGED
@@ -1,106 +1,106 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Queues
|
3
|
-
# This is internally used by the waz-queues part of the gem and it exposes the Windows Azure Queue API REST methods
|
4
|
-
# implementation. You can use this class to perform an specific operation that aren't provided by the current API.
|
5
|
-
class Service
|
6
|
-
include WAZ::Storage::SharedKeyCoreService
|
7
|
-
|
8
|
-
# Lists the queues on the given storage account.
|
9
|
-
#
|
10
|
-
# When the options :include => 'metadata' is passed it returns
|
11
|
-
# the corresponding metadata for each queue on the listing.
|
12
|
-
def list_queues(options ={})
|
13
|
-
content = execute(:get, nil, { :comp => 'list' }.merge!(options), { :x_ms_version => "2011-08-18" })
|
14
|
-
doc = REXML::Document.new(content)
|
15
|
-
queues = []
|
16
|
-
|
17
|
-
REXML::XPath.each(doc, '//Queue/') do |item|
|
18
|
-
metadata = {}
|
19
|
-
|
20
|
-
item.elements['Metadata'].elements.each do |element|
|
21
|
-
metadata.merge!(element.name.gsub(/-/, '_').downcase.to_sym => element.text)
|
22
|
-
end unless item.elements['Metadata'].nil?
|
23
|
-
|
24
|
-
queues << { :name => REXML::XPath.first(item, "Name").text,
|
25
|
-
:url => REXML::XPath.first(item, "Url").text,
|
26
|
-
:metadata => metadata}
|
27
|
-
end
|
28
|
-
return queues
|
29
|
-
end
|
30
|
-
|
31
|
-
# Creates a queue on the current storage account. Throws WAZ::Queues::QueueAlreadyExists when
|
32
|
-
# existing metadata and given metadata differ.
|
33
|
-
def create_queue(queue_name, metadata = {})
|
34
|
-
execute(:put, queue_name, nil, metadata.merge!(:x_ms_version => '2011-08-18'))
|
35
|
-
end
|
36
|
-
|
37
|
-
# Deletes the given queue from the current storage account.
|
38
|
-
def delete_queue(queue_name)
|
39
|
-
execute(:delete, queue_name, {}, {:x_ms_version => '2011-08-18'})
|
40
|
-
end
|
41
|
-
|
42
|
-
# Gets the given queue metadata.
|
43
|
-
def get_queue_metadata(queue_name)
|
44
|
-
execute(:head, queue_name, { :comp => 'metadata'}, :x_ms_version => '2011-08-18').headers
|
45
|
-
end
|
46
|
-
|
47
|
-
# Sets the given queue metadata.
|
48
|
-
def set_queue_metadata(queue_name, metadata = {})
|
49
|
-
execute(:put, queue_name, { :comp => 'metadata' }, metadata.merge!(:x_ms_version => '2011-08-18'))
|
50
|
-
end
|
51
|
-
|
52
|
-
# Enqueues a message on the current queue.
|
53
|
-
#
|
54
|
-
# ttl Specifies the time-to-live interval for the message, in seconds. The maximum time-to-live allowed is 7 days. If this parameter
|
55
|
-
# is omitted, the default time-to-live is 7 days.
|
56
|
-
def enqueue(queue_name, message_payload, ttl = 604800)
|
57
|
-
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?><QueueMessage><MessageText>#{message_payload}</MessageText></QueueMessage>"
|
58
|
-
execute(:post, "#{queue_name}/messages", { :messagettl => ttl }, { 'Content-Type' => 'application/xml', :x_ms_version => "2011-08-18"}, payload)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Locks N messages (1 default) from the given queue.
|
62
|
-
#
|
63
|
-
# :num_of_messages option specifies the max number of messages to get (maximum 32)
|
64
|
-
#
|
65
|
-
# :visibility_timeout option specifies the timeout of the message locking in seconds (max two hours)
|
66
|
-
def get_messages(queue_name, options = {})
|
67
|
-
raise WAZ::Queues::OptionOutOfRange, {:name => :num_of_messages, :min => 1, :max => 32} if (options.keys.include?(:num_of_messages) && (options[:num_of_messages].to_i < 1 || options[:num_of_messages].to_i > 32))
|
68
|
-
raise WAZ::Queues::OptionOutOfRange, {:name => :visibility_timeout, :min => 1, :max => 7200} if (options.keys.include?(:visibility_timeout) && (options[:visibility_timeout].to_i < 1 || options[:visibility_timeout].to_i > 7200))
|
69
|
-
content = execute(:get, "#{queue_name}/messages", options, {:x_ms_version => "2011-08-18"})
|
70
|
-
doc = REXML::Document.new(content)
|
71
|
-
messages = []
|
72
|
-
REXML::XPath.each(doc, '//QueueMessage/') do |item|
|
73
|
-
message = { :message_id => REXML::XPath.first(item, "MessageId").text,
|
74
|
-
:message_text => REXML::XPath.first(item, "MessageText").text,
|
75
|
-
:dequeue_count => REXML::XPath.first(item, "DequeueCount").nil? ? nil : REXML::XPath.first(item, "DequeueCount").text.to_i,
|
76
|
-
:expiration_time => Time.httpdate(REXML::XPath.first(item, "ExpirationTime").text),
|
77
|
-
:insertion_time => Time.httpdate(REXML::XPath.first(item, "InsertionTime").text) }
|
78
|
-
|
79
|
-
# This are only valid when peek-locking messages
|
80
|
-
message[:pop_receipt] = REXML::XPath.first(item, "PopReceipt").text unless REXML::XPath.first(item, "PopReceipt").nil?
|
81
|
-
message[:time_next_visible] = Time.httpdate(REXML::XPath.first(item, "TimeNextVisible").text) unless REXML::XPath.first(item, "TimeNextVisible").nil?
|
82
|
-
messages << message
|
83
|
-
end
|
84
|
-
return messages
|
85
|
-
end
|
86
|
-
|
87
|
-
# Peeks N messages (default 1) from the given queue.
|
88
|
-
#
|
89
|
-
# Implementation is the same of get_messages but differs on an additional parameter called :peek_only.
|
90
|
-
def peek(queue_name, options = {})
|
91
|
-
return get_messages(queue_name, {:peek_only => true}.merge(options))
|
92
|
-
end
|
93
|
-
|
94
|
-
# Deletes the given message from the queue, correlating the operation with the pop_receipt
|
95
|
-
# in order to avoid eventually inconsistent scenarios.
|
96
|
-
def delete_message(queue_name, message_id, pop_receipt)
|
97
|
-
execute :delete, "#{queue_name}/messages/#{message_id}", { :pop_receipt => pop_receipt }
|
98
|
-
end
|
99
|
-
|
100
|
-
# Marks every message on the given queue for deletion.
|
101
|
-
def clear_queue(queue_name)
|
102
|
-
execute :delete, "#{queue_name}/messages", {}, :x_ms_version => '2011-08-18'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Queues
|
3
|
+
# This is internally used by the waz-queues part of the gem and it exposes the Windows Azure Queue API REST methods
|
4
|
+
# implementation. You can use this class to perform an specific operation that aren't provided by the current API.
|
5
|
+
class Service
|
6
|
+
include WAZ::Storage::SharedKeyCoreService
|
7
|
+
|
8
|
+
# Lists the queues on the given storage account.
|
9
|
+
#
|
10
|
+
# When the options :include => 'metadata' is passed it returns
|
11
|
+
# the corresponding metadata for each queue on the listing.
|
12
|
+
def list_queues(options ={})
|
13
|
+
content = execute(:get, nil, { :comp => 'list' }.merge!(options), { :x_ms_version => "2011-08-18" })
|
14
|
+
doc = REXML::Document.new(content)
|
15
|
+
queues = []
|
16
|
+
|
17
|
+
REXML::XPath.each(doc, '//Queue/') do |item|
|
18
|
+
metadata = {}
|
19
|
+
|
20
|
+
item.elements['Metadata'].elements.each do |element|
|
21
|
+
metadata.merge!(element.name.gsub(/-/, '_').downcase.to_sym => element.text)
|
22
|
+
end unless item.elements['Metadata'].nil?
|
23
|
+
|
24
|
+
queues << { :name => REXML::XPath.first(item, "Name").text,
|
25
|
+
:url => REXML::XPath.first(item, "Url").text,
|
26
|
+
:metadata => metadata}
|
27
|
+
end
|
28
|
+
return queues
|
29
|
+
end
|
30
|
+
|
31
|
+
# Creates a queue on the current storage account. Throws WAZ::Queues::QueueAlreadyExists when
|
32
|
+
# existing metadata and given metadata differ.
|
33
|
+
def create_queue(queue_name, metadata = {})
|
34
|
+
execute(:put, queue_name, nil, metadata.merge!(:x_ms_version => '2011-08-18'))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Deletes the given queue from the current storage account.
|
38
|
+
def delete_queue(queue_name)
|
39
|
+
execute(:delete, queue_name, {}, {:x_ms_version => '2011-08-18'})
|
40
|
+
end
|
41
|
+
|
42
|
+
# Gets the given queue metadata.
|
43
|
+
def get_queue_metadata(queue_name)
|
44
|
+
execute(:head, queue_name, { :comp => 'metadata'}, :x_ms_version => '2011-08-18').headers
|
45
|
+
end
|
46
|
+
|
47
|
+
# Sets the given queue metadata.
|
48
|
+
def set_queue_metadata(queue_name, metadata = {})
|
49
|
+
execute(:put, queue_name, { :comp => 'metadata' }, metadata.merge!(:x_ms_version => '2011-08-18'))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Enqueues a message on the current queue.
|
53
|
+
#
|
54
|
+
# ttl Specifies the time-to-live interval for the message, in seconds. The maximum time-to-live allowed is 7 days. If this parameter
|
55
|
+
# is omitted, the default time-to-live is 7 days.
|
56
|
+
def enqueue(queue_name, message_payload, ttl = 604800)
|
57
|
+
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?><QueueMessage><MessageText>#{message_payload}</MessageText></QueueMessage>"
|
58
|
+
execute(:post, "#{queue_name}/messages", { :messagettl => ttl }, { 'Content-Type' => 'application/xml', :x_ms_version => "2011-08-18"}, payload)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Locks N messages (1 default) from the given queue.
|
62
|
+
#
|
63
|
+
# :num_of_messages option specifies the max number of messages to get (maximum 32)
|
64
|
+
#
|
65
|
+
# :visibility_timeout option specifies the timeout of the message locking in seconds (max two hours)
|
66
|
+
def get_messages(queue_name, options = {})
|
67
|
+
raise WAZ::Queues::OptionOutOfRange, {:name => :num_of_messages, :min => 1, :max => 32} if (options.keys.include?(:num_of_messages) && (options[:num_of_messages].to_i < 1 || options[:num_of_messages].to_i > 32))
|
68
|
+
raise WAZ::Queues::OptionOutOfRange, {:name => :visibility_timeout, :min => 1, :max => 7200} if (options.keys.include?(:visibility_timeout) && (options[:visibility_timeout].to_i < 1 || options[:visibility_timeout].to_i > 7200))
|
69
|
+
content = execute(:get, "#{queue_name}/messages", options, {:x_ms_version => "2011-08-18"})
|
70
|
+
doc = REXML::Document.new(content)
|
71
|
+
messages = []
|
72
|
+
REXML::XPath.each(doc, '//QueueMessage/') do |item|
|
73
|
+
message = { :message_id => REXML::XPath.first(item, "MessageId").text,
|
74
|
+
:message_text => REXML::XPath.first(item, "MessageText").text,
|
75
|
+
:dequeue_count => REXML::XPath.first(item, "DequeueCount").nil? ? nil : REXML::XPath.first(item, "DequeueCount").text.to_i,
|
76
|
+
:expiration_time => Time.httpdate(REXML::XPath.first(item, "ExpirationTime").text),
|
77
|
+
:insertion_time => Time.httpdate(REXML::XPath.first(item, "InsertionTime").text) }
|
78
|
+
|
79
|
+
# This are only valid when peek-locking messages
|
80
|
+
message[:pop_receipt] = REXML::XPath.first(item, "PopReceipt").text unless REXML::XPath.first(item, "PopReceipt").nil?
|
81
|
+
message[:time_next_visible] = Time.httpdate(REXML::XPath.first(item, "TimeNextVisible").text) unless REXML::XPath.first(item, "TimeNextVisible").nil?
|
82
|
+
messages << message
|
83
|
+
end
|
84
|
+
return messages
|
85
|
+
end
|
86
|
+
|
87
|
+
# Peeks N messages (default 1) from the given queue.
|
88
|
+
#
|
89
|
+
# Implementation is the same of get_messages but differs on an additional parameter called :peek_only.
|
90
|
+
def peek(queue_name, options = {})
|
91
|
+
return get_messages(queue_name, {:peek_only => true}.merge(options))
|
92
|
+
end
|
93
|
+
|
94
|
+
# Deletes the given message from the queue, correlating the operation with the pop_receipt
|
95
|
+
# in order to avoid eventually inconsistent scenarios.
|
96
|
+
def delete_message(queue_name, message_id, pop_receipt)
|
97
|
+
execute :delete, "#{queue_name}/messages/#{message_id}", { :pop_receipt => pop_receipt }
|
98
|
+
end
|
99
|
+
|
100
|
+
# Marks every message on the given queue for deletion.
|
101
|
+
def clear_queue(queue_name)
|
102
|
+
execute :delete, "#{queue_name}/messages", {}, :x_ms_version => '2011-08-18'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
106
|
end
|