hoodoo 2.11.1 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hoodoo/services/middleware/middleware.rb +96 -15
- data/lib/hoodoo/services/services/session.rb +77 -23
- data/lib/hoodoo/transient_store/transient_store/memcached_redis_mirror.rb +24 -2
- data/lib/hoodoo/version.rb +2 -2
- data/spec/services/middleware/middleware_spec.rb +38 -0
- data/spec/services/services/session_spec.rb +128 -96
- data/spec/transient_store/transient_store/memcached_redis_mirror_spec.rb +11 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6cfaed24695383d45ef45ee57241f89f37ef6005247c613014238c59b57f158
|
4
|
+
data.tar.gz: 0547a5c355d815eaf6709f5023fa9878065f613d43c492fe781d87dbcb40b075
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af7cd5e04e9ed36530627d80120a43a3f7e5569fda99969cf23c437edb98e509011cd00a83e720d67027bbfedd09a2b3cdc20cbcfcbd7b6d56dfb1a30152122a
|
7
|
+
data.tar.gz: a4cc5ef27dfb5ae7d8f3c8ad555fd96101ca0ac6b864055d4b37534a276ffb47856da28c9b7eacbe6fb93b766b9285c164ae338d76ed268998c209dc5b2446a6
|
@@ -243,15 +243,30 @@ module Hoodoo; module Services
|
|
243
243
|
@@environment ||= Hoodoo::StringInquirer.new( ENV[ 'RACK_ENV' ] || 'development' )
|
244
244
|
end
|
245
245
|
|
246
|
-
#
|
247
|
-
#
|
248
|
-
#
|
246
|
+
# This method is deprecated. Use ::has_session_store? instead.
|
247
|
+
#
|
248
|
+
# Return a boolean value for whether Memcached is explicitly defined as
|
249
|
+
# the Hoodoo::TransientStore engine. In previous versions, a +nil+ response
|
250
|
+
# used to indicate local development without a queue available, but that is
|
251
|
+
# not a valid assumption in modern code.
|
249
252
|
#
|
250
253
|
def self.has_memcached?
|
254
|
+
$stderr.puts( 'Hoodoo::Services::Middleware::Middleware#has_memcached? is deprecated - use #has_session_store?' )
|
255
|
+
|
251
256
|
m = self.memcached_host()
|
252
257
|
m.nil? == false && m.empty? == false
|
253
258
|
end
|
254
259
|
|
260
|
+
# Return a boolean value for whether an environment variable declaring
|
261
|
+
# Hoodoo::TransientStore engine URI(s) have been defined by service author.
|
262
|
+
#
|
263
|
+
def self.has_session_store?
|
264
|
+
config = self.session_store_uri()
|
265
|
+
config.nil? == false && config.empty? == false
|
266
|
+
end
|
267
|
+
|
268
|
+
# This method is deprecated. Use ::session_store_uri instead.
|
269
|
+
#
|
255
270
|
# Return a Memcached host (IP address/port combination) as a String if
|
256
271
|
# defined in environment variable MEMCACHED_HOST (with MEMCACHE_URL also
|
257
272
|
# accepted as a legacy fallback).
|
@@ -274,6 +289,69 @@ module Hoodoo; module Services
|
|
274
289
|
@@memcached_host = nil
|
275
290
|
end
|
276
291
|
|
292
|
+
# Return configuration for the selected Hoodoo::TransientStore engine, as
|
293
|
+
# a flat String (IP address/ port combination) or a serialised JSON string
|
294
|
+
# with symbolised keys, defining a URI for each supported storage engine
|
295
|
+
# defined (required if <tt>ENV[ 'SESSION_STORE_ENGINE' ]</yy> defines a
|
296
|
+
# multi-engine strategy).
|
297
|
+
#
|
298
|
+
# Checks for the engine agnostic environment variable +SESSION_STORE_URI+
|
299
|
+
# first then uses #memcached_host as a legacy fallback.
|
300
|
+
#
|
301
|
+
def self.session_store_uri
|
302
|
+
|
303
|
+
# See also ::clear_session_store_configuration_cache!
|
304
|
+
#
|
305
|
+
@@session_store_uri ||= ( ENV[ 'SESSION_STORE_URI' ] || self.memcached_host() )
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
# Return a symbolised key for the transient storage engine as defined in
|
310
|
+
# the environment variable +SESSION_STORE_ENGINE+ (with +:memcached+ as a
|
311
|
+
# legacy fallback if ::has_memcached? is +true+, else default is +nil+).
|
312
|
+
#
|
313
|
+
# The +SESSION_STORE_ENGINE+ environment variable must contain an entry
|
314
|
+
# from Hoodoo::TransientStore::supported_storage_engines. This collection
|
315
|
+
# is initialised by either requiring the top-level +hoodoo+ file to pull
|
316
|
+
# in everything, requiring <tt>hoodoo/transient_store</tt> to pull in all
|
317
|
+
# currently defined transient store engines or requiring the following
|
318
|
+
# in order to pull in a specific engine - in this example, redis:
|
319
|
+
#
|
320
|
+
# require 'hoodoo/transient_store/transient_store'
|
321
|
+
# require 'hoodoo/transient_store/transient_store/base'
|
322
|
+
# require 'hoodoo/transient_store/transient_store/redis'
|
323
|
+
#
|
324
|
+
# If the engine requested appears to be unsupported, this method returns
|
325
|
+
# +nil+.
|
326
|
+
#
|
327
|
+
def self.session_store_engine
|
328
|
+
if (
|
329
|
+
! defined?( @@session_store_engine ) ||
|
330
|
+
@@session_store_engine.nil? ||
|
331
|
+
@@session_store_engine.empty?
|
332
|
+
)
|
333
|
+
default = self.has_memcached? ? 'memcached' : ''
|
334
|
+
engine = ( ENV[ 'SESSION_STORE_ENGINE' ] || default ).to_sym()
|
335
|
+
|
336
|
+
if Hoodoo::TransientStore::supported_storage_engines.include?( engine )
|
337
|
+
@@session_store_engine = engine
|
338
|
+
else
|
339
|
+
@@session_store_engine = nil
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
@@session_store_engine
|
344
|
+
end
|
345
|
+
|
346
|
+
# This method is intended really just for testing purposes; it clears the
|
347
|
+
# internal cache of session storage engine data read from environment
|
348
|
+
# variables.
|
349
|
+
#
|
350
|
+
def self.clear_session_store_configuration_cache!
|
351
|
+
@@session_store_engine = nil
|
352
|
+
@@session_store_uri = nil
|
353
|
+
end
|
354
|
+
|
277
355
|
# Are we running on the queue, else (implied) a local HTTP server?
|
278
356
|
#
|
279
357
|
def self.on_queue?
|
@@ -423,9 +501,10 @@ module Hoodoo; module Services
|
|
423
501
|
end
|
424
502
|
|
425
503
|
# A Hoodoo::Services::Session instance to use for tests or when no
|
426
|
-
# local
|
427
|
-
# +
|
428
|
-
# time a request is made via
|
504
|
+
# local Hoodoo::TransientStore instance is known about (environment
|
505
|
+
# variable +SESSION_STORE_ENGINE+ and +SESSION_STORE_URI+ are not set).
|
506
|
+
# The session is (eventually) read each time a request is made via
|
507
|
+
# Rack (through #call).
|
429
508
|
#
|
430
509
|
# "Out of the box", DEFAULT_TEST_SESSION is used.
|
431
510
|
#
|
@@ -973,8 +1052,9 @@ module Hoodoo; module Services
|
|
973
1052
|
|
974
1053
|
# If we get this far the interim session isn't needed. We might have
|
975
1054
|
# exited early due to errors above and left this behind, but that's not
|
976
|
-
# the end of the world - it'll expire out of
|
977
|
-
|
1055
|
+
# the end of the world - it'll expire out of the Hoodoo::TransientStore
|
1056
|
+
# eventually.
|
1057
|
+
#
|
978
1058
|
if session &&
|
979
1059
|
source_interaction.context &&
|
980
1060
|
source_interaction.context.session &&
|
@@ -1647,8 +1727,8 @@ module Hoodoo; module Services
|
|
1647
1727
|
end
|
1648
1728
|
end
|
1649
1729
|
|
1650
|
-
# Load a session from
|
1651
|
-
# in the current interaction's Rack request data.
|
1730
|
+
# Load a session from the selected Hoodoo::TransientStore on the basis of
|
1731
|
+
# a session ID header in the current interaction's Rack request data.
|
1652
1732
|
#
|
1653
1733
|
# On exit, the interaction context may have been updated. Be sure to
|
1654
1734
|
# check +interaction.context.response.halt_processing?+ to see if
|
@@ -1665,11 +1745,12 @@ module Hoodoo; module Services
|
|
1665
1745
|
|
1666
1746
|
if session_id != nil && ( test_session.nil? || test_session.session_id != session_id )
|
1667
1747
|
session = Hoodoo::Services::Session.new(
|
1668
|
-
:
|
1669
|
-
:
|
1748
|
+
:storage_engine => self.class.session_store_engine(),
|
1749
|
+
:storage_host_uri => self.class.session_store_uri(),
|
1750
|
+
:session_id => session_id
|
1670
1751
|
)
|
1671
1752
|
|
1672
|
-
result
|
1753
|
+
result = session.load_from_store!( session_id )
|
1673
1754
|
session = nil if result != :ok
|
1674
1755
|
elsif ( self.class.environment.test? || self.class.environment.development? )
|
1675
1756
|
interaction.using_test_session()
|
@@ -1679,7 +1760,7 @@ module Hoodoo; module Services
|
|
1679
1760
|
# If there's no session and no local interfaces have any public
|
1680
1761
|
# methods (everything is protected) then bail out early, as the
|
1681
1762
|
# request can't possibly succeed.
|
1682
|
-
|
1763
|
+
#
|
1683
1764
|
if session.nil? && interfaces_have_public_methods? == false
|
1684
1765
|
return interaction.context.response.add_error( 'platform.invalid_session' )
|
1685
1766
|
end
|
@@ -1688,7 +1769,7 @@ module Hoodoo; module Services
|
|
1688
1769
|
# the context data is exposed to service implementations, the
|
1689
1770
|
# session reference is read-only; don't break that protection;
|
1690
1771
|
# instead build and use a replacement context.
|
1691
|
-
|
1772
|
+
#
|
1692
1773
|
if session != interaction.context.session
|
1693
1774
|
updated_context = Hoodoo::Services::Context.new(
|
1694
1775
|
session,
|
@@ -53,7 +53,7 @@ module Hoodoo
|
|
53
53
|
#
|
54
54
|
# If you _change_ a Caller version in a Session, you _really_ should
|
55
55
|
# call #save_to_store as soon as possible afterwards so that the
|
56
|
-
# change gets recognised in the
|
56
|
+
# change gets recognised in the Hoodoo::TransientStore.
|
57
57
|
#
|
58
58
|
attr_accessor :caller_version
|
59
59
|
|
@@ -119,13 +119,17 @@ module Hoodoo
|
|
119
119
|
#
|
120
120
|
attr_reader :expires_at
|
121
121
|
|
122
|
-
#
|
122
|
+
# Declares the transient storage engine this session will write to.
|
123
|
+
# Both this and +storage_host_uri+ are used within
|
124
|
+
# Hoodoo::TransientStore::new.
|
123
125
|
#
|
124
|
-
|
125
|
-
|
126
|
+
attr_accessor :storage_engine
|
127
|
+
|
128
|
+
# Connection IP address/port String for the selected storage engine. The
|
129
|
+
# connection host can be set either through this accessor, or via the
|
126
130
|
# object's constructor.
|
127
131
|
#
|
128
|
-
attr_accessor :
|
132
|
+
attr_accessor :storage_host_uri
|
129
133
|
|
130
134
|
# Create a new instance.
|
131
135
|
#
|
@@ -133,26 +137,35 @@ module Hoodoo
|
|
133
137
|
#
|
134
138
|
# Options are:
|
135
139
|
#
|
136
|
-
# +session_id+::
|
137
|
-
#
|
138
|
-
#
|
140
|
+
# +session_id+:: UUID of this session. If unset, a new UUID is
|
141
|
+
# generated for you. You can read the UUID with
|
142
|
+
# the #session_id accessor method.
|
143
|
+
#
|
144
|
+
# +caller_id+:: UUID of the Caller instance associated with this
|
145
|
+
# session. This can be set either now or later,
|
146
|
+
# but the session cannot be saved without it.
|
147
|
+
#
|
148
|
+
# +caller_version+:: Version of the Caller instance. Defaults to
|
149
|
+
# zero.
|
139
150
|
#
|
140
|
-
# +
|
141
|
-
#
|
142
|
-
# the session cannot be saved without it.
|
151
|
+
# +caller_fingerprint+:: Optional Caller fingerprint UUID. Defaults to
|
152
|
+
# +nil+.
|
143
153
|
#
|
144
|
-
# +
|
154
|
+
# +storage_engine+:: An entry (Symbol) from
|
155
|
+
# Hoodoo::TransientStore::supported_storage_engines.
|
156
|
+
# Defaults to +:memcached+.
|
145
157
|
#
|
146
|
-
# +
|
147
|
-
#
|
158
|
+
# +storage_host_uri+:: URI for Hoodoo::TransientStore engine
|
159
|
+
# connections.
|
148
160
|
#
|
149
|
-
# +memcached_host+::
|
161
|
+
# +memcached_host+:: Host for Memcached connections (deprecated).
|
150
162
|
#
|
151
163
|
def initialize( options = {} )
|
152
164
|
@created_at = Time.now.utc
|
153
165
|
|
154
166
|
self.session_id = options[ :session_id ] || Hoodoo::UUID.generate()
|
155
|
-
self.
|
167
|
+
self.storage_engine = options[ :storage_engine ] || :memcached
|
168
|
+
self.storage_host_uri = options[ :storage_host_uri ] || options[ :memcached_host ]
|
156
169
|
self.caller_id = options[ :caller_id ]
|
157
170
|
self.caller_version = options[ :caller_version ] || 0
|
158
171
|
self.caller_fingerprint = options[ :caller_fingerprint ]
|
@@ -277,7 +290,7 @@ module Hoodoo
|
|
277
290
|
# * +:not_found+: The session was not found.
|
278
291
|
#
|
279
292
|
# * +:fail+: The session data could not be loaded (unexpected storage
|
280
|
-
#
|
293
|
+
# engine failure).
|
281
294
|
#
|
282
295
|
def load_from_store!( sid )
|
283
296
|
begin
|
@@ -347,7 +360,7 @@ module Hoodoo
|
|
347
360
|
# local Caller data must therefore already be out of date.
|
348
361
|
#
|
349
362
|
# * +:fail+: The Caller could not be updated (unexpected storage engine
|
350
|
-
#
|
363
|
+
# failure).
|
351
364
|
#
|
352
365
|
def update_caller_version_in_store( cid, cv, store = nil )
|
353
366
|
begin
|
@@ -374,6 +387,45 @@ module Hoodoo
|
|
374
387
|
return :fail
|
375
388
|
end
|
376
389
|
|
390
|
+
# Deprecated interface (use #storage_host_uri instead),
|
391
|
+
# dating back to when the Session engine was hard-coded to Memcached.
|
392
|
+
#
|
393
|
+
# Supports backwards compatibility of options key +memcached_host+,
|
394
|
+
# aliases +storage_host_uri+.
|
395
|
+
#
|
396
|
+
# Provides same functionality as +alias_method+, however includes a
|
397
|
+
# deprecation warning.
|
398
|
+
#
|
399
|
+
# Similar to:
|
400
|
+
#
|
401
|
+
# alias_method( :memcached_host, :storage_host_uri )
|
402
|
+
#
|
403
|
+
def memcached_host
|
404
|
+
Hoodoo::Services::Middleware.logger.warn(
|
405
|
+
'Hoodoo::Services::Session#memcached_host is deprecated - use #storage_host_uri'
|
406
|
+
)
|
407
|
+
|
408
|
+
storage_host_uri()
|
409
|
+
end
|
410
|
+
|
411
|
+
# Deprecated interface (use #storage_host_uri= instead),
|
412
|
+
# dating back to when the Session engine was hard-coded to Memcached.
|
413
|
+
#
|
414
|
+
# Provides same functionality as +alias_method+, however includes a
|
415
|
+
# deprecation warning.
|
416
|
+
#
|
417
|
+
# Similar to:
|
418
|
+
#
|
419
|
+
# alias_method( :memcached_host=, :storage_host_uri= )
|
420
|
+
#
|
421
|
+
def memcached_host=( uri )
|
422
|
+
Hoodoo::Services::Middleware.logger.warn(
|
423
|
+
'Hoodoo::Services::Session#memcached_host= is deprecated - use #storage_host_uri='
|
424
|
+
)
|
425
|
+
|
426
|
+
self.storage_host_uri = uri
|
427
|
+
end
|
428
|
+
|
377
429
|
# Deprecated interface (use #update_caller_version_in_store instead),
|
378
430
|
# dating back to when the Session engine was hard-coded to Memcached.
|
379
431
|
#
|
@@ -421,7 +473,7 @@ module Hoodoo
|
|
421
473
|
# * +:ok+: The Session was deleted from the transient store successfully.
|
422
474
|
#
|
423
475
|
# * +:fail+: The session data could not be deleted (unexpected storage
|
424
|
-
#
|
476
|
+
# engine failure).
|
425
477
|
#
|
426
478
|
def delete_from_store
|
427
479
|
begin
|
@@ -641,16 +693,18 @@ module Hoodoo
|
|
641
693
|
|
642
694
|
private
|
643
695
|
|
644
|
-
# Connect to the storage engine
|
696
|
+
# Connect to the storage engine, using the +storage_engine+ and
|
697
|
+
# +storage_host_uri+ attributes. Returns a Hoodoo:TransientStore
|
645
698
|
# instance. Raises an exception if no connection can be established.
|
646
699
|
#
|
647
700
|
def get_store
|
648
|
-
|
701
|
+
engine = self.storage_engine()
|
702
|
+
host = self.storage_host_uri()
|
649
703
|
|
650
704
|
begin
|
651
705
|
@@stores ||= {}
|
652
706
|
@@stores[ host ] ||= Hoodoo::TransientStore.new(
|
653
|
-
storage_engine:
|
707
|
+
storage_engine: engine,
|
654
708
|
storage_host_uri: host,
|
655
709
|
default_namespace: 'nz_co_loyalty_hoodoo_session_'
|
656
710
|
)
|
@@ -658,7 +712,7 @@ module Hoodoo
|
|
658
712
|
raise 'Unknown storage engine failure' if @@stores[ host ].nil?
|
659
713
|
|
660
714
|
rescue => exception
|
661
|
-
raise "Hoodoo::Services::Session\#get_store: Cannot connect to
|
715
|
+
raise "Hoodoo::Services::Session\#get_store: Cannot connect to #{ engine } at '#{ host }': #{ exception }"
|
662
716
|
|
663
717
|
end
|
664
718
|
|
@@ -61,8 +61,9 @@ module Hoodoo
|
|
61
61
|
# Hoodoo::TransientStore::new.
|
62
62
|
#
|
63
63
|
# The +storage_host_uri+ parameter is necessarily unusual here. It must
|
64
|
-
# be _a Hash_ with Symbol keys +:memcached+ and +:redis+,
|
65
|
-
#
|
64
|
+
# be either _a Hash_ with Symbol keys +:memcached+ and +:redis+, or a
|
65
|
+
# serialised JSON string representing the same information. These values
|
66
|
+
# define the actual storage engine host URI for the respective engines.
|
66
67
|
# For example, to connect to locally running engines configured on their
|
67
68
|
# default ports, pass this Hash in +storage_host_uri+:
|
68
69
|
#
|
@@ -71,6 +72,13 @@ module Hoodoo
|
|
71
72
|
# :redis => 'redis://localhost:6379'
|
72
73
|
# }
|
73
74
|
#
|
75
|
+
# ...or:
|
76
|
+
#
|
77
|
+
# "{
|
78
|
+
# \"memcached\": \"localhost:11211\",
|
79
|
+
# \"redis\": \"redis://localhost:6379\"
|
80
|
+
# }"
|
81
|
+
#
|
74
82
|
# See Hoodoo::TransientStore::Memcached::new and
|
75
83
|
# Hoodoo::TransientStore::Redis::new for details of connection URI
|
76
84
|
# requirements for those engines.
|
@@ -80,6 +88,8 @@ module Hoodoo
|
|
80
88
|
def initialize( storage_host_uri:, namespace: )
|
81
89
|
super # Pass all arguments through -> *not* 'super()'
|
82
90
|
|
91
|
+
storage_host_uri = deserialize_and_symbolize( storage_host_uri ) if storage_host_uri.is_a?( String )
|
92
|
+
|
83
93
|
unless storage_host_uri.is_a?( Hash ) &&
|
84
94
|
storage_host_uri.has_key?( :memcached ) &&
|
85
95
|
storage_host_uri.has_key?( :redis )
|
@@ -170,6 +180,18 @@ module Hoodoo
|
|
170
180
|
@redis_store.close()
|
171
181
|
end
|
172
182
|
|
183
|
+
private
|
184
|
+
|
185
|
+
# Helper method for deserialising JSON objects and enforcing hash
|
186
|
+
# keys are symbolised.
|
187
|
+
#
|
188
|
+
def deserialize_and_symbolize( serialized_string )
|
189
|
+
Hoodoo::Utilities.symbolize( JSON.parse( serialized_string ) )
|
190
|
+
|
191
|
+
rescue JSON::ParserError
|
192
|
+
raise 'Hoodoo::TransientStore::MemcachedRedisMirror: Bad storage host URI data passed to constructor'
|
193
|
+
end
|
194
|
+
|
173
195
|
end
|
174
196
|
|
175
197
|
Hoodoo::TransientStore.register(
|
data/lib/hoodoo/version.rb
CHANGED
@@ -12,11 +12,11 @@ module Hoodoo
|
|
12
12
|
# The Hoodoo gem version. If this changes, be sure to re-run
|
13
13
|
# <tt>bundle install</tt> or <tt>bundle update</tt>.
|
14
14
|
#
|
15
|
-
VERSION = '2.
|
15
|
+
VERSION = '2.12.0'
|
16
16
|
|
17
17
|
# The Hoodoo gem date. If this changes, be sure to re-run
|
18
18
|
# <tt>bundle install</tt> or <tt>bundle update</tt>.
|
19
19
|
#
|
20
|
-
DATE = '2018-12-
|
20
|
+
DATE = '2018-12-17'
|
21
21
|
|
22
22
|
end
|
@@ -179,11 +179,13 @@ describe Hoodoo::Services::Middleware do
|
|
179
179
|
|
180
180
|
context 'utility methods' do
|
181
181
|
before :each do
|
182
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
182
183
|
Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
|
183
184
|
Hoodoo::Services::Middleware.clear_queue_configuration_cache!
|
184
185
|
end
|
185
186
|
|
186
187
|
after :each do
|
188
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
187
189
|
Hoodoo::Services::Middleware.clear_memcached_configuration_cache!
|
188
190
|
Hoodoo::Services::Middleware.clear_queue_configuration_cache!
|
189
191
|
end
|
@@ -212,6 +214,42 @@ describe Hoodoo::Services::Middleware do
|
|
212
214
|
end
|
213
215
|
end
|
214
216
|
|
217
|
+
it 'should know about TransientStore configuration via environment variable' do
|
218
|
+
old_uri = ENV[ 'SESSION_STORE_URI' ]
|
219
|
+
old_engine = ENV[ 'SESSION_STORE_ENGINE' ]
|
220
|
+
ENV[ 'MEMCACHED_HOST' ] = nil
|
221
|
+
ENV[ 'SESSION_STORE_URI' ] = nil
|
222
|
+
ENV[ 'SESSION_STORE_ENGINE' ] = nil
|
223
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
224
|
+
expect( Hoodoo::Services::Middleware.has_session_store? ).to eq( false )
|
225
|
+
expect( Hoodoo::Services::Middleware.session_store_engine ).to be_nil
|
226
|
+
expect( Hoodoo::Services::Middleware.session_store_uri ).to be_nil
|
227
|
+
ENV[ 'SESSION_STORE_URI' ] = 'foo'
|
228
|
+
ENV[ 'SESSION_STORE_ENGINE' ] = 'redis'
|
229
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
230
|
+
expect( Hoodoo::Services::Middleware.has_session_store? ).to eq( true )
|
231
|
+
expect( Hoodoo::Services::Middleware.session_store_uri ).to eq( 'foo' )
|
232
|
+
expect( Hoodoo::Services::Middleware.session_store_engine ).to eq( :redis )
|
233
|
+
ENV[ 'SESSION_STORE_URI' ] = old_uri
|
234
|
+
ENV[ 'SESSION_STORE_ENGINE' ] = old_engine
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should know about Memcached via legacy environment variable' do
|
238
|
+
old_uri = ENV[ 'MEMCACHED_HOST' ]
|
239
|
+
old_engine = ENV[ 'SESSION_STORE_ENGINE' ]
|
240
|
+
ENV[ 'MEMCACHED_HOST' ] = nil
|
241
|
+
ENV[ 'SESSION_STORE_ENGINE' ] = nil
|
242
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
243
|
+
expect( Hoodoo::Services::Middleware.has_memcached? ).to eq(false)
|
244
|
+
expect( Hoodoo::Services::Middleware.session_store_engine ).to be_nil
|
245
|
+
ENV[ 'MEMCACHED_HOST' ] = 'foo'
|
246
|
+
Hoodoo::Services::Middleware.clear_session_store_configuration_cache!
|
247
|
+
expect( Hoodoo::Services::Middleware.has_memcached? ).to eq(true)
|
248
|
+
expect( Hoodoo::Services::Middleware.session_store_engine ).to eq(:memcached)
|
249
|
+
ENV[ 'MEMCACHED_HOST' ] = old_uri
|
250
|
+
ENV[ 'SESSION_STORE_ENGINE' ] = old_engine
|
251
|
+
end
|
252
|
+
|
215
253
|
it 'should know about Memcached via legacy environment variable' do
|
216
254
|
spec_helper_change_environment( 'MEMCACHE_URL', nil ) do
|
217
255
|
expect(Hoodoo::Services::Middleware.has_memcached?).to eq(false)
|
@@ -11,30 +11,49 @@ describe Hoodoo::Services::Session do
|
|
11
11
|
context 'basics' do
|
12
12
|
it 'initialises with default options' do
|
13
13
|
s = described_class.new()
|
14
|
-
expect( s.created_at
|
14
|
+
expect( s.created_at ).to be_a( Time )
|
15
15
|
expect( Hoodoo::UUID.valid?( s.session_id ) ).to eq( true )
|
16
|
-
expect( s.memcached_host
|
17
|
-
expect( s.
|
18
|
-
expect( s.
|
19
|
-
expect( s.
|
16
|
+
expect( s.memcached_host ).to be_nil
|
17
|
+
expect( s.storage_host_uri ).to eq( s.memcached_host )
|
18
|
+
expect( s.storage_engine ).to eq( :memcached )
|
19
|
+
expect( s.caller_id ).to be_nil
|
20
|
+
expect( s.caller_version ).to eq( 0 )
|
21
|
+
expect( s.caller_fingerprint ).to be_nil
|
20
22
|
end
|
21
23
|
|
22
24
|
it 'initialises with given options' do
|
23
25
|
s = described_class.new(
|
24
|
-
:session_id
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
26
|
+
:session_id => '1234',
|
27
|
+
:storage_host_uri => 'abcd',
|
28
|
+
:storage_engine => :redis,
|
29
|
+
:caller_id => '0987',
|
30
|
+
:caller_version => 2,
|
31
|
+
:caller_fingerprint => 'asdf'
|
29
32
|
)
|
30
|
-
expect( s.created_at
|
31
|
-
expect( s.session_id
|
32
|
-
expect( s.memcached_host
|
33
|
-
expect( s.
|
34
|
-
expect( s.
|
33
|
+
expect( s.created_at ).to be_a( Time )
|
34
|
+
expect( s.session_id ).to eq( '1234' )
|
35
|
+
expect( s.memcached_host ).to eq( 'abcd' )
|
36
|
+
expect( s.storage_host_uri ).to eq( 'abcd' )
|
37
|
+
expect( s.storage_engine ).to eq( :redis )
|
38
|
+
expect( s.caller_id ).to eq( '0987' )
|
39
|
+
expect( s.caller_version ).to eq( 2 )
|
35
40
|
expect( s.caller_fingerprint ).to eq( 'asdf' )
|
36
41
|
end
|
37
42
|
|
43
|
+
it 'initialises with deprecated :memcached_host option' do
|
44
|
+
s = described_class.new(
|
45
|
+
:session_id => '1234',
|
46
|
+
:memcached_host => 'abcd',
|
47
|
+
:caller_id => '0987',
|
48
|
+
:caller_version => 2,
|
49
|
+
:caller_fingerprint => 'asdf'
|
50
|
+
)
|
51
|
+
|
52
|
+
expect( s.memcached_host ).to eq( 'abcd' )
|
53
|
+
expect( s.storage_host_uri ).to eq( 'abcd' )
|
54
|
+
expect( s.storage_engine ).to eq( :memcached )
|
55
|
+
end
|
56
|
+
|
38
57
|
it 'reports not expired when it has no expiry' do
|
39
58
|
s = described_class.new
|
40
59
|
expect( s.expired? ).to eq( false )
|
@@ -48,10 +67,11 @@ describe Hoodoo::Services::Session do
|
|
48
67
|
|
49
68
|
it 'converts to a Hash' do
|
50
69
|
s = described_class.new(
|
51
|
-
:session_id
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
70
|
+
:session_id => '1234',
|
71
|
+
:storage_host_uri => 'abcd',
|
72
|
+
:storage_engine => :memcached,
|
73
|
+
:caller_id => '0987',
|
74
|
+
:caller_version => 2,
|
55
75
|
:caller_fingerprint => 'asdf'
|
56
76
|
)
|
57
77
|
p = Hoodoo::Services::Permissions.new
|
@@ -109,12 +129,13 @@ describe Hoodoo::Services::Session do
|
|
109
129
|
expect( s.permissions.to_h ).to eq( p.to_h )
|
110
130
|
end
|
111
131
|
|
112
|
-
it 'saves/loads to/from
|
132
|
+
it 'saves/loads to/from transient store' do
|
113
133
|
s1 = described_class.new(
|
114
|
-
:session_id
|
115
|
-
:
|
116
|
-
:
|
117
|
-
:
|
134
|
+
:session_id => '1234',
|
135
|
+
:storage_host_uri => 'abcd',
|
136
|
+
:storage_engine => :memcached,
|
137
|
+
:caller_id => '0987',
|
138
|
+
:caller_version => 2,
|
118
139
|
:caller_fingerprint => 'asdf'
|
119
140
|
)
|
120
141
|
|
@@ -142,7 +163,7 @@ describe Hoodoo::Services::Session do
|
|
142
163
|
expect( s2.created_at ).to eq( Time.parse( Hoodoo::Utilities.standard_datetime( s1.created_at ) ) )
|
143
164
|
expect( s2.expires_at ).to eq( Time.parse( Hoodoo::Utilities.standard_datetime( s1.expires_at ) ) )
|
144
165
|
expect( s2.session_id ).to eq( s1.session_id )
|
145
|
-
expect( s2.
|
166
|
+
expect( s2.storage_host_uri ).to be_nil
|
146
167
|
expect( s2.caller_id ).to eq( s1.caller_id )
|
147
168
|
expect( s2.caller_version ).to eq( s1.caller_version )
|
148
169
|
expect( s2.caller_fingerprint ).to eq( s1.caller_fingerprint )
|
@@ -150,10 +171,11 @@ describe Hoodoo::Services::Session do
|
|
150
171
|
|
151
172
|
it 'can be deleted' do
|
152
173
|
s = described_class.new(
|
153
|
-
:session_id
|
154
|
-
:
|
155
|
-
:
|
156
|
-
:
|
174
|
+
:session_id => '1234',
|
175
|
+
:storage_host_uri => 'abcd',
|
176
|
+
:storage_engine => :memcached,
|
177
|
+
:caller_id => '0987',
|
178
|
+
:caller_version => 1
|
157
179
|
)
|
158
180
|
|
159
181
|
s.save_to_store
|
@@ -163,10 +185,11 @@ describe Hoodoo::Services::Session do
|
|
163
185
|
|
164
186
|
it 'handles attempts to delete not-found things' do
|
165
187
|
s = described_class.new(
|
166
|
-
:session_id
|
167
|
-
:
|
168
|
-
:
|
169
|
-
:
|
188
|
+
:session_id => '1234',
|
189
|
+
:storage_host_uri => 'abcd',
|
190
|
+
:storage_engine => :memcached,
|
191
|
+
:caller_id => '0987',
|
192
|
+
:caller_version => 1
|
170
193
|
)
|
171
194
|
|
172
195
|
expect( s.delete_from_store ).to eq( :ok )
|
@@ -181,10 +204,10 @@ describe Hoodoo::Services::Session do
|
|
181
204
|
# Save a session with a high caller version
|
182
205
|
|
183
206
|
s1 = described_class.new(
|
184
|
-
:session_id
|
185
|
-
:
|
186
|
-
:caller_id
|
187
|
-
:caller_version
|
207
|
+
:session_id => '1234',
|
208
|
+
:storage_host_uri => 'abcd',
|
209
|
+
:caller_id => '0987',
|
210
|
+
:caller_version => 4
|
188
211
|
)
|
189
212
|
|
190
213
|
expect( s1.save_to_store ).to eq( :ok )
|
@@ -193,10 +216,10 @@ describe Hoodoo::Services::Session do
|
|
193
216
|
# is that session creation is underway when a caller gets updated.
|
194
217
|
|
195
218
|
s2 = described_class.new(
|
196
|
-
:session_id
|
197
|
-
:
|
198
|
-
:caller_id
|
199
|
-
:caller_version
|
219
|
+
:session_id => '2345',
|
220
|
+
:storage_host_uri => 'abcd',
|
221
|
+
:caller_id => '0987',
|
222
|
+
:caller_version => 3
|
200
223
|
)
|
201
224
|
|
202
225
|
expect( s2.save_to_store ).to eq( :outdated )
|
@@ -208,10 +231,10 @@ describe Hoodoo::Services::Session do
|
|
208
231
|
# Save a session with a low caller version.
|
209
232
|
|
210
233
|
s1 = described_class.new(
|
211
|
-
:session_id
|
212
|
-
:
|
213
|
-
:caller_id
|
214
|
-
:caller_version
|
234
|
+
:session_id => '1234',
|
235
|
+
:storage_host_uri => 'abcd',
|
236
|
+
:caller_id => '0987',
|
237
|
+
:caller_version => 1
|
215
238
|
)
|
216
239
|
|
217
240
|
expect( s1.save_to_store ).to eq( :ok )
|
@@ -219,10 +242,10 @@ describe Hoodoo::Services::Session do
|
|
219
242
|
# Save another with a higher caller version.
|
220
243
|
|
221
244
|
s2 = described_class.new(
|
222
|
-
:session_id
|
223
|
-
:
|
224
|
-
:caller_id
|
225
|
-
:caller_version
|
245
|
+
:session_id => '2345',
|
246
|
+
:storage_host_uri => 'abcd',
|
247
|
+
:caller_id => '0987',
|
248
|
+
:caller_version => 2
|
226
249
|
)
|
227
250
|
|
228
251
|
expect( s2.save_to_store ).to eq( :ok )
|
@@ -239,10 +262,10 @@ describe Hoodoo::Services::Session do
|
|
239
262
|
# Save a session with a low caller version
|
240
263
|
|
241
264
|
s1 = described_class.new(
|
242
|
-
:session_id
|
243
|
-
:
|
244
|
-
:caller_id
|
245
|
-
:caller_version
|
265
|
+
:session_id => '1234',
|
266
|
+
:storage_host_uri => 'abcd',
|
267
|
+
:caller_id => '0987',
|
268
|
+
:caller_version => 1
|
246
269
|
)
|
247
270
|
|
248
271
|
expect( s1.save_to_store ).to eq( :ok )
|
@@ -254,10 +277,10 @@ describe Hoodoo::Services::Session do
|
|
254
277
|
# Save another with a higher caller version.
|
255
278
|
|
256
279
|
s2 = described_class.new(
|
257
|
-
:session_id
|
258
|
-
:
|
259
|
-
:caller_id
|
260
|
-
:caller_version
|
280
|
+
:session_id => '2345',
|
281
|
+
:storage_host_uri => 'abcd',
|
282
|
+
:caller_id => '0987',
|
283
|
+
:caller_version => 2
|
261
284
|
)
|
262
285
|
|
263
286
|
expect( s2.save_to_store ).to eq( :ok )
|
@@ -277,10 +300,10 @@ describe Hoodoo::Services::Session do
|
|
277
300
|
# Save a session for caller ID '0987'.
|
278
301
|
#
|
279
302
|
s1 = described_class.new(
|
280
|
-
:session_id
|
281
|
-
:
|
282
|
-
:caller_id
|
283
|
-
:caller_version
|
303
|
+
:session_id => '1234',
|
304
|
+
:storage_host_uri => 'abcd',
|
305
|
+
:caller_id => '0987',
|
306
|
+
:caller_version => 1
|
284
307
|
)
|
285
308
|
|
286
309
|
expect( s1.save_to_store ).to eq( :ok )
|
@@ -299,10 +322,11 @@ describe Hoodoo::Services::Session do
|
|
299
322
|
# caller IDs/versions.
|
300
323
|
|
301
324
|
s2 = described_class.new(
|
302
|
-
:session_id
|
303
|
-
:
|
304
|
-
:
|
305
|
-
:
|
325
|
+
:session_id => '2345',
|
326
|
+
:storage_host_uri => 'abcd',
|
327
|
+
:storage_engine => :memcached,
|
328
|
+
:caller_id => Hoodoo::UUID.generate(),
|
329
|
+
:caller_version => 1
|
306
330
|
)
|
307
331
|
|
308
332
|
expect( s2.save_to_store ).to eq( :ok )
|
@@ -322,10 +346,11 @@ describe Hoodoo::Services::Session do
|
|
322
346
|
# Save a session with a high caller version
|
323
347
|
|
324
348
|
s = described_class.new(
|
325
|
-
:session_id
|
326
|
-
:
|
327
|
-
:
|
328
|
-
:
|
349
|
+
:session_id => '1234',
|
350
|
+
:storage_host_uri => 'abcd',
|
351
|
+
:storage_engine => :memcached,
|
352
|
+
:caller_id => '0987',
|
353
|
+
:caller_version => 1
|
329
354
|
)
|
330
355
|
|
331
356
|
expect( s ).to receive( :to_h ).and_wrap_original do | obj, args |
|
@@ -344,10 +369,11 @@ describe Hoodoo::Services::Session do
|
|
344
369
|
context 'can explicitly update a caller' do
|
345
370
|
before :each do
|
346
371
|
@session = described_class.new(
|
347
|
-
:session_id
|
348
|
-
:
|
349
|
-
:
|
350
|
-
:
|
372
|
+
:session_id => '1234',
|
373
|
+
:storage_host_uri => 'abcd',
|
374
|
+
:storage_engine => :memcached,
|
375
|
+
:caller_id => '0987',
|
376
|
+
:caller_version => 1
|
351
377
|
)
|
352
378
|
end
|
353
379
|
|
@@ -463,10 +489,11 @@ describe Hoodoo::Services::Session do
|
|
463
489
|
|
464
490
|
it 'handles unknown Hoodoo::TransientStore engine failures when saving' do
|
465
491
|
s = described_class.new(
|
466
|
-
:session_id
|
467
|
-
:
|
468
|
-
:
|
469
|
-
:
|
492
|
+
:session_id => '1234',
|
493
|
+
:storage_host_uri => 'abcd',
|
494
|
+
:storage_engine => :memcached,
|
495
|
+
:caller_id => '0987',
|
496
|
+
:caller_version => 1
|
470
497
|
)
|
471
498
|
|
472
499
|
expect_any_instance_of( Hoodoo::TransientStore::Memcached ).to receive( :set ).once.and_call_original
|
@@ -484,10 +511,11 @@ describe Hoodoo::Services::Session do
|
|
484
511
|
|
485
512
|
it 'handles unknown Hoodoo::TransientStore engine failures when deleting' do
|
486
513
|
s = described_class.new(
|
487
|
-
:session_id
|
488
|
-
:
|
489
|
-
:
|
490
|
-
:
|
514
|
+
:session_id => '1234',
|
515
|
+
:storage_host_uri => 'abcd',
|
516
|
+
:storage_engine => :memcached,
|
517
|
+
:caller_id => '0987',
|
518
|
+
:caller_version => 1
|
491
519
|
)
|
492
520
|
|
493
521
|
s.save_to_store
|
@@ -502,10 +530,11 @@ describe Hoodoo::Services::Session do
|
|
502
530
|
|
503
531
|
it 'handles unknown Hoodoo::TransientStore engine returned exceptions' do
|
504
532
|
s = described_class.new(
|
505
|
-
:session_id
|
506
|
-
:
|
507
|
-
:
|
508
|
-
:
|
533
|
+
:session_id => '1234',
|
534
|
+
:storage_host_uri => 'abcd',
|
535
|
+
:storage_engine => :memcached,
|
536
|
+
:caller_id => '0987',
|
537
|
+
:caller_version => 1
|
509
538
|
)
|
510
539
|
|
511
540
|
s.save_to_store
|
@@ -520,10 +549,11 @@ describe Hoodoo::Services::Session do
|
|
520
549
|
|
521
550
|
it 'logs and reports internal deletion exceptions' do
|
522
551
|
s = described_class.new(
|
523
|
-
:session_id
|
524
|
-
:
|
525
|
-
:
|
526
|
-
:
|
552
|
+
:session_id => '1234',
|
553
|
+
:storage_host_uri => 'abcd',
|
554
|
+
:storage_engine => :memcached,
|
555
|
+
:caller_id => '0987',
|
556
|
+
:caller_version => 1
|
527
557
|
)
|
528
558
|
|
529
559
|
s.save_to_store
|
@@ -549,9 +579,9 @@ describe Hoodoo::Services::Session do
|
|
549
579
|
Hoodoo::Services::Session.class_variable_set( '@@stores', nil ) # Hack for test!
|
550
580
|
|
551
581
|
@instance = described_class.new(
|
552
|
-
:session_id
|
582
|
+
:session_id => '1234',
|
553
583
|
:memcached_host => 'abcd',
|
554
|
-
:caller_id
|
584
|
+
:caller_id => '0987',
|
555
585
|
:caller_version => 1
|
556
586
|
)
|
557
587
|
end
|
@@ -605,16 +635,18 @@ describe Hoodoo::Services::Session do
|
|
605
635
|
|
606
636
|
it 'via aliases for deprecated methods' do
|
607
637
|
s = described_class.new(
|
608
|
-
:session_id
|
638
|
+
:session_id => '1234',
|
609
639
|
:memcached_host => 'abcd',
|
610
|
-
:caller_id
|
640
|
+
:caller_id => '0987',
|
611
641
|
:caller_version => 2
|
612
642
|
)
|
613
643
|
|
614
|
-
expect( s ).to respond_to( :save_to_memcached
|
615
|
-
expect( s ).to respond_to( :load_from_memcached!
|
644
|
+
expect( s ).to respond_to( :save_to_memcached )
|
645
|
+
expect( s ).to respond_to( :load_from_memcached! )
|
616
646
|
expect( s ).to respond_to( :update_caller_version_in_memcached )
|
617
|
-
expect( s ).to respond_to( :delete_from_memcached
|
647
|
+
expect( s ).to respond_to( :delete_from_memcached )
|
648
|
+
expect( s ).to respond_to( :memcached_host )
|
649
|
+
expect( s ).to respond_to( :memcached_host= )
|
618
650
|
end
|
619
651
|
end
|
620
652
|
end
|
@@ -15,10 +15,10 @@ describe Hoodoo::TransientStore::MemcachedRedisMirror do
|
|
15
15
|
@memcached_uri = 'localhost:11211'
|
16
16
|
@redis_uri = 'redis://localhost:6379'
|
17
17
|
@namespace = Hoodoo::UUID.generate()
|
18
|
-
@storage_engine_uri = {
|
18
|
+
@storage_engine_uri = JSON.generate({
|
19
19
|
:memcached => @memcached_uri,
|
20
20
|
:redis => @redis_uri
|
21
|
-
}
|
21
|
+
})
|
22
22
|
|
23
23
|
# Use pure mock back-ends behind the Memcached and Redis abstraction
|
24
24
|
# layers; real back-end tests are done for them in their unit tests.
|
@@ -56,8 +56,15 @@ describe Hoodoo::TransientStore::MemcachedRedisMirror do
|
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'creates Memcached and Redis instances' do
|
59
|
-
expect( Hoodoo::TransientStore::Memcached ).to receive( :new )
|
60
|
-
|
59
|
+
expect( Hoodoo::TransientStore::Memcached ).to receive( :new ).with(
|
60
|
+
namespace: @namespace,
|
61
|
+
storage_host_uri: @memcached_uri
|
62
|
+
)
|
63
|
+
|
64
|
+
expect( Hoodoo::TransientStore::Redis ).to receive( :new ).with(
|
65
|
+
namespace: @namespace,
|
66
|
+
storage_host_uri: @redis_uri
|
67
|
+
)
|
61
68
|
|
62
69
|
Hoodoo::TransientStore::MemcachedRedisMirror.new(
|
63
70
|
storage_host_uri: @storage_engine_uri,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hoodoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loyalty New Zealand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -599,7 +599,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
599
599
|
version: '0'
|
600
600
|
requirements: []
|
601
601
|
rubyforge_project:
|
602
|
-
rubygems_version: 2.7.
|
602
|
+
rubygems_version: 2.7.7
|
603
603
|
signing_key:
|
604
604
|
specification_version: 4
|
605
605
|
summary: Opinionated APIs
|