waz-storage 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ tests/waz/func/*.rb
2
+ coverage
3
+ pkg/*
4
+ rdoc/*
5
+ sdk/*
6
+ sdk
7
+ .rvmrc
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,72 @@
1
+ = Revision History for Windows Azure Storage for Ruby
2
+ === v1.1 - (smarx)
3
+ - Upload from stream, plus XML/URI escaping in various places, and a few other minor fixes
4
+ - Add upload method to container
5
+ - Add put_block_list to support upload
6
+ - Fix message canonicalization of ?comp= parameters for versions prior to 2009-09-19 (seems put_block was broken)
7
+ - Unescape query string parameters when constructing signatures (needed for put_block, since some base64-encoded names include non-URI-friendly characters)
8
+ - XML-escape property values for table entities (needed to insert things containing &, <, etc.)
9
+ - Remove Unicode characters from rakefile (was breaking something on Windows)
10
+ - Add tests for put_block_list and upload
11
+ - Fix tests for content type (typo, = instead of .should ==)
12
+ - Fix tests using RestClient.beautify_headers (expects an array, not a scalar)
13
+
14
+ === v1.0.6 - (hermes.logicalbricks)
15
+ - Update tests to rspec 2.5.0
16
+ - Allow authorization using only SharedAccessSignature
17
+
18
+ === v1.0.5 - (tomconte)
19
+ - Fixed for list_blobs as it wasn't fully merged to 2009-09-19. Now it works without 403 exceptions
20
+
21
+ === v1.0.3 - (Johnny Halife)
22
+ - Merged with sriramk fix for loading path issues on some environments
23
+
24
+ === v1.0.2 - (Johnny Halife)
25
+ - Completed Blobs API migration to 2009-09-19, _fully supporting_ what third-party tools does (e.g. Cerebrata) [thanks percent20]
26
+
27
+ === v1.0.1 - (Johnny halife)
28
+ - Added syntax's sugar for ensuring a queue (get or create)
29
+
30
+ === v1.0 - (Juan Pablo Garcia Dalolla)
31
+ - Added support for table service to query, get_one, insert, update, merge and delete entities.
32
+ - Added support for running against the Storage Developement Fabriq shipped with Microsoft SDK.
33
+ - Added signature support for Tables service according to msdn.microsoft.com/en-us/library/dd179428.aspx
34
+ - Added support to enumerate, create, and delete tables on give storage account.
35
+ - Improved support for stacked connection management.
36
+
37
+ === v0.5.81 - (Johnny Halife)
38
+ - When simulating a container using a forward slash starting the blob name it crashed with 404, now it's fixed.
39
+
40
+ === v0.5.8 - (Johnny Halife)
41
+ - Fixed an issue on the Queues Documentation (thanks @ezequielm)
42
+ - Added _naming validation for Containers_ according to http://msdn.microsoft.com/en-us/library/dd135715.aspx (thanks @panosjee)
43
+ - Added _naming validation for Queues_ according to http://msdn.microsoft.com/en-us/library/dd179349.aspx (thanks @panosjee)
44
+ - Added _support for Blob snapshots_
45
+ - Added support for rest-client 1.3.0. (thanks @jpgd)
46
+
47
+ === v0.5.7 - (Johnny Halife)
48
+ - Fixes a critical bug on URL management that some time prevents message from being deleted, caused by a missing encoding on the URL parameters.
49
+
50
+ === v0.5.6 - (Johnny Halife)
51
+ - Added signature support for 2009-09-19 Version of the Storage API
52
+ - Queues API has been migrated to the 2009-09-19 Version of the Storage API
53
+ - Added a new parameter for listing queues with metadata
54
+ - Added support for DequeueCount on messages being retrieved from the Queue
55
+ - <strong>Known Issue</strong>: Creating a queue multiple times with same metadata throws 409.
56
+
57
+ === v0.5.5 - (Johnny Halife)
58
+ - Added a Change Log
59
+ - Added support for copy-blob [WAZ::Blobs::BlobObject.copy("container/blob_name")]
60
+ - Refactored out the whole request logic to an _execute_ method on the SharedKeyCoreService
61
+ - Added transparent support for block management (users don't know if their blob is being uploaded chunked or not)
62
+ - Added support for a blob to list its blocks
63
+
64
+ === v0.5.4 - Sat Oct 17 19:35:48 2009 -0300 (Johnny Halife)
65
+ - Fixed method name for String.start_with? (previously starts_with?)
66
+
67
+ === v0.5.3 - Sat Oct 17 18:20:51 2009 -0300 (Johnny Halife)
68
+ - Added the stack-based contextual connection handling (WAZ::Storage::Base.establish_connection {|block| }
69
+ - Added string extensions for non rails environments (and work to work on heroku) String.starts_with?
70
+
71
+ === v0.5.2 - Thu Oct 15 22:08:01 2009 -0300 (Johnny Halife)
72
+ - Initial Version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in waz-storage.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ waz-storage (1.1.1)
5
+ rest-client
6
+ ruby-hmac
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.1.3)
12
+ metaclass (0.0.1)
13
+ mime-types (1.18)
14
+ mocha (0.10.5)
15
+ metaclass (~> 0.0.1)
16
+ rcov (1.0.0)
17
+ rest-client (1.6.7)
18
+ mime-types (>= 1.16)
19
+ rspec (2.9.0)
20
+ rspec-core (~> 2.9.0)
21
+ rspec-expectations (~> 2.9.0)
22
+ rspec-mocks (~> 2.9.0)
23
+ rspec-core (2.9.0)
24
+ rspec-expectations (2.9.1)
25
+ diff-lcs (~> 1.1.3)
26
+ rspec-mocks (2.9.0)
27
+ ruby-hmac (0.4.0)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ mocha
34
+ rcov
35
+ rspec
36
+ waz-storage!
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Johnny G. Halife
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,307 @@
1
+ = Why this fork ?
2
+
3
+ The main difference with the original library is the adding of the method "railsetag".
4
+ This method add to any blob object an "x_ms_meta_railsetag" header, its value is calculated as the rails etag way (Digest::MD5.hexdigest(file))
5
+
6
+ By doing so we can easily know if a locale copy of a file is up-to-date on Azure CDN.
7
+ This is very much used in the "waz-sync" gem which purpose is to sync file between local storage and Azure.
8
+
9
+ = Windows Azure Storage library — simple gem for accessing WAZ‘s Storage REST API
10
+ A simple implementation of Windows Azure Storage API for Ruby, inspired by the S3 gems and self experience of dealing with queues. The major
11
+ goal of the whole gem is to enable ruby developers [like me =)] to leverage Windows Azure Storage features and have another option
12
+ for cloud storage.
13
+
14
+ The whole gem is implemented based on Microsoft's specs from the communication and underlying service description and protocol (REST). The API
15
+ is for ruby developers built by a ruby developer. I'm trying to follow idioms, patterns and fluent type of doing APIs on Ruby.
16
+
17
+ This work isn't related at all with StorageClient Sample shipped with Microsoft SDK and written in .NET, the whole API is based on my own understanding,
18
+ experience and values of elegance and ruby development.
19
+
20
+ Full documentation for the gem is available at http://waz-storage.heroku.com
21
+
22
+ === How does this differ from <em>waz-queues</em> and <em>waz-blobs</em> work?
23
+ Well, this is a sum up of the whole experience of writing those gems and getting them to work together to simplify
24
+ end user experience. Although there're some breaking changes, it's pretty backward compatible with existing gems.
25
+
26
+ === What's new on the v1.1 version? [thanks to smarx]
27
+ - Upload from stream, plus XML/URI escaping in various places, and a few other minor fixes
28
+ - Add upload method to container
29
+ - Add put_block_list to support upload
30
+ - Fix message canonicalization of ?comp= parameters for versions prior to 2009-09-19 (seems put_block was broken)
31
+ - Unescape query string parameters when constructing signatures (needed for put_block, since some base64-encoded names include non-URI-friendly characters)
32
+ - XML-escape property values for table entities (needed to insert things containing &, <, etc.)
33
+ - Remove Unicode characters from rakefile (was breaking something on Windows)
34
+ - Add tests for put_block_list and upload
35
+ - Fix tests for content type (typo, = instead of .should ==)
36
+ - Fix tests using RestClient.beautify_headers (expects an array, not a scalar)
37
+
38
+ === What's new on the v1.0.6 version? [thanks to hermes.logicalbricks]
39
+ - Update tests to rspec 2.5.0
40
+ - Allow authorization using only SharedAccessSignature
41
+
42
+ === What's new on the version version?
43
+ - Fixed for list_blobs as it wasn't fully merged to 2009-09-19. Now it works without 403 exceptions [Thanks tomconte]
44
+
45
+ === What's new on the v1.0.3 version?
46
+ - Merged with sriramk fix for loading path issues on some environments
47
+
48
+ === What's new on the 1.0.2 version?
49
+ - Completed Blobs API migration to 2009-09-19, _fully supporting_ what third-party tools does (e.g. Cerebrata) [thanks percent20]
50
+
51
+ === What's new on the 1.0.1 version?
52
+ - Added Syntax's sugar for ensuring a Queue (get or create)
53
+
54
+ === What's new on the 1.0 version?
55
+ - Added support for table service to query, get_one, insert, update, merge and delete entities.
56
+ - Added support for running against the Storage Developement Fabriq shipped with Microsoft SDK.
57
+ - Added signature support for Tables service according to msdn.microsoft.com/en-us/library/dd179428.aspx
58
+ - Added support to enumerate, create, and delete tables on give storage account.
59
+ - Improved support for stacked connection management.
60
+
61
+ === What's new on the 0.5.81 version?
62
+ - When simulating a container using a forward slash starting the blob name it crashed with 404, now it's fixed.
63
+
64
+ === What's new on the 0.5.8 version?
65
+ - Fixed an issue on the Queues Documentation (thanks @ezequielm)
66
+ - Added <b>naming validation for Containers</b> according to http://msdn.microsoft.com/en-us/library/dd135715.aspx (thanks @panosjee)
67
+ - Added <b>naming validation for Queues</b> according to http://msdn.microsoft.com/en-us/library/dd179349.aspx (thanks @panosjee)
68
+ - Added <b>support for Blob snapshots</b>
69
+ - Added support for rest-client 1.3.0. (thanks @jpgd)
70
+
71
+ === What's new on the 0.5.7 version?
72
+ - Fixes a critical bug on URL management that some time prevents messages from being deleted, caused by a missing encoding on the URL parameters.
73
+
74
+ === What's new on the 0.5.6 version?
75
+ - Added new <b>shared key authentication support for 2009-09-19 Version of the Storage API</b>
76
+ - Queues API has been migrated to the <b>2009-09-19 Version of the Storage API</b>
77
+ - Added a new parameter for <b>listing queues with metadata</b>
78
+ - Added support for <b>DequeueCount</b> on messages being retrieved from the Queue
79
+ - <b>Known Issue</b>: Creating a queue multiple times with same metadata throws 409.
80
+
81
+ == Getting started
82
+ sudo gem install waz-storage --source http://gemcutter.org
83
+
84
+ == Basic Configuration
85
+ One of the major changes from the waz-queues and waz-blobs APIs was the ability to set a single storage account (99% of the cases) to be
86
+ used on your code just once. Since Windows Azure Storage Services are all related to a single account that includes Tables, Queues and Blobs,
87
+ I've changed the API in order to make ease that administration by requiring you to set the configuration just once:
88
+
89
+ require 'waz-queues' #=> if you want to use queues
90
+ require 'waz-blobs' #=> if you want to use blobs (or you can include both for using both)
91
+
92
+ WAZ::Storage::Base.establish_connection!(:account_name => account_name,
93
+ :access_key => access_key)
94
+
95
+ As you can see you, the way to get started it pretty simple, just include the establish_connection! call on your application bootstrapper, for example
96
+ if you are doing a sinatra-rb application it can be
97
+
98
+ configure :production do
99
+ # here is were you hook up with WAZ Storage Stuff.
100
+ end
101
+
102
+ That's all you need to get started and running your Windows Azure Code on a sinatra application.
103
+
104
+ == Usage: Queues
105
+ Windows Azure Queues are extremely powerful for asyc programming, they are very useful when you don’t need "always consistent"
106
+ data operations allowing you to enqueue and process on background. It’s important to mention that being WAZ-Queues a buffered
107
+ message system, you should design for idempotent operations given the fact that there’s no guarantee that a message can be repeated.
108
+
109
+ The implementation of the Windows Azure Queues REST API available online at http://msdn.microsoft.com/en-us/library/dd179363.aspx is fully
110
+ covered here.
111
+
112
+ Here's a quick getting started of the usage of the API:
113
+
114
+ WAZ::Storage::Base.establish_connection!(:account_name => account_name,
115
+ :access_key => access_key)
116
+
117
+ # NEW! Now you can do ensure and it will return the queue, first trying to retrieve it
118
+ # and then if it doesn't exist, will created it
119
+ queue = WAZ::Queues::Queue.ensure('my-queue')
120
+
121
+ # excepts that the metadata for the queue changes this method behaves as PUT (create/replace)
122
+ # remarks: it performs a validation whether metadata changed or not (if changed HTTP 409 conflict)
123
+ queue = WAZ::Queues::Queue.create('my-queue')
124
+
125
+ 10.times do |m|
126
+ # enqueue a receives string. Message content can be anything up to 8KB
127
+ # you can serialize and send anything that serializes to UTF-8 string (JSON, XML, etc)
128
+ queue.enqueue!("message##{m}")
129
+ end
130
+
131
+ while(queue.size > 0) do
132
+ # Since WAZ implements the peek lock pattern we are locking messages (not dequeuing)
133
+ # it has two parameters how many messages and for how long they are locked
134
+ messages = queue.lock(10)
135
+
136
+ puts "dequeued message: #{messages.size}"
137
+
138
+ # deletes the message from the queue so other clients do not pick it after
139
+ # visibility time out expires
140
+ messages.each {|m| m.destroy!}
141
+ end
142
+
143
+ It's pretty intuitive, but full documentation (RDoc) is available for the API for further reference.
144
+
145
+ == Usage: Blobs
146
+ The blobs implementation inside this gem is fully compliant with the spec available at http://msdn.microsoft.com/en-us/library/dd135733.aspx. The Windows
147
+ Azure Blobs REST API isn't fully covered here (see TODO's for more information). It's pretty usable and stable right now,
148
+ I've been doing lot of testing around and it works seamlessly with the current Windows Azure implementation.
149
+
150
+ require 'waz-blobs'
151
+
152
+ WAZ::Storage::Base.establish_connection!(:account_name => account_name,
153
+ :access_key => access_key)
154
+
155
+ # creates a container
156
+ container = WAZ::Blobs::Container.create('my-container')
157
+
158
+ # stores a blob with custom properties (metadata)
159
+ blob = container.store('my_blob.txt',
160
+ 'this is the content of my blob',
161
+ 'plain/text',
162
+ {:x_ms_meta_Custom_Property => "custom_value" })
163
+
164
+ # return a specific blob from a container
165
+ blob = container['my_blob.txt']
166
+
167
+ # retrieves a blob value
168
+ blob.value
169
+
170
+ It's pretty intuitive, but full documentation (RDoc) is available for the API for further reference.
171
+
172
+ === Using Blob with Shared Acess Signature
173
+ This feature allow to access a blob only with the information of the blob's name, the container, and the Shared Access Signature. If you don't have permission to perform an action (for example: list the blobs, create a new blob or something like that) you will receive an exception. If you want more details about this: http://msdn.microsoft.com/en-us/library/ee395415.aspx
174
+
175
+ require 'waz-blobs'
176
+
177
+ WAZ::Storage::Base.establish_connection!(:account_name=> 'mysharedblob',
178
+ :use_sas_auth_only=> true,
179
+ :sharedaccesssignature =>"?se=XXXXXX&sr=c&si=XXXXX&sig=XXXXXXXXXXXXXXXXXXXXX")
180
+
181
+ container = WAZ::Blobs::Container.new(:name=>'container')
182
+
183
+ blob = container.store('myfile.txt',File.read('fileofthecontent.txt'),'plain/text')
184
+
185
+ The feature was only tested storing a blob.
186
+
187
+ == Usage: Tables
188
+ The tables implementation inside this gem is fully compliant with the spec available at http://msdn.microsoft.com/en-us/library/dd179423.aspx. The Windows
189
+ Azure Tables REST API is fully covered here.
190
+
191
+ require 'waz-storage'
192
+ require 'waz-tables'
193
+
194
+ WAZ::Storage::Base.establish_connection!(:account_name => account_name,
195
+ :access_key => access_key)
196
+
197
+ # creates a new table
198
+ table = WAZ::Tables::Table.create('my-table')
199
+
200
+ # list available tables
201
+ # (returns a maximum of 1,000 items at one time (more details here: http://msdn.microsoft.com/en-us/library/dd135718.aspx)
202
+ tables = WAZ::Tables::Table.list
203
+
204
+ # more tables
205
+ WAZ::Tables::Table.list(tables.continuation_token)
206
+
207
+ # get a specific table, returning nil when the specified table is not found
208
+ my_table = WAZ::Tables::Table.find('my-table')
209
+
210
+ # table properties
211
+ my_table.name
212
+ my_table.url
213
+
214
+ # delete a table
215
+ my_table.destroy!
216
+
217
+ # Entity operations using the Table service
218
+
219
+ # get the existing service instance
220
+ service = WAZ::Tables::Table.service_instance
221
+
222
+ # define a new entity
223
+ entity = { :address => 'Mountain View',
224
+ :age => 23,
225
+ :amount_due => 200.23,
226
+ :binary_data => File.open(__FILE__),
227
+ :customer_code => 'aaaaaaaa-bbbb-cccc-dddd-aaaabbbbcccc',
228
+ :customer_since => Time.now.utc,
229
+ :is_active => true,
230
+ :num_of_orders => 255,
231
+ :partition_key => 'customer',
232
+ :row_key => "myRowKey#{rand(2000000).to_s}",
233
+ :Timestamp => Time.now.utc }
234
+
235
+ # inserts a new entity
236
+ service.insert_entity('customer_table', entity)
237
+
238
+ # retrieves all entities from a table
239
+ # (returns a maximum of 1,000 items at one time (more details here: http://msdn.microsoft.com/en-us/library/dd135718.aspx)
240
+ # Remarks on development storage it retrieves all items instead the first 1,000
241
+ entities = service.query('customer_table')
242
+
243
+ # retrieves more entities providing the obtained continuation_token
244
+ service.query('customer_table', {:continuation_token => entities.continuation_token} )
245
+
246
+ # retrieves all records that match with the specified query but only the first fifteen rows
247
+ service.query('customer_table', {:expression => "(PartitionKey eq 'customer') and (Age eq 23)", :top => 15} )
248
+
249
+ # get an existing entity by its partion_key and row_key
250
+ entity = service.get_entity('customer_table', 'customer', 'rowKey1')
251
+
252
+ # updates an entity
253
+ entity[:age] = 90
254
+ service.update_entity('customer_table', new_entity)
255
+
256
+ # merges an entity (more details here: http://msdn.microsoft.com/en-us/library/dd179392.aspx)
257
+ entity[:age] = 20
258
+ service.merge_entity('customer_table', new_entity)
259
+
260
+ # deletes an entity
261
+ service.delete_entity('customer_table', 'customer', 'rowKey1')
262
+
263
+ It's pretty intuitive, but full documentation (RDoc) is available for the API for further reference.
264
+
265
+ == Usage: Contextual Connection Handling
266
+ Sometimes while you are building a web application you may require handling different storage account but contextualized. The sample
267
+ that comes to my mind is something like a Storage Explorer or Account Monitor for WAZ.
268
+
269
+ That is why? I've added a new way of handling a stack-based contextual connection handling. The usage is pretty simple:
270
+
271
+ WAZ::Storage::Base.establish_connection(options) do
272
+ container = WAZ::Blobs::Container.find('container-name')
273
+ blob = container['blob-name']
274
+ blob.destroy!
275
+ end
276
+
277
+ As it is described on the example above, there's a new way of establishing a connection and use it on a given block. The whole implementation
278
+ is stack based, and will let you scope your context for some rare cases where you have another account.
279
+
280
+ *Disclaimer*: Moving objects across context isn't contemplated yet, and if you try to do changes among scopes you will get
281
+ to some wired Windows Azure Errors regarding objects that may not exist.
282
+
283
+ === Remarks
284
+ Windows Azure Storage API works flawlessly from Heroku and custom ruby hosting deployments on EC2, as far as I tested it. You can leverage the storage
285
+ services without the need of having to write the application on .NET or hosting your application on Windows Azure.
286
+
287
+ The documentation and implementation exposed here is for the pre-release version and is subject to change on the future.
288
+
289
+ === TODO's
290
+ As far as users start using it, I'll be building a backlog and probably handling a wish-list of features, but right now I've the following
291
+ TODO's already enqueued for further releases of the waz-storage API.
292
+
293
+ -Generate a sample application to better show the usage.
294
+
295
+ The things listed above do not represent any sort of priority, or the order they are going to be tackled. It's just a list.
296
+
297
+ == Meta
298
+
299
+ Written by Johnny G. Halife (johnny.halife at me dot com)
300
+
301
+ contributed by: Ezequiel Morito (http://twitter.com/ezequielm), Juan Pablo Garcia (http://twitter.com/jpgd), Steve Marx (http://twitter.com/smarx)
302
+
303
+ Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
304
+
305
+ http://waz-storage.heroku.com
306
+
307
+ http://github.com/johnnyhalife/waz-storage