waz-storage 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -9
- data/CHANGELOG.rdoc +72 -72
- data/Gemfile +4 -4
- data/Gemfile.lock +46 -46
- 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 -172
- data/lib/waz/blobs/exceptions.rb +10 -10
- data/lib/waz/blobs/service.rb +181 -181
- 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/core_service.rb +2 -1
- 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 +7 -7
- data/spec/configuration.rb +22 -22
- data/spec/waz/blobs/blob_object_spec.rb +80 -80
- data/spec/waz/blobs/container_spec.rb +175 -175
- data/spec/waz/blobs/service_spec.rb +336 -336
- data/spec/waz/queues/message_spec.rb +32 -32
- data/spec/waz/queues/queue_spec.rb +205 -205
- data/spec/waz/queues/service_spec.rb +298 -298
- data/spec/waz/storage/base_tests.rb +81 -81
- data/spec/waz/storage/shared_key_core_service_spec.rb +141 -141
- data/spec/waz/tables/service_spec.rb +613 -613
- data/spec/waz/tables/table_spec.rb +97 -97
- data/waz-storage.gemspec +29 -29
- metadata +3 -3
data/lib/waz/storage/base.rb
CHANGED
@@ -1,70 +1,70 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Storage
|
3
|
-
# This class is used to handle a general connection with Windows Azure Storage Account and it
|
4
|
-
# should be used at least once on the application bootstrap or configuration file.
|
5
|
-
#
|
6
|
-
# The usage is pretty simple as it's depicted on the following sample
|
7
|
-
# WAZ::Storage::establish_connection!(:account_name => "my_account_name",
|
8
|
-
# :access_key => "your_base64_key",
|
9
|
-
# :use_ssl => false)
|
10
|
-
#
|
11
|
-
class Base
|
12
|
-
class << self
|
13
|
-
# Sets the basic configuration parameters to use the API on the current context
|
14
|
-
# required parameters are :account_name, :access_key.
|
15
|
-
#
|
16
|
-
# All other parameters are optional.
|
17
|
-
def establish_connection!(options = {})
|
18
|
-
raise InvalidOption, :account_name unless options.keys.include? :account_name
|
19
|
-
raise InvalidOption, :access_key if !options.keys.include? :use_sas_auth_only unless options.keys.include? :access_key
|
20
|
-
raise InvalidOption, :use_sas_auth_only if !options.keys.include? :access_key unless options.keys.include? :use_sas_auth_only
|
21
|
-
raise InvalidOption, :sharedaccesssignature if !options.keys.include? :access_key unless options.keys.include? :sharedaccesssignature and options.keys.include? :use_sas_auth_only
|
22
|
-
options[:use_ssl] = false unless options.keys.include? :use_ssl
|
23
|
-
(@connections ||= []) << options
|
24
|
-
end
|
25
|
-
|
26
|
-
# Block Syntax
|
27
|
-
#
|
28
|
-
# Pushes the named repository onto the context-stack,
|
29
|
-
# yields a new session, and pops the context-stack.
|
30
|
-
#
|
31
|
-
# This helps you set contextual operations like in the following sample
|
32
|
-
#
|
33
|
-
# Base.establish_connection(options) do
|
34
|
-
# # do some operations on the given context
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# The context is restored to the previous one (what you configured on establish_connection!)
|
38
|
-
# or nil.
|
39
|
-
#
|
40
|
-
# Non-Block Syntax
|
41
|
-
#
|
42
|
-
# Behaves exactly as establish_connection!
|
43
|
-
def establish_connection(options = {}) # :yields: current_context
|
44
|
-
establish_connection!(options)
|
45
|
-
if (block_given?)
|
46
|
-
begin
|
47
|
-
return yield
|
48
|
-
ensure
|
49
|
-
@connections.pop() if connected?
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Returns the default connection (last set) parameters. It will raise an exception WAZ::Storage::NotConnected
|
55
|
-
# when there's no connection information registered.
|
56
|
-
def default_connection
|
57
|
-
raise NotConnected unless connected?
|
58
|
-
return @connections.last
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns a value indicating whether the current connection information has been set or not.
|
62
|
-
def connected?
|
63
|
-
return false if (@connections.nil?)
|
64
|
-
return false if (@connections.empty?)
|
65
|
-
return true
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Storage
|
3
|
+
# This class is used to handle a general connection with Windows Azure Storage Account and it
|
4
|
+
# should be used at least once on the application bootstrap or configuration file.
|
5
|
+
#
|
6
|
+
# The usage is pretty simple as it's depicted on the following sample
|
7
|
+
# WAZ::Storage::establish_connection!(:account_name => "my_account_name",
|
8
|
+
# :access_key => "your_base64_key",
|
9
|
+
# :use_ssl => false)
|
10
|
+
#
|
11
|
+
class Base
|
12
|
+
class << self
|
13
|
+
# Sets the basic configuration parameters to use the API on the current context
|
14
|
+
# required parameters are :account_name, :access_key.
|
15
|
+
#
|
16
|
+
# All other parameters are optional.
|
17
|
+
def establish_connection!(options = {})
|
18
|
+
raise InvalidOption, :account_name unless options.keys.include? :account_name
|
19
|
+
raise InvalidOption, :access_key if !options.keys.include? :use_sas_auth_only unless options.keys.include? :access_key
|
20
|
+
raise InvalidOption, :use_sas_auth_only if !options.keys.include? :access_key unless options.keys.include? :use_sas_auth_only
|
21
|
+
raise InvalidOption, :sharedaccesssignature if !options.keys.include? :access_key unless options.keys.include? :sharedaccesssignature and options.keys.include? :use_sas_auth_only
|
22
|
+
options[:use_ssl] = false unless options.keys.include? :use_ssl
|
23
|
+
(@connections ||= []) << options
|
24
|
+
end
|
25
|
+
|
26
|
+
# Block Syntax
|
27
|
+
#
|
28
|
+
# Pushes the named repository onto the context-stack,
|
29
|
+
# yields a new session, and pops the context-stack.
|
30
|
+
#
|
31
|
+
# This helps you set contextual operations like in the following sample
|
32
|
+
#
|
33
|
+
# Base.establish_connection(options) do
|
34
|
+
# # do some operations on the given context
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# The context is restored to the previous one (what you configured on establish_connection!)
|
38
|
+
# or nil.
|
39
|
+
#
|
40
|
+
# Non-Block Syntax
|
41
|
+
#
|
42
|
+
# Behaves exactly as establish_connection!
|
43
|
+
def establish_connection(options = {}) # :yields: current_context
|
44
|
+
establish_connection!(options)
|
45
|
+
if (block_given?)
|
46
|
+
begin
|
47
|
+
return yield
|
48
|
+
ensure
|
49
|
+
@connections.pop() if connected?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the default connection (last set) parameters. It will raise an exception WAZ::Storage::NotConnected
|
55
|
+
# when there's no connection information registered.
|
56
|
+
def default_connection
|
57
|
+
raise NotConnected unless connected?
|
58
|
+
return @connections.last
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a value indicating whether the current connection information has been set or not.
|
62
|
+
def connected?
|
63
|
+
return false if (@connections.nil?)
|
64
|
+
return false if (@connections.empty?)
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -113,7 +113,8 @@ module WAZ
|
|
113
113
|
# Generates a Windows Azure Storage call, it internally calls url generation method
|
114
114
|
# and the request generation message.
|
115
115
|
def execute(verb, path, query = {}, headers = {}, payload = nil)
|
116
|
-
|
116
|
+
escaped_path = path.split("/").map{ | part | CGI.escape(part) }.join("/")
|
117
|
+
url = generate_request_uri(escaped_path, query)
|
117
118
|
request = generate_request(verb, url, headers, payload)
|
118
119
|
request.execute()
|
119
120
|
end
|
@@ -1,33 +1,33 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Storage
|
3
|
-
# This class is the base exception from where all the exceptions raised from this API
|
4
|
-
# inherit from. If you want to handle an exception that your code may throw and you don't
|
5
|
-
# know which specific type you should handle, handle this type of exception.
|
6
|
-
class StorageException < StandardError
|
7
|
-
end
|
8
|
-
|
9
|
-
# This exception raises whenever a required parameter for initializing any class isn't provided. From
|
10
|
-
# WAZ::Storage::Base up to WAZ::Queues::Queue all of them use this exception.
|
11
|
-
class InvalidOption < StorageException
|
12
|
-
def initialize(missing_option)
|
13
|
-
super("You did not provide one of the required parameters. Please provide the #{missing_option}.")
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# This exception is raised when the user tries to perform an operation on any Storage API class
|
18
|
-
# without previously specificying the connection options.
|
19
|
-
class NotConnected < StorageException
|
20
|
-
def initialize
|
21
|
-
super("You should establish connection before using the services, the connection configuration is required.")
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# This exception if raised when the value given for an argument doesn't fall into the permitted values. For example
|
26
|
-
# if values on the blocklisttype aren't [all|uncommitted|committed]
|
27
|
-
class InvalidParameterValue < StorageException
|
28
|
-
def initialize(args = {})
|
29
|
-
super("The value supplied for the parameter #{args[:name]} is invalid. Permitted values are #{args[:values].join(',')}")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Storage
|
3
|
+
# This class is the base exception from where all the exceptions raised from this API
|
4
|
+
# inherit from. If you want to handle an exception that your code may throw and you don't
|
5
|
+
# know which specific type you should handle, handle this type of exception.
|
6
|
+
class StorageException < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
# This exception raises whenever a required parameter for initializing any class isn't provided. From
|
10
|
+
# WAZ::Storage::Base up to WAZ::Queues::Queue all of them use this exception.
|
11
|
+
class InvalidOption < StorageException
|
12
|
+
def initialize(missing_option)
|
13
|
+
super("You did not provide one of the required parameters. Please provide the #{missing_option}.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# This exception is raised when the user tries to perform an operation on any Storage API class
|
18
|
+
# without previously specificying the connection options.
|
19
|
+
class NotConnected < StorageException
|
20
|
+
def initialize
|
21
|
+
super("You should establish connection before using the services, the connection configuration is required.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# This exception if raised when the value given for an argument doesn't fall into the permitted values. For example
|
26
|
+
# if values on the blocklisttype aren't [all|uncommitted|committed]
|
27
|
+
class InvalidParameterValue < StorageException
|
28
|
+
def initialize(args = {})
|
29
|
+
super("The value supplied for the parameter #{args[:name]} is invalid. Permitted values are #{args[:values].join(',')}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Storage
|
3
|
-
class ValidationRules
|
4
|
-
class << self
|
5
|
-
# Validates that the Container/Queue name given matches with the requirements of Windows Azure.
|
6
|
-
#
|
7
|
-
# -Container/Queue names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character.
|
8
|
-
# -Every dash (-) character must be immediately preceded and followed by a letter or number.
|
9
|
-
# -All letters in a container name must be lowercase.
|
10
|
-
# -Container/Queue names must be from 3 through 63 characters long.
|
11
|
-
def valid_name?(name)
|
12
|
-
name =~ /^[a-z0-9][a-z0-9\-]{1,}[^-]$/ && name.length < 64
|
13
|
-
end
|
14
|
-
|
15
|
-
# Validates that the Table name given matches with the requirements of Windows Azure.
|
16
|
-
#
|
17
|
-
# -Table names must start with at least one lower / upper character.
|
18
|
-
# -Table names can have character or any digit starting from the second position.
|
19
|
-
# -Table names must be from 3 through 63 characters long.
|
20
|
-
def valid_table_name?(name)
|
21
|
-
name =~ /^([a-z]|[A-Z]){1}([a-z]|[A-Z]|\d){2,62}$/
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Storage
|
3
|
+
class ValidationRules
|
4
|
+
class << self
|
5
|
+
# Validates that the Container/Queue name given matches with the requirements of Windows Azure.
|
6
|
+
#
|
7
|
+
# -Container/Queue names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character.
|
8
|
+
# -Every dash (-) character must be immediately preceded and followed by a letter or number.
|
9
|
+
# -All letters in a container name must be lowercase.
|
10
|
+
# -Container/Queue names must be from 3 through 63 characters long.
|
11
|
+
def valid_name?(name)
|
12
|
+
name =~ /^[a-z0-9][a-z0-9\-]{1,}[^-]$/ && name.length < 64
|
13
|
+
end
|
14
|
+
|
15
|
+
# Validates that the Table name given matches with the requirements of Windows Azure.
|
16
|
+
#
|
17
|
+
# -Table names must start with at least one lower / upper character.
|
18
|
+
# -Table names can have character or any digit starting from the second position.
|
19
|
+
# -Table names must be from 3 through 63 characters long.
|
20
|
+
def valid_table_name?(name)
|
21
|
+
name =~ /^([a-z]|[A-Z]){1}([a-z]|[A-Z]|\d){2,62}$/
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
26
|
end
|
@@ -1,45 +1,45 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Tables
|
3
|
-
class EdmTypeHelper
|
4
|
-
class << self
|
5
|
-
def parse_from(item)
|
6
|
-
return nil if !item.attributes['m:null'].nil? and item.attributes['m:null'] == 'true'
|
7
|
-
case item.attributes['m:type']
|
8
|
-
when 'Edm.Int16', 'Edm.Int32', 'Edm.Int64'
|
9
|
-
item.text.to_i
|
10
|
-
when 'Edm.Single', 'Edm.Double'
|
11
|
-
item.text.to_f
|
12
|
-
when 'Edm.Boolean'
|
13
|
-
item.text == 'true'
|
14
|
-
when 'Edm.DateTime'
|
15
|
-
Time.parse(item.text)
|
16
|
-
when 'Edm.Binary'
|
17
|
-
StringIO.new(Base64.decode64(item.text))
|
18
|
-
else
|
19
|
-
item.text
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def parse_to(item)
|
24
|
-
case item.class.name
|
25
|
-
when 'String'
|
26
|
-
[item, 'Edm.String']
|
27
|
-
when 'Fixnum'
|
28
|
-
[item, 'Edm.Int32']
|
29
|
-
when 'Float'
|
30
|
-
[item, 'Edm.Double']
|
31
|
-
when 'TrueClass', 'FalseClass'
|
32
|
-
[item, 'Edm.Boolean']
|
33
|
-
when 'Time'
|
34
|
-
[item.iso8601, 'Edm.DateTime']
|
35
|
-
when 'File', 'StringIO'
|
36
|
-
item.pos = 0
|
37
|
-
[Base64.encode64(item.read), 'Edm.Binary']
|
38
|
-
else
|
39
|
-
[item, 'Edm.String']
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Tables
|
3
|
+
class EdmTypeHelper
|
4
|
+
class << self
|
5
|
+
def parse_from(item)
|
6
|
+
return nil if !item.attributes['m:null'].nil? and item.attributes['m:null'] == 'true'
|
7
|
+
case item.attributes['m:type']
|
8
|
+
when 'Edm.Int16', 'Edm.Int32', 'Edm.Int64'
|
9
|
+
item.text.to_i
|
10
|
+
when 'Edm.Single', 'Edm.Double'
|
11
|
+
item.text.to_f
|
12
|
+
when 'Edm.Boolean'
|
13
|
+
item.text == 'true'
|
14
|
+
when 'Edm.DateTime'
|
15
|
+
Time.parse(item.text)
|
16
|
+
when 'Edm.Binary'
|
17
|
+
StringIO.new(Base64.decode64(item.text))
|
18
|
+
else
|
19
|
+
item.text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_to(item)
|
24
|
+
case item.class.name
|
25
|
+
when 'String'
|
26
|
+
[item, 'Edm.String']
|
27
|
+
when 'Fixnum'
|
28
|
+
[item, 'Edm.Int32']
|
29
|
+
when 'Float'
|
30
|
+
[item, 'Edm.Double']
|
31
|
+
when 'TrueClass', 'FalseClass'
|
32
|
+
[item, 'Edm.Boolean']
|
33
|
+
when 'Time'
|
34
|
+
[item.iso8601, 'Edm.DateTime']
|
35
|
+
when 'File', 'StringIO'
|
36
|
+
item.pos = 0
|
37
|
+
[Base64.encode64(item.read), 'Edm.Binary']
|
38
|
+
else
|
39
|
+
[item, 'Edm.String']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
45
|
end
|
@@ -1,45 +1,45 @@
|
|
1
|
-
module WAZ
|
2
|
-
module Tables
|
3
|
-
# This exception is raised while trying to create table that already exists.
|
4
|
-
class TableAlreadyExists < WAZ::Storage::StorageException
|
5
|
-
def initialize(name)
|
6
|
-
super("The table #{name} already exists on your account.")
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
# This exception is raised while trying to delete an unexisting table.
|
11
|
-
class TableDoesNotExist < WAZ::Storage::StorageException
|
12
|
-
def initialize(name)
|
13
|
-
super("The specified table #{name} does not exist.")
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# This exception is raised when an invalid table name is provided.
|
18
|
-
class InvalidTableName < WAZ::Storage::StorageException
|
19
|
-
def initialize(name)
|
20
|
-
super("The table name #{name} is invalid, it must start with at least one lower/upper characted, must be from 3 through 63 characters long and can have character or any digit starting from the second position")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# This exception is raised when provided more than the 252 properties allowed by the Rest API.
|
25
|
-
class TooManyProperties < WAZ::Storage::StorageException
|
26
|
-
def initialize(total)
|
27
|
-
super("The entity contains more properties than allowed (252). The entity has #{total} properties.")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# This exception is raised when the specified entity already exists.
|
32
|
-
class EntityAlreadyExists < WAZ::Storage::StorageException
|
33
|
-
def initialize(row_key)
|
34
|
-
super("The specified entity already exists. RowKey: #{row_key}")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# This exception is raised while trying to delete an unexisting entity.
|
39
|
-
class EntityDoesNotExist < WAZ::Storage::StorageException
|
40
|
-
def initialize(key)
|
41
|
-
super("The specified entity with #{key} does not exist.")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
1
|
+
module WAZ
|
2
|
+
module Tables
|
3
|
+
# This exception is raised while trying to create table that already exists.
|
4
|
+
class TableAlreadyExists < WAZ::Storage::StorageException
|
5
|
+
def initialize(name)
|
6
|
+
super("The table #{name} already exists on your account.")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# This exception is raised while trying to delete an unexisting table.
|
11
|
+
class TableDoesNotExist < WAZ::Storage::StorageException
|
12
|
+
def initialize(name)
|
13
|
+
super("The specified table #{name} does not exist.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# This exception is raised when an invalid table name is provided.
|
18
|
+
class InvalidTableName < WAZ::Storage::StorageException
|
19
|
+
def initialize(name)
|
20
|
+
super("The table name #{name} is invalid, it must start with at least one lower/upper characted, must be from 3 through 63 characters long and can have character or any digit starting from the second position")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# This exception is raised when provided more than the 252 properties allowed by the Rest API.
|
25
|
+
class TooManyProperties < WAZ::Storage::StorageException
|
26
|
+
def initialize(total)
|
27
|
+
super("The entity contains more properties than allowed (252). The entity has #{total} properties.")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# This exception is raised when the specified entity already exists.
|
32
|
+
class EntityAlreadyExists < WAZ::Storage::StorageException
|
33
|
+
def initialize(row_key)
|
34
|
+
super("The specified entity already exists. RowKey: #{row_key}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# This exception is raised while trying to delete an unexisting entity.
|
39
|
+
class EntityDoesNotExist < WAZ::Storage::StorageException
|
40
|
+
def initialize(key)
|
41
|
+
super("The specified entity with #{key} does not exist.")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
45
|
end
|