waz-storage 1.1.1 → 1.1.2

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 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