aws-sessionstore-dynamodb 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.yardopts +3 -0
- data/Gemfile +28 -0
- data/LICENSE.txt +12 -0
- data/README.md +171 -0
- data/Rakefile +15 -0
- data/aws-sessionstore-dynamodb.gemspec +18 -0
- data/lib/aws-sessionstore-dynamodb.rb +34 -0
- data/lib/aws/session_store/dynamo_db/configuration.rb +298 -0
- data/lib/aws/session_store/dynamo_db/errors/base_handler.rb +45 -0
- data/lib/aws/session_store/dynamo_db/errors/default_handler.rb +57 -0
- data/lib/aws/session_store/dynamo_db/garbage_collection.rb +128 -0
- data/lib/aws/session_store/dynamo_db/invalid_id_error.rb +21 -0
- data/lib/aws/session_store/dynamo_db/lock_wait_timeout_error.rb +21 -0
- data/lib/aws/session_store/dynamo_db/locking/base.rb +162 -0
- data/lib/aws/session_store/dynamo_db/locking/null.rb +40 -0
- data/lib/aws/session_store/dynamo_db/locking/pessimistic.rb +160 -0
- data/lib/aws/session_store/dynamo_db/missing_secret_key_error.rb +21 -0
- data/lib/aws/session_store/dynamo_db/rack_middleware.rb +130 -0
- data/lib/aws/session_store/dynamo_db/railtie.rb +28 -0
- data/lib/aws/session_store/dynamo_db/table.rb +98 -0
- data/lib/aws/session_store/dynamo_db/tasks/session_table.rake +21 -0
- data/lib/aws/session_store/dynamo_db/version.rb +21 -0
- data/lib/rails/generators/sessionstore/dynamodb/dynamodb_generator.rb +55 -0
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/USAGE +13 -0
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/dynamodb.yml +71 -0
- data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore_migration.rb +10 -0
- data/spec/aws/session_store/dynamo_db/app_config.yml +19 -0
- data/spec/aws/session_store/dynamo_db/config/dynamo_db_session.yml +24 -0
- data/spec/aws/session_store/dynamo_db/configuration_spec.rb +101 -0
- data/spec/aws/session_store/dynamo_db/error/default_error_handler_spec.rb +62 -0
- data/spec/aws/session_store/dynamo_db/garbage_collection_spec.rb +156 -0
- data/spec/aws/session_store/dynamo_db/locking/threaded_sessions_spec.rb +95 -0
- data/spec/aws/session_store/dynamo_db/rack_middleware_database_spec.rb +129 -0
- data/spec/aws/session_store/dynamo_db/rack_middleware_spec.rb +149 -0
- data/spec/aws/session_store/dynamo_db/rails_app_config.yml +24 -0
- data/spec/aws/session_store/dynamo_db/table_spec.rb +46 -0
- data/spec/spec_helper.rb +61 -0
- data/tasks/test.rake +29 -0
- metadata +123 -0
@@ -0,0 +1,45 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB::Errors
|
16
|
+
# BaseErrorHandler provides an interface for error handlers
|
17
|
+
# that can be passed in to {AWS::SessionStore::DynamoDB::RackMiddleware}.
|
18
|
+
# Each error handler must implement a handle_error method.
|
19
|
+
#
|
20
|
+
# @example Sample ErrorHandler class
|
21
|
+
# class MyErrorHandler < BaseErrorHandler
|
22
|
+
# # Handles error passed in
|
23
|
+
# def handle_error(e, env = {})
|
24
|
+
# File.open(path_to_file, 'w') {|f| f.write(e.message) }
|
25
|
+
# false
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
class BaseHandler
|
29
|
+
# An error and an environment (optionally) will be passed in to
|
30
|
+
# this method and it will determine how to deal
|
31
|
+
# with the error.
|
32
|
+
# Must return false if you have handled the error but are not reraising the
|
33
|
+
# error up the stack.
|
34
|
+
# You may reraise the error passed.
|
35
|
+
#
|
36
|
+
# @param [AWS::DynamoDB::Errors::Base] error error passed in from
|
37
|
+
# AWS::SessionStore::DynamoDB::RackMiddleware.
|
38
|
+
# @param [Rack::Request::Environment,nil] env Rack environment
|
39
|
+
# @return [false] If exception was handled and will not reraise exception.
|
40
|
+
# @raise [AWS::DynamoDB::Errors] If error has be reraised.
|
41
|
+
def handle_error(error, env = {})
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB::Errors
|
16
|
+
# This class handles errors raised from DynamoDB.
|
17
|
+
class DefaultHandler < AWS::SessionStore::DynamoDB::Errors::BaseHandler
|
18
|
+
# Array of errors that will always be passed up the Rack stack.
|
19
|
+
HARD_ERRORS = [
|
20
|
+
AWS::DynamoDB::Errors::ResourceNotFoundException,
|
21
|
+
AWS::DynamoDB::Errors::ConditionalCheckFailedException,
|
22
|
+
AWS::SessionStore::DynamoDB::MissingSecretKeyError,
|
23
|
+
AWS::SessionStore::DynamoDB::LockWaitTimeoutError
|
24
|
+
]
|
25
|
+
|
26
|
+
# Determines behavior of DefaultErrorHandler
|
27
|
+
# @param [true] raise_errors Pass all errors up the Rack stack.
|
28
|
+
def initialize(raise_errors)
|
29
|
+
@raise_errors = raise_errors
|
30
|
+
end
|
31
|
+
|
32
|
+
# Raises {HARD_ERRORS} up the Rack stack.
|
33
|
+
# Places all other errors in Racks error stream.
|
34
|
+
def handle_error(error, env = {})
|
35
|
+
if HARD_ERRORS.include?(error.class) || @raise_errors
|
36
|
+
raise error
|
37
|
+
else
|
38
|
+
store_error(error, env)
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Sends error to error stream
|
44
|
+
def store_error(error, env = {})
|
45
|
+
env["rack.errors"].puts(errors_string(error)) if env
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns string to be placed in error stream
|
49
|
+
def errors_string(error)
|
50
|
+
str = []
|
51
|
+
str << "Exception occurred: #{error.message}"
|
52
|
+
str << "Stack trace:"
|
53
|
+
str += error.backtrace.map {|l| " " + l }
|
54
|
+
str.join("\n")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,128 @@
|
|
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
|
+
require 'aws-sdk'
|
15
|
+
|
16
|
+
module AWS::SessionStore::DynamoDB
|
17
|
+
# Collects and deletes unwanted sessions based on
|
18
|
+
# their creation and update dates.
|
19
|
+
module GarbageCollection
|
20
|
+
module_function
|
21
|
+
|
22
|
+
# Scans DynamoDB session table to find
|
23
|
+
# sessions that match the max age and max stale period
|
24
|
+
# requirements. it then deletes all of the found sessions.
|
25
|
+
def collect_garbage(options = {})
|
26
|
+
config = load_config(options)
|
27
|
+
last_key = eliminate_unwanted_sessions(config)
|
28
|
+
while !last_key.empty?
|
29
|
+
last_key = eliminate_unwanted_sessions(config, last_key)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Loads configuration options.
|
34
|
+
# @option (see Configuration#initialize)
|
35
|
+
# @api private
|
36
|
+
def load_config(options = {})
|
37
|
+
AWS::SessionStore::DynamoDB::Configuration.new(options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets scan filter attributes based on attributes specified.
|
41
|
+
# @api private
|
42
|
+
def scan_filter(config)
|
43
|
+
hash = {}
|
44
|
+
hash['created_at'] = oldest_date(config.max_age) if config.max_age
|
45
|
+
hash['updated_at'] = oldest_date(config.max_stale) if config.max_stale
|
46
|
+
{ :scan_filter => hash }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Scans and deletes batch.
|
50
|
+
# @api private
|
51
|
+
def eliminate_unwanted_sessions(config, last_key = nil)
|
52
|
+
scan_result = scan(config, last_key)
|
53
|
+
batch_delete(config, scan_result[:member])
|
54
|
+
scan_result[:last_evaluated_key] || {}
|
55
|
+
end
|
56
|
+
|
57
|
+
# Scans the table for sessions matching the max age and
|
58
|
+
# max stale time specified.
|
59
|
+
# @api private
|
60
|
+
def scan(config, last_item = nil)
|
61
|
+
options = scan_opts(config)
|
62
|
+
options.merge(start_key(last_item)) if last_item
|
63
|
+
config.dynamo_db_client.scan(options)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Deletes the batch gotten from the scan result.
|
67
|
+
# @api private
|
68
|
+
def batch_delete(config, items)
|
69
|
+
begin
|
70
|
+
subset = items.shift(25)
|
71
|
+
sub_batch = write(subset)
|
72
|
+
process!(config, sub_batch)
|
73
|
+
end until subset.empty?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Turns array into correct format to be passed in to
|
77
|
+
# a delete request.
|
78
|
+
# @api private
|
79
|
+
def write(sub_batch)
|
80
|
+
sub_batch.inject([]) do |rqst_array, item|
|
81
|
+
rqst_array << {:delete_request => {:key => item}}
|
82
|
+
rqst_array
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Proccesses pending request items.
|
87
|
+
# @api private
|
88
|
+
def process!(config, sub_batch)
|
89
|
+
return if sub_batch.empty?
|
90
|
+
opts = {}
|
91
|
+
opts[:request_items] = {config.table_name => sub_batch}
|
92
|
+
begin
|
93
|
+
response = config.dynamo_db_client.batch_write_item(opts)
|
94
|
+
opts[:request_items] = response[:unprocessed_items]
|
95
|
+
end until opts[:request_items].empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
# Provides scan options.
|
99
|
+
# @api private
|
100
|
+
def scan_opts(config)
|
101
|
+
table_opts(config).merge(scan_filter(config))
|
102
|
+
end
|
103
|
+
|
104
|
+
# Provides table options
|
105
|
+
# @api private
|
106
|
+
def table_opts(config)
|
107
|
+
{
|
108
|
+
:table_name => config.table_name,
|
109
|
+
:attributes_to_get => [config.table_key]
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [Hash] Hash with specified date attributes.
|
114
|
+
# @api private
|
115
|
+
def oldest_date(sec)
|
116
|
+
hash = {}
|
117
|
+
hash[:attribute_value_list] = [:n => "#{((Time.now - sec).to_f)}"]
|
118
|
+
hash[:comparison_operator] = 'LT'
|
119
|
+
hash
|
120
|
+
end
|
121
|
+
|
122
|
+
# Provides start key.
|
123
|
+
# @api private
|
124
|
+
def start_key(last_item)
|
125
|
+
{ :exclusive_start_key => last_item }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,21 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB
|
16
|
+
class InvalidIDError < RuntimeError
|
17
|
+
def initialize(msg = "Corrupt Session ID!")
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB
|
16
|
+
class LockWaitTimeoutError < RuntimeError
|
17
|
+
def initialize(msg = 'Maximum time spent to acquire lock has been exceeded!')
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,162 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB::Locking
|
16
|
+
# This class provides a framework for implementing
|
17
|
+
# locking strategies.
|
18
|
+
class Base
|
19
|
+
|
20
|
+
# Creates configuration object.
|
21
|
+
def initialize(cfg)
|
22
|
+
@config = cfg
|
23
|
+
end
|
24
|
+
|
25
|
+
# Updates session in database
|
26
|
+
def set_session_data(env, sid, session, options = {})
|
27
|
+
return false if session.empty?
|
28
|
+
packed_session = pack_data(session)
|
29
|
+
handle_error(env) do
|
30
|
+
save_opts = update_opts(env, sid, packed_session, options)
|
31
|
+
result = @config.dynamo_db_client.update_item(save_opts)
|
32
|
+
sid
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Packs session data.
|
37
|
+
def pack_data(data)
|
38
|
+
[Marshal.dump(data)].pack("m*")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Gets session data.
|
42
|
+
def get_session_data(env, sid)
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes session based on id
|
47
|
+
def delete_session(env, sid)
|
48
|
+
handle_error(env) do
|
49
|
+
@config.dynamo_db_client.delete_item(delete_opts(sid))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Each database operation is placed in this rescue wrapper.
|
54
|
+
# This wrapper will call the method, rescue any exceptions and then pass
|
55
|
+
# exceptions to the configured error handler.
|
56
|
+
def handle_error(env = nil, &block)
|
57
|
+
begin
|
58
|
+
yield
|
59
|
+
rescue AWS::DynamoDB::Errors::Base => e
|
60
|
+
@config.error_handler.handle_error(e, env)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# @return [Hash] Options for deleting session.
|
67
|
+
def delete_opts(sid)
|
68
|
+
merge_all(table_opts(sid), expected_attributes(sid))
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Hash] Options for updating item in Session table.
|
72
|
+
def update_opts(env, sid, session, options = {})
|
73
|
+
if env['dynamo_db.new_session']
|
74
|
+
updt_options = save_new_opts(env, sid, session)
|
75
|
+
else
|
76
|
+
updt_options = save_exists_opts(env, sid, session, options)
|
77
|
+
end
|
78
|
+
updt_options
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Hash] Options for saving a new session in database.
|
82
|
+
def save_new_opts(env, sid, session)
|
83
|
+
attribute_opts = attr_updts(env, session, created_attr)
|
84
|
+
merge_all(table_opts(sid), attribute_opts)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Hash] Options for saving an existing sesison in the database.
|
88
|
+
def save_exists_opts(env, sid, session, options = {})
|
89
|
+
add_attr = options[:add_attrs] || {}
|
90
|
+
expected = options[:expect_attr] || {}
|
91
|
+
attribute_opts = merge_all(attr_updts(env, session, add_attr), expected)
|
92
|
+
merge_all(table_opts(sid), attribute_opts)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Unmarshal the data.
|
96
|
+
def unpack_data(packed_data)
|
97
|
+
Marshal.load(packed_data.unpack("m*").first)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Table options for client.
|
101
|
+
def table_opts(sid)
|
102
|
+
{
|
103
|
+
:table_name => @config.table_name,
|
104
|
+
:key => {@config.table_key => {:s => sid}}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
# Attributes to update via client.
|
109
|
+
def attr_updts(env, session, add_attrs = {})
|
110
|
+
data = data_unchanged?(env, session) ? {} : data_attr(session)
|
111
|
+
{
|
112
|
+
:attribute_updates => merge_all(updated_attr, data, add_attrs),
|
113
|
+
:return_values => "UPDATED_NEW"
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
# Update client with current time attribute.
|
118
|
+
def updated_at
|
119
|
+
{ :value => {:n => "#{(Time.now).to_f}"}, :action => "PUT" }
|
120
|
+
end
|
121
|
+
|
122
|
+
# Attribute for creation of session.
|
123
|
+
def created_attr
|
124
|
+
{ "created_at" => updated_at }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Attribute for updating session.
|
128
|
+
def updated_attr
|
129
|
+
{
|
130
|
+
"updated_at" => updated_at
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def data_attr(session)
|
135
|
+
{ "data" => {:value => {:s => session}, :action => "PUT"} }
|
136
|
+
end
|
137
|
+
|
138
|
+
# Determine if data has been manipulated
|
139
|
+
def data_unchanged?(env, session)
|
140
|
+
return false unless env['rack.initial_data']
|
141
|
+
env['rack.initial_data'] == session
|
142
|
+
end
|
143
|
+
|
144
|
+
# Expected attributes
|
145
|
+
def expected_attributes(sid)
|
146
|
+
{ :expected => {@config.table_key => {:value => {:s => sid}, :exists => true}} }
|
147
|
+
end
|
148
|
+
|
149
|
+
# Attributes to be retrieved via client
|
150
|
+
def attr_opts
|
151
|
+
{:attributes_to_get => ["data"],
|
152
|
+
:consistent_read => @config.consistent_read}
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [Hash] merged hash of all hashes passed in.
|
156
|
+
def merge_all(*hashes)
|
157
|
+
new_hash = {}
|
158
|
+
hashes.each{|hash| new_hash.merge!(hash)}
|
159
|
+
new_hash
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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
|
+
module AWS::SessionStore::DynamoDB::Locking
|
16
|
+
# This class gets and sets sessions
|
17
|
+
# without a locking strategy.
|
18
|
+
class Null < AWS::SessionStore::DynamoDB::Locking::Base
|
19
|
+
# Retrieve session if it exists from the database by id.
|
20
|
+
# Unpack the data once retrieved from the database.
|
21
|
+
def get_session_data(env, sid)
|
22
|
+
handle_error(env) do
|
23
|
+
result = @config.dynamo_db_client.get_item(get_session_opts(sid))
|
24
|
+
extract_data(env, result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Hash] Options for getting session.
|
29
|
+
def get_session_opts(sid)
|
30
|
+
merge_all(table_opts(sid), attr_opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String] Session data.
|
34
|
+
def extract_data(env, result = nil)
|
35
|
+
env['rack.initial_data'] = result[:item]["data"][:s] if result[:item]
|
36
|
+
unpack_data(result[:item]["data"][:s]) if result[:item]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|