hoodoo 2.11.1 → 2.12.0
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.
- 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
|