Skip to content

Commit f6c57c6

Browse files
committed
Initial commit
0 parents  commit f6c57c6

39 files changed

+2638
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
doc
2+
coverage
3+
.yardoc
4+
Gemfile.lock

.yardopts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--title "Amazon DynamoDB Session Store"
2+
--exclude /generators/
3+
--hide-api private

Gemfile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
14+
source 'https://rubygems.org'
15+
16+
gemspec
17+
18+
gem 'rake', '~> 10.0'
19+
20+
group :documentation do
21+
gem 'yard', '~> 0.0'
22+
end
23+
24+
group :test do
25+
gem 'rspec', '~> 2.0'
26+
gem 'simplecov', '~> 0.0', :require => false
27+
gem 'rack-test', '~> 0.0'
28+
end

LICENSE.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"). You
4+
may not use this file except in compliance with the License. A copy of
5+
the License is located at
6+
7+
http://aws.amazon.com/apache2.0/
8+
9+
or in the "license" file accompanying this file. This file is
10+
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
ANY KIND, either express or implied. See the License for the specific
12+
language governing permissions and limitations under the License.

README.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Amazon DynamoDB Session Store
2+
3+
The **Amazon DynamoDB Session Store** handles sessions for Ruby web applications
4+
using a DynamoDB backend. The session store is compatible with Rails and other
5+
Rack based frameworks.
6+
7+
## Installation
8+
9+
#### Rails Installation
10+
11+
Install the session store gem by placing the following command into your
12+
Gemfile:
13+
14+
gem 'aws-dynamodb-sessionstore'
15+
16+
You will need to have an existing Amazon DynamoDB session table in order for the
17+
application to work. You can generate a migration file for the session table
18+
with the following command:
19+
20+
rails generate dynamo_db_session_handler
21+
22+
To create the table, run migrations as normal with:
23+
24+
rake db:migrate
25+
26+
Change the session store to `:dynamodb_store` by editing
27+
`config/initializers/session_store.rb` to contain the following:
28+
29+
YourAppName::Application.config.session_store :dynamodb_store
30+
31+
You can now start your Rails application with session support.
32+
33+
#### Basic Rack Application Installation
34+
35+
For non-Rails applications, you can create the Amazon DynamoDB table in a
36+
Ruby file using the following method:
37+
38+
require 'aws-dynamodb-sessionstore'
39+
40+
AWS::DynamoDB::SessionStore::Table.create_table
41+
42+
Run the session store as a Rack middleware in the following way:
43+
44+
require 'aws-dynamodb-sessionstore'
45+
require 'some_rack_app'
46+
47+
options = { :secret_key => 'SECRET_KEY' }
48+
49+
use AWS::DynamoDB::SessionStore::RackMiddleware.new(options)
50+
run SomeRackApp
51+
52+
Note that `:secret_key` is a mandatory configuration option that must be set.
53+
54+
## Detailed Usage
55+
56+
The session store is a Rack Middleware, meaning that it will implement the Rack
57+
interface for dealing with HTTP request/responses.
58+
59+
This session store uses a DynamoDB backend in order to provide scaling and
60+
centralized data benefits for session storage with more ease than other
61+
containers, like local servers or cookies. Once an application scales beyond
62+
a single web server, session data will need to be shared across the servers.
63+
DynamoDB takes care of this burden for you by scaling with your application.
64+
Cookie storage places all session data on the client side,
65+
discouraging sensitive data storage. It also forces strict data size
66+
limitations. DynamoDB takes care of these concerns by allowing for a safe and
67+
scalable storage container with a much larger data size limit for session data.
68+
69+
### Configuration Options
70+
71+
The following options are available to be set in
72+
`AWS::DynamoDB::SessionStore::Configuration`, which is used by the
73+
`RackMiddleware` class. These options can be set in the YAML configuration
74+
file in a Rails application, directly by Ruby code, or environment variables.
75+
76+
<table>
77+
<tbody>
78+
<tr class="odd">
79+
<th align="left"><p>Option Name</p></td>
80+
<th align="left"><p>Description</p></td>
81+
</tr>
82+
<tr class="even">
83+
<td><p>:table_name</p></td>
84+
<td><p>The session table name.</p></td>
85+
</tr>
86+
<tr class="odd">
87+
<td><p>:table_key</p></td>
88+
<td><p>The session table hash key name.</p></td>
89+
</tr>
90+
<tr class="odd">
91+
<td><p>:secret_key</p></td>
92+
<td><p>The secret key for HMAC encryption.</p></td>
93+
</tr>
94+
<tr class="even">
95+
<td><p>:consistent_read</p></td>
96+
<td><p>True/false depending on whether a strongly consistent read
97+
is desired.</p></td>
98+
</tr>
99+
<tr class="odd">
100+
<td><p>:read_capacity</p></td>
101+
<td><p>The maximum number of reads consumed per second before
102+
DynamoDB returns a ThrottlingException.</p></td>
103+
</tr>
104+
<tr class="even">
105+
<td><p>:write_capacity</p></td>
106+
<td><p>The maximum number of writes consumed per second before
107+
DynamoDB returns a ThrottlingException.</p></td>
108+
</tr>
109+
<tr class="odd">
110+
<td><p>:raise_errors</p></td>
111+
<td><p>True/false depending on whether all errors should be raised
112+
up the Rack stack. See documentation for details.</p></td>
113+
</tr>
114+
<tr class="even">
115+
<td><p>:dynamo_db_client</p></td>
116+
<td><p>The DynamoDB client used to perform DynamoDB calls.</p></td>
117+
</tr>
118+
<tr class="even">
119+
<td><p>:max_age</p></td>
120+
<td><p>Maximum age in seconds from the current time of
121+
a session.</p></td>
122+
</tr>
123+
<tr class="odd">
124+
<td><p>:max_stale</p></td>
125+
<td><p>Maximum time in seconds from the current time in which a
126+
session was last updated.</p></td>
127+
</tr>
128+
<tr class="even">
129+
<td><p>:error_handler</p></td>
130+
<td><p>Error handling object for raised errors.</p></td>
131+
</tr>
132+
<tr class="even">
133+
<td><p>:enable_locking</p></td>
134+
<td><p>True/false depending on whether a locking strategy should
135+
be implemented for session accesses.</p></td>
136+
</tr>
137+
<tr class="odd">
138+
<td><p>:lock_expiry_time</p></td>
139+
<td><p>The time in milleseconds after which the lock
140+
will expire.</p></td>
141+
</tr>
142+
<tr class="even">
143+
<td><p>:lock_retry_delay</p></td>
144+
<td><p>The time in milleseconds to wait before
145+
retrying to obtain a lock.</p></td>
146+
</tr>
147+
<tr class="odd">
148+
<td><p>:lock_max_wait_time</p></td>
149+
<td><p>Maximum time in seconds a request will wait to obtain
150+
the lock before throwing an exception.</p></td>
151+
</tr>
152+
<tr class="even">
153+
<td><p>:config_file</p></td>
154+
<td><p>File path to YAML configuration file</p></td>
155+
</tr>
156+
</tbody>
157+
</table>
158+
159+
#### Environment Options
160+
161+
Certain configuration options can be loaded from the environment. These
162+
options must be specified in the following format:
163+
164+
DYNAMO_DB_SESSION_NAME-OF-CONFIGURATION-OPTION
165+
166+
The example below would be a valid way to set the session table name:
167+
168+
export DYNAMO_DB_SESSION_TABLE_NAME='sessions'
169+
170+
### Rails Generator Details
171+
172+
The generator command specified in the installation section will generate two
173+
files: a migration file, `db/migration/VERSION_migration_name.rb`, and a
174+
configuration YAML file, `config/dynamo_db_session.yml`.
175+
176+
You can run the command with an argument that will define the name of the
177+
migration file. Once the YAML file is created, you can uncomment any of the
178+
lines to set configuration options to your liking. The session store will pull
179+
options from `config/dynamo_db_session.yml` by default if the file exists.
180+
If you do not wish to place the configuration YAML file in that location,
181+
you can also pass in a different file path to pull options from.
182+
183+
### Garbage Collection
184+
185+
You may want to delete old sessions from your session table. The
186+
following examples show how to clear old sessions from your table.
187+
188+
#### Rails
189+
190+
A Rake task for garbage collection is provided for Rails applications.
191+
By default sessions do not expire. See `config/dynamo_db_session.yml` to
192+
configure the max age or stale period of a session. Once you have configured
193+
those values you can clear the old sessions with:
194+
195+
rake dynamo_db:collect_garbage
196+
197+
#### Outside of Rails
198+
199+
You can create your own Rake task for garbage collection similar to below:
200+
201+
require "aws-dynamodb-sessionstore"
202+
203+
desc 'Perform Garbage Collection'
204+
task :garbage_collect do |t|
205+
options = {:max_age => 3600*24, max_stale => 5*3600 }
206+
AWS::DynamoDB::SessionStore::GarbageCollection.collect_garbage(options)
207+
end
208+
209+
The above example will clear sessions older than one day or that have been
210+
stale for longer than an hour.
211+
212+
### Locking Strategy
213+
214+
You may want the Session Store to implement the provided pessimistic locking
215+
strategy if you are concerned about concurrency issues with session accesses.
216+
By default, locking is not implemented for the session store. You must trigger
217+
the locking strategy through the configuration of the session store. Pessimistic
218+
locking, in this case, means that only one read can be made on a session at
219+
once. While the session is being read by the process with the lock, other
220+
processes may try to obtain a lock on the same session but will be blocked.
221+
222+
Locking is expensive and will drive up costs depending on how it is used.
223+
Without locking, one read and one write are performed per request for session
224+
data manipulation. If a locking strategy is implemented, as many as the total
225+
maximum wait time divided by the lock retry delay writes to the database.
226+
Keep these considerations in mind if you plan to enable locking.
227+
228+
#### Configuration for Locking
229+
230+
The following configuration options will allow you to configure the pessimistic
231+
locking strategy according to your needs:
232+
233+
options = {
234+
:enable_locking => true,
235+
:lock_expiry_time => 500,
236+
:lock_retry_delay => 500,
237+
:lock_max_wait_time => 1
238+
}
239+
240+
### Error Handling
241+
242+
You can pass in your own error handler for raised exceptions or you can allow
243+
the default error handler to them for you. See the API documentation
244+
on the {AWS::DynamoDB::SessionStore::Errors::BaseHandler} class for more
245+
details.

Rakefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
14+
Dir.glob(File.dirname(__FILE__) + '/tasks/*.rake').each {|file| load file }
15+
task :default => 'test:unit'

aws-dynamodb-sessionstore.gemspec

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# coding: utf-8
2+
lib = File.expand_path('../lib', __FILE__)
3+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4+
require 'aws/dynamo_db/session_store/version'
5+
6+
Gem::Specification.new do |spec|
7+
spec.name = "aws-dynamodb-sessionstore"
8+
spec.version = AWS::DynamoDB::SessionStore::VERSION
9+
spec.authors = ["Ruby Robinson"]
10+
spec.summary = "The Amazon DynamoDB Session Store handles sessions for Ruby web applications using a DynamoDB backend."
11+
spec.homepage = "http://github.com/aws/aws-dynamodb-sessionstore-ruby"
12+
spec.license = "Apache License 2.0"
13+
14+
spec.files = `git ls-files`.split($/)
15+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16+
spec.require_paths = ["lib"]
17+
18+
spec.add_dependency 'aws-sdk', '~> 1.0'
19+
spec.add_dependency 'rack', '~> 1.0'
20+
end

lib/aws-dynamodb-sessionstore.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
14+
15+
require 'aws/dynamo_db/session_store/configuration'
16+
require 'aws/dynamo_db/session_store/invalid_id_error'
17+
require 'aws/dynamo_db/session_store/missing_secret_key_error'
18+
require 'aws/dynamo_db/session_store/lock_wait_timeout_error'
19+
require 'aws/dynamo_db/session_store/errors/base_handler'
20+
require 'aws/dynamo_db/session_store/errors/default_handler'
21+
require 'aws/dynamo_db/session_store/garbage_collection'
22+
require 'aws/dynamo_db/session_store/locking/base'
23+
require 'aws/dynamo_db/session_store/locking/null'
24+
require 'aws/dynamo_db/session_store/locking/pessimistic'
25+
require 'aws/dynamo_db/session_store/rack_middleware'
26+
require 'aws/dynamo_db/session_store/table'
27+
require 'aws/dynamo_db/session_store/version'
28+
require 'aws/dynamo_db/session_store/railtie' if defined?(Rails)

0 commit comments

Comments
 (0)