routemaster-drain 2.4.4 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +3 -2
- data/README.md +23 -4
- data/gemfiles/rails_3.gemfile.lock +9 -8
- data/gemfiles/rails_4.gemfile.lock +11 -10
- data/gemfiles/rails_5.gemfile.lock +45 -44
- data/lib/routemaster/drain/basic.rb +0 -1
- data/lib/routemaster/drain/cache_busting.rb +38 -0
- data/lib/routemaster/drain/caching.rb +4 -1
- data/lib/routemaster/drain/mapping.rb +2 -1
- data/lib/routemaster/drain.rb +1 -1
- data/lib/routemaster/middleware/authenticate.rb +1 -2
- data/lib/routemaster/middleware/cache.rb +1 -2
- data/lib/routemaster/middleware/dirty.rb +1 -4
- data/lib/routemaster/middleware/expire_cache.rb +20 -0
- data/lib/routemaster/middleware/filter.rb +2 -2
- data/lib/routemaster/middleware/payload_filter.rb +10 -0
- data/lib/routemaster/middleware/siphon.rb +32 -0
- data/lib/routemaster/resources/rest_resource.rb +18 -8
- data/routemaster-drain.gemspec +1 -0
- data/spec/routemaster/api_client_spec.rb +1 -6
- data/spec/routemaster/drain/cache_busting_spec.rb +43 -0
- data/spec/routemaster/drain/caching_spec.rb +10 -4
- data/spec/routemaster/drain/mapping_spec.rb +10 -7
- data/spec/routemaster/middleware/cache_spec.rb +0 -5
- data/spec/routemaster/middleware/root_post_only_spec.rb +0 -4
- data/spec/routemaster/middleware/siphon_spec.rb +46 -0
- data/spec/routemaster/resources/rest_resource_spec.rb +35 -26
- data/spec/support/siphon.rb +13 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 174d544b122fdee4b52eb706ce2d1324e416eea4
|
4
|
+
data.tar.gz: 2d33ba614a48f0e613adc1941a2126d17354b2a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b3cc42bfe4e62e6ecc2b60e71c69525d669447c0601ea5bf06a1b79c1fdab7b6c1e20e1494acb980ac5097615231b2b22fda210cca1fc43b5fd87875667d453
|
7
|
+
data.tar.gz: 4688fb67eb80241cf5fe28e5eed11be1617d083f8625fe378de960ee2506d45f105666ab556e69adb0944d592755d2ec9b302c31b6c8864ebdcc23070e02734d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
### 2.5.0 (2017-04-11)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Allow template urls to be defined in services (#38)
|
6
|
+
- Adds the `Siphon` middleware (#39, #44)
|
7
|
+
- Adds `CacheBusting` middleware (#40)
|
8
|
+
|
9
|
+
Bug fixes:
|
10
|
+
|
11
|
+
- Caching middleware always busts the cache on events - preventing stale events being cached in some circumstances (#40)
|
12
|
+
|
1
13
|
### 2.4.4 (2017-03-27)
|
2
14
|
|
3
15
|
Features:
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
routemaster-drain (2.
|
4
|
+
routemaster-drain (2.5.0)
|
5
|
+
addressable
|
5
6
|
concurrent-ruby
|
6
7
|
faraday (>= 0.9.0)
|
7
8
|
faraday_middleware
|
@@ -36,7 +37,7 @@ GEM
|
|
36
37
|
dotenv (2.1.1)
|
37
38
|
ethon (0.10.1)
|
38
39
|
ffi (>= 1.3.0)
|
39
|
-
faraday (0.
|
40
|
+
faraday (0.12.0.1)
|
40
41
|
multipart-post (>= 1.2, < 3)
|
41
42
|
faraday_middleware (0.11.0.1)
|
42
43
|
faraday (>= 0.7.4, < 1.0)
|
data/README.md
CHANGED
@@ -199,7 +199,7 @@ response = @cache.fget('https://example.com/widgets/123')
|
|
199
199
|
puts response.body.id
|
200
200
|
```
|
201
201
|
|
202
|
-
In this example,
|
202
|
+
In this example, if your app was notified by Routemaster about Widget #123, the
|
203
203
|
cache will be very likely to be hit; and it will be invalidated automatically
|
204
204
|
whenever the drain gets notified about a change on that widget.
|
205
205
|
|
@@ -210,6 +210,17 @@ See
|
|
210
210
|
[rubydoc](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Cache)
|
211
211
|
for more details on `Cache`.
|
212
212
|
|
213
|
+
### Expire Cache data for all notified resources
|
214
|
+
|
215
|
+
You may wish to maintain a coherent cache but don't need the cache to be warmed
|
216
|
+
before you process incoming events. In that case, use the cache as detailed above
|
217
|
+
but swap the `Caching` drain out for `CachingBusting`
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
require 'routemaster/drain/machine'
|
221
|
+
$app = Routemaster::Drain::CachingBusting.new
|
222
|
+
```
|
223
|
+
|
213
224
|
## HTTP Client
|
214
225
|
The Drain is using a Faraday http client for communication between services. The client
|
215
226
|
comes with a convenient caching mechanism as a default and supports custom response materialization.
|
@@ -277,9 +288,10 @@ response.user.show(1)
|
|
277
288
|
|
278
289
|
The more elaborate drains are built with two components which can also be used
|
279
290
|
independently,
|
280
|
-
[`Dirty::Map`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Map)
|
281
|
-
and
|
282
|
-
[`
|
291
|
+
[`Dirty::Map`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Map),
|
292
|
+
[`Dirty::Filter`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Filter) and
|
293
|
+
[`Middleware::Siphon`](http://www.rubydoc.info/github/deliveroo/routemaster-drain/master/Routemaster/Middleware/Siphon).
|
294
|
+
|
283
295
|
|
284
296
|
### Dirty map
|
285
297
|
|
@@ -314,6 +326,11 @@ It stores transient state in Redis and will emit `:entity_changed` events
|
|
314
326
|
whenever an entity has changed. This event can usefully be fed into a dirty map,
|
315
327
|
as in `Receiver::Filter` for instance.
|
316
328
|
|
329
|
+
### Siphon
|
330
|
+
|
331
|
+
[`Middleware::Siphon`](http://www.rubydoc.info/github/deliveroo/routemaster-drain/master/Routemaster/Middleware/Siphon) extracts
|
332
|
+
payloads from the middleware chain, allowing them to be processed separately. This is useful for event topics where the update frequency is not well suited
|
333
|
+
to frequent caching. For example, a location update event which you'd expect to receive every few seconds.
|
317
334
|
|
318
335
|
## Contributing
|
319
336
|
|
@@ -327,3 +344,5 @@ Do not bump version numbers on branches (a maintainer will do this when cutting
|
|
327
344
|
a release); but please do describe your changes in the `CHANGELOG` (at the top,
|
328
345
|
without a version number).
|
329
346
|
|
347
|
+
If you have changed dependencies, you need to run `appraisal update` to make
|
348
|
+
sure the various version specific gemfiles are updated.
|
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
routemaster-drain (2.
|
4
|
+
routemaster-drain (2.5.0)
|
5
|
+
addressable
|
5
6
|
concurrent-ruby
|
6
7
|
faraday (>= 0.9.0)
|
7
8
|
faraday_middleware
|
@@ -41,7 +42,7 @@ GEM
|
|
41
42
|
activesupport (3.2.22.5)
|
42
43
|
i18n (~> 0.6, >= 0.6.4)
|
43
44
|
multi_json (~> 1.0)
|
44
|
-
addressable (2.5.
|
45
|
+
addressable (2.5.1)
|
45
46
|
public_suffix (~> 2.0, >= 2.0.2)
|
46
47
|
appraisal (2.1.0)
|
47
48
|
bundler
|
@@ -50,7 +51,7 @@ GEM
|
|
50
51
|
arel (3.0.3)
|
51
52
|
builder (3.0.4)
|
52
53
|
byebug (9.0.6)
|
53
|
-
codecov (0.1.
|
54
|
+
codecov (0.1.10)
|
54
55
|
json
|
55
56
|
simplecov
|
56
57
|
url
|
@@ -66,11 +67,11 @@ GEM
|
|
66
67
|
erubis (2.7.0)
|
67
68
|
ethon (0.10.1)
|
68
69
|
ffi (>= 1.3.0)
|
69
|
-
faraday (0.
|
70
|
+
faraday (0.12.0.1)
|
70
71
|
multipart-post (>= 1.2, < 3)
|
71
72
|
faraday_middleware (0.11.0.1)
|
72
73
|
faraday (>= 0.7.4, < 1.0)
|
73
|
-
ffi (1.9.
|
74
|
+
ffi (1.9.18)
|
74
75
|
fork (1.0.1)
|
75
76
|
fork_break (0.1.4)
|
76
77
|
fork (= 1.0.1)
|
@@ -174,12 +175,12 @@ GEM
|
|
174
175
|
ruby_dep (1.5.0)
|
175
176
|
safe_yaml (1.0.4)
|
176
177
|
shellany (0.0.1)
|
177
|
-
sidekiq (4.2.
|
178
|
+
sidekiq (4.2.10)
|
178
179
|
concurrent-ruby (~> 1.0)
|
179
180
|
connection_pool (~> 2.2, >= 2.2.0)
|
180
181
|
rack-protection (>= 1.5.0)
|
181
182
|
redis (~> 3.2, >= 3.2.1)
|
182
|
-
simplecov (0.
|
183
|
+
simplecov (0.14.1)
|
183
184
|
docile (~> 1.1.0)
|
184
185
|
json (>= 1.8, < 3)
|
185
186
|
simplecov-html (~> 0.10.0)
|
@@ -201,7 +202,7 @@ GEM
|
|
201
202
|
polyglot (>= 0.3.1)
|
202
203
|
typhoeus (1.1.2)
|
203
204
|
ethon (>= 0.9.0)
|
204
|
-
tzinfo (0.3.
|
205
|
+
tzinfo (0.3.53)
|
205
206
|
url (0.3.2)
|
206
207
|
vegas (0.1.11)
|
207
208
|
rack (>= 1.0.0)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
routemaster-drain (2.
|
4
|
+
routemaster-drain (2.5.0)
|
5
|
+
addressable
|
5
6
|
concurrent-ruby
|
6
7
|
faraday (>= 0.9.0)
|
7
8
|
faraday_middleware
|
@@ -48,7 +49,7 @@ GEM
|
|
48
49
|
minitest (~> 5.1)
|
49
50
|
thread_safe (~> 0.3, >= 0.3.4)
|
50
51
|
tzinfo (~> 1.1)
|
51
|
-
addressable (2.5.
|
52
|
+
addressable (2.5.1)
|
52
53
|
public_suffix (~> 2.0, >= 2.0.2)
|
53
54
|
appraisal (2.1.0)
|
54
55
|
bundler
|
@@ -57,7 +58,7 @@ GEM
|
|
57
58
|
arel (6.0.4)
|
58
59
|
builder (3.2.3)
|
59
60
|
byebug (9.0.6)
|
60
|
-
codecov (0.1.
|
61
|
+
codecov (0.1.10)
|
61
62
|
json
|
62
63
|
simplecov
|
63
64
|
url
|
@@ -73,11 +74,11 @@ GEM
|
|
73
74
|
erubis (2.7.0)
|
74
75
|
ethon (0.10.1)
|
75
76
|
ffi (>= 1.3.0)
|
76
|
-
faraday (0.
|
77
|
+
faraday (0.12.0.1)
|
77
78
|
multipart-post (>= 1.2, < 3)
|
78
79
|
faraday_middleware (0.11.0.1)
|
79
80
|
faraday (>= 0.7.4, < 1.0)
|
80
|
-
ffi (1.9.
|
81
|
+
ffi (1.9.18)
|
81
82
|
fork (1.0.1)
|
82
83
|
fork_break (0.1.4)
|
83
84
|
fork (= 1.0.1)
|
@@ -121,7 +122,7 @@ GEM
|
|
121
122
|
multi_json (1.12.1)
|
122
123
|
multipart-post (2.0.0)
|
123
124
|
nenv (0.3.0)
|
124
|
-
nokogiri (1.7.
|
125
|
+
nokogiri (1.7.1)
|
125
126
|
mini_portile2 (~> 2.1.0)
|
126
127
|
notiffany (0.1.1)
|
127
128
|
nenv (~> 0.1)
|
@@ -190,12 +191,12 @@ GEM
|
|
190
191
|
ruby_dep (1.5.0)
|
191
192
|
safe_yaml (1.0.4)
|
192
193
|
shellany (0.0.1)
|
193
|
-
sidekiq (4.2.
|
194
|
+
sidekiq (4.2.10)
|
194
195
|
concurrent-ruby (~> 1.0)
|
195
196
|
connection_pool (~> 2.2, >= 2.2.0)
|
196
197
|
rack-protection (>= 1.5.0)
|
197
198
|
redis (~> 3.2, >= 3.2.1)
|
198
|
-
simplecov (0.
|
199
|
+
simplecov (0.14.1)
|
199
200
|
docile (~> 1.1.0)
|
200
201
|
json (>= 1.8, < 3)
|
201
202
|
simplecov-html (~> 0.10.0)
|
@@ -214,10 +215,10 @@ GEM
|
|
214
215
|
sprockets (>= 3.0.0)
|
215
216
|
thor (0.19.4)
|
216
217
|
thread_safe (0.3.6)
|
217
|
-
tilt (2.0.
|
218
|
+
tilt (2.0.7)
|
218
219
|
typhoeus (1.1.2)
|
219
220
|
ethon (>= 0.9.0)
|
220
|
-
tzinfo (1.2.
|
221
|
+
tzinfo (1.2.3)
|
221
222
|
thread_safe (~> 0.1)
|
222
223
|
url (0.3.2)
|
223
224
|
vegas (0.1.11)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
routemaster-drain (2.
|
4
|
+
routemaster-drain (2.5.0)
|
5
|
+
addressable
|
5
6
|
concurrent-ruby
|
6
7
|
faraday (>= 0.9.0)
|
7
8
|
faraday_middleware
|
@@ -14,44 +15,44 @@ PATH
|
|
14
15
|
GEM
|
15
16
|
remote: https://rubygems.org/
|
16
17
|
specs:
|
17
|
-
actioncable (5.0.
|
18
|
-
actionpack (= 5.0.
|
19
|
-
nio4r (
|
18
|
+
actioncable (5.0.2)
|
19
|
+
actionpack (= 5.0.2)
|
20
|
+
nio4r (>= 1.2, < 3.0)
|
20
21
|
websocket-driver (~> 0.6.1)
|
21
|
-
actionmailer (5.0.
|
22
|
-
actionpack (= 5.0.
|
23
|
-
actionview (= 5.0.
|
24
|
-
activejob (= 5.0.
|
22
|
+
actionmailer (5.0.2)
|
23
|
+
actionpack (= 5.0.2)
|
24
|
+
actionview (= 5.0.2)
|
25
|
+
activejob (= 5.0.2)
|
25
26
|
mail (~> 2.5, >= 2.5.4)
|
26
27
|
rails-dom-testing (~> 2.0)
|
27
|
-
actionpack (5.0.
|
28
|
-
actionview (= 5.0.
|
29
|
-
activesupport (= 5.0.
|
28
|
+
actionpack (5.0.2)
|
29
|
+
actionview (= 5.0.2)
|
30
|
+
activesupport (= 5.0.2)
|
30
31
|
rack (~> 2.0)
|
31
32
|
rack-test (~> 0.6.3)
|
32
33
|
rails-dom-testing (~> 2.0)
|
33
34
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
34
|
-
actionview (5.0.
|
35
|
-
activesupport (= 5.0.
|
35
|
+
actionview (5.0.2)
|
36
|
+
activesupport (= 5.0.2)
|
36
37
|
builder (~> 3.1)
|
37
38
|
erubis (~> 2.7.0)
|
38
39
|
rails-dom-testing (~> 2.0)
|
39
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.
|
40
|
-
activejob (5.0.
|
41
|
-
activesupport (= 5.0.
|
40
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
41
|
+
activejob (5.0.2)
|
42
|
+
activesupport (= 5.0.2)
|
42
43
|
globalid (>= 0.3.6)
|
43
|
-
activemodel (5.0.
|
44
|
-
activesupport (= 5.0.
|
45
|
-
activerecord (5.0.
|
46
|
-
activemodel (= 5.0.
|
47
|
-
activesupport (= 5.0.
|
44
|
+
activemodel (5.0.2)
|
45
|
+
activesupport (= 5.0.2)
|
46
|
+
activerecord (5.0.2)
|
47
|
+
activemodel (= 5.0.2)
|
48
|
+
activesupport (= 5.0.2)
|
48
49
|
arel (~> 7.0)
|
49
|
-
activesupport (5.0.
|
50
|
+
activesupport (5.0.2)
|
50
51
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
51
52
|
i18n (~> 0.7)
|
52
53
|
minitest (~> 5.1)
|
53
54
|
tzinfo (~> 1.1)
|
54
|
-
addressable (2.5.
|
55
|
+
addressable (2.5.1)
|
55
56
|
public_suffix (~> 2.0, >= 2.0.2)
|
56
57
|
appraisal (2.1.0)
|
57
58
|
bundler
|
@@ -60,7 +61,7 @@ GEM
|
|
60
61
|
arel (7.1.4)
|
61
62
|
builder (3.2.3)
|
62
63
|
byebug (9.0.6)
|
63
|
-
codecov (0.1.
|
64
|
+
codecov (0.1.10)
|
64
65
|
json
|
65
66
|
simplecov
|
66
67
|
url
|
@@ -76,11 +77,11 @@ GEM
|
|
76
77
|
erubis (2.7.0)
|
77
78
|
ethon (0.10.1)
|
78
79
|
ffi (>= 1.3.0)
|
79
|
-
faraday (0.
|
80
|
+
faraday (0.12.0.1)
|
80
81
|
multipart-post (>= 1.2, < 3)
|
81
82
|
faraday_middleware (0.11.0.1)
|
82
83
|
faraday (>= 0.7.4, < 1.0)
|
83
|
-
ffi (1.9.
|
84
|
+
ffi (1.9.18)
|
84
85
|
fork (1.0.1)
|
85
86
|
fork_break (0.1.4)
|
86
87
|
fork (= 1.0.1)
|
@@ -124,8 +125,8 @@ GEM
|
|
124
125
|
multi_json (1.12.1)
|
125
126
|
multipart-post (2.0.0)
|
126
127
|
nenv (0.3.0)
|
127
|
-
nio4r (
|
128
|
-
nokogiri (1.7.
|
128
|
+
nio4r (2.0.0)
|
129
|
+
nokogiri (1.7.1)
|
129
130
|
mini_portile2 (~> 2.1.0)
|
130
131
|
notiffany (0.1.1)
|
131
132
|
nenv (~> 0.1)
|
@@ -141,26 +142,26 @@ GEM
|
|
141
142
|
rack
|
142
143
|
rack-test (0.6.3)
|
143
144
|
rack (>= 1.0)
|
144
|
-
rails (5.0.
|
145
|
-
actioncable (= 5.0.
|
146
|
-
actionmailer (= 5.0.
|
147
|
-
actionpack (= 5.0.
|
148
|
-
actionview (= 5.0.
|
149
|
-
activejob (= 5.0.
|
150
|
-
activemodel (= 5.0.
|
151
|
-
activerecord (= 5.0.
|
152
|
-
activesupport (= 5.0.
|
145
|
+
rails (5.0.2)
|
146
|
+
actioncable (= 5.0.2)
|
147
|
+
actionmailer (= 5.0.2)
|
148
|
+
actionpack (= 5.0.2)
|
149
|
+
actionview (= 5.0.2)
|
150
|
+
activejob (= 5.0.2)
|
151
|
+
activemodel (= 5.0.2)
|
152
|
+
activerecord (= 5.0.2)
|
153
|
+
activesupport (= 5.0.2)
|
153
154
|
bundler (>= 1.3.0, < 2.0)
|
154
|
-
railties (= 5.0.
|
155
|
+
railties (= 5.0.2)
|
155
156
|
sprockets-rails (>= 2.0.0)
|
156
157
|
rails-dom-testing (2.0.2)
|
157
158
|
activesupport (>= 4.2.0, < 6.0)
|
158
159
|
nokogiri (~> 1.6)
|
159
160
|
rails-html-sanitizer (1.0.3)
|
160
161
|
loofah (~> 2.0)
|
161
|
-
railties (5.0.
|
162
|
-
actionpack (= 5.0.
|
163
|
-
activesupport (= 5.0.
|
162
|
+
railties (5.0.2)
|
163
|
+
actionpack (= 5.0.2)
|
164
|
+
activesupport (= 5.0.2)
|
164
165
|
method_source
|
165
166
|
rake (>= 0.8.7)
|
166
167
|
thor (>= 0.18.1, < 2.0)
|
@@ -193,12 +194,12 @@ GEM
|
|
193
194
|
ruby_dep (1.5.0)
|
194
195
|
safe_yaml (1.0.4)
|
195
196
|
shellany (0.0.1)
|
196
|
-
sidekiq (4.2.
|
197
|
+
sidekiq (4.2.10)
|
197
198
|
concurrent-ruby (~> 1.0)
|
198
199
|
connection_pool (~> 2.2, >= 2.2.0)
|
199
200
|
rack-protection (>= 1.5.0)
|
200
201
|
redis (~> 3.2, >= 3.2.1)
|
201
|
-
simplecov (0.
|
202
|
+
simplecov (0.14.1)
|
202
203
|
docile (~> 1.1.0)
|
203
204
|
json (>= 1.8, < 3)
|
204
205
|
simplecov-html (~> 0.10.0)
|
@@ -217,7 +218,7 @@ GEM
|
|
217
218
|
thread_safe (0.3.6)
|
218
219
|
typhoeus (1.1.2)
|
219
220
|
ethon (>= 0.9.0)
|
220
|
-
tzinfo (1.2.
|
221
|
+
tzinfo (1.2.3)
|
221
222
|
thread_safe (~> 0.1)
|
222
223
|
url (0.3.2)
|
223
224
|
vegas (0.1.11)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'routemaster/middleware/root_post_only'
|
2
|
+
require 'routemaster/middleware/authenticate'
|
3
|
+
require 'routemaster/middleware/parse'
|
4
|
+
require 'routemaster/middleware/expire_cache'
|
5
|
+
require 'routemaster/middleware/payload_filter'
|
6
|
+
require 'routemaster/middleware/filter'
|
7
|
+
require 'routemaster/drain/terminator'
|
8
|
+
require 'rack/builder'
|
9
|
+
require 'delegate'
|
10
|
+
|
11
|
+
module Routemaster
|
12
|
+
module Drain
|
13
|
+
# Rack application which authenticates, parses, filters duplicates in this request
|
14
|
+
# and invalidates the cache for all updated or new items.
|
15
|
+
#
|
16
|
+
# See the various corresponding middleware for details on operation:
|
17
|
+
# {Middleware::RootPostOnly}, {Middleware::Authenticate},
|
18
|
+
# {Middleware::Parse}, {Middleware::ExpireCache} and {Terminator}.
|
19
|
+
class CacheBusting
|
20
|
+
extend Forwardable
|
21
|
+
|
22
|
+
def initialize(options = {})
|
23
|
+
@terminator = terminator = Terminator.new
|
24
|
+
@app = ::Rack::Builder.new do
|
25
|
+
use Middleware::RootPostOnly
|
26
|
+
use Middleware::Authenticate, options
|
27
|
+
use Middleware::Parse
|
28
|
+
use Middleware::Filter, { filter: Routemaster::Middleware::PayloadFilter.new }.merge(options)
|
29
|
+
use Middleware::ExpireCache
|
30
|
+
run terminator
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
delegate :call => :@app
|
35
|
+
delegate [:on, :subscribe] => :@terminator
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'routemaster/middleware/root_post_only'
|
2
2
|
require 'routemaster/middleware/authenticate'
|
3
3
|
require 'routemaster/middleware/parse'
|
4
|
+
require 'routemaster/middleware/siphon'
|
4
5
|
require 'routemaster/middleware/filter'
|
5
6
|
require 'routemaster/middleware/dirty'
|
6
7
|
require 'routemaster/middleware/cache'
|
8
|
+
require 'routemaster/middleware/expire_cache'
|
7
9
|
require 'routemaster/drain/terminator'
|
8
10
|
require 'rack/builder'
|
9
11
|
require 'delegate'
|
@@ -28,6 +30,8 @@ module Routemaster
|
|
28
30
|
use Middleware::RootPostOnly
|
29
31
|
use Middleware::Authenticate, options
|
30
32
|
use Middleware::Parse
|
33
|
+
use Middleware::ExpireCache, options
|
34
|
+
use Middleware::Siphon, options
|
31
35
|
use Middleware::Filter, options
|
32
36
|
use Middleware::Dirty, options
|
33
37
|
use Middleware::Cache, options
|
@@ -40,4 +44,3 @@ module Routemaster
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
43
|
-
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'routemaster/middleware/root_post_only'
|
2
2
|
require 'routemaster/middleware/authenticate'
|
3
3
|
require 'routemaster/middleware/parse'
|
4
|
+
require 'routemaster/middleware/siphon'
|
4
5
|
require 'routemaster/middleware/filter'
|
5
6
|
require 'routemaster/middleware/dirty'
|
6
7
|
require 'routemaster/drain/terminator'
|
@@ -29,6 +30,7 @@ module Routemaster
|
|
29
30
|
use Middleware::RootPostOnly
|
30
31
|
use Middleware::Authenticate, options
|
31
32
|
use Middleware::Parse
|
33
|
+
use Middleware::Siphon, options
|
32
34
|
use Middleware::Filter, options
|
33
35
|
use Middleware::Dirty, options
|
34
36
|
run terminator
|
@@ -40,4 +42,3 @@ module Routemaster
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
end
|
43
|
-
|
data/lib/routemaster/drain.rb
CHANGED
@@ -17,7 +17,7 @@ module Routemaster
|
|
17
17
|
include Wisper::Publisher
|
18
18
|
|
19
19
|
# @param uuid [Enumerable] a set of accepted authentication tokens
|
20
|
-
def initialize(app, uuid: nil)
|
20
|
+
def initialize(app, uuid: nil, **_)
|
21
21
|
@app = app
|
22
22
|
@uuid = uuid || Config.drain_tokens
|
23
23
|
|
@@ -56,4 +56,3 @@ module Routemaster
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
@@ -7,7 +7,7 @@ require 'routemaster/event_index'
|
|
7
7
|
module Routemaster
|
8
8
|
module Middleware
|
9
9
|
class Cache
|
10
|
-
def initialize(app, cache:nil, client:nil, queue:nil)
|
10
|
+
def initialize(app, cache:nil, client:nil, queue:nil, **_)
|
11
11
|
@app = app
|
12
12
|
@cache = cache || Routemaster::Cache.new
|
13
13
|
@client = client || Routemaster::Jobs::Client.new
|
@@ -16,7 +16,6 @@ module Routemaster
|
|
16
16
|
|
17
17
|
def call(env)
|
18
18
|
env.fetch('routemaster.dirty', []).each do |url|
|
19
|
-
@cache.invalidate(url)
|
20
19
|
@client.enqueue(@queue, Routemaster::Jobs::CacheAndSweep, url)
|
21
20
|
end
|
22
21
|
@app.call(env)
|
@@ -11,7 +11,7 @@ module Routemaster
|
|
11
11
|
# The dirty map is passed as `:map` to the constructor and must respond to
|
12
12
|
# `#mark` (like `Routemaster::Dirty::Map`).
|
13
13
|
class Dirty
|
14
|
-
def initialize(app, dirty_map:nil)
|
14
|
+
def initialize(app, dirty_map: nil, **_)
|
15
15
|
@app = app
|
16
16
|
@map = dirty_map || Routemaster::Dirty::Map.new
|
17
17
|
end
|
@@ -28,6 +28,3 @@ module Routemaster
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'routemaster/cache'
|
2
|
+
|
3
|
+
module Routemaster
|
4
|
+
module Middleware
|
5
|
+
class ExpireCache
|
6
|
+
def initialize(app, cache:nil, **_)
|
7
|
+
@app = app
|
8
|
+
@cache = cache || Routemaster::Cache.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env.fetch('routemaster.payload', []).each do |event|
|
13
|
+
next if event['type'] == 'noop'
|
14
|
+
@cache.invalidate(event['url'])
|
15
|
+
end
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -9,7 +9,7 @@ module Routemaster
|
|
9
9
|
class Filter
|
10
10
|
# @param filter [Routemaster::Dirty::Filter] an event filter (optional;
|
11
11
|
# will be created using the `redis` and `expiry` options if not provided)
|
12
|
-
def initialize(app, filter:nil)
|
12
|
+
def initialize(app, filter:nil, **_)
|
13
13
|
@app = app
|
14
14
|
@filter = filter || Routemaster::Dirty::Filter.new
|
15
15
|
end
|
@@ -19,7 +19,7 @@ module Routemaster
|
|
19
19
|
if payload && payload.any?
|
20
20
|
env['routemaster.payload'] = @filter.run(payload)
|
21
21
|
end
|
22
|
-
@app.call(env)
|
22
|
+
@app.call(env)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Routemaster
|
2
|
+
module Middleware
|
3
|
+
class PayloadFilter
|
4
|
+
# Filters duplicate events by url and type in a single payload.
|
5
|
+
def run(payload)
|
6
|
+
payload.group_by { |event| [event['url'], event['type']] }.map { |_, events| events.last }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Routemaster
|
2
|
+
module Middleware
|
3
|
+
# Filters out events based on their topic and passes them to a handling class
|
4
|
+
#
|
5
|
+
# `use Middleware::Siphon, 'some_topic' => SomeTopicHandler`
|
6
|
+
#
|
7
|
+
# Topic handlers are initialized with the full event payload and must respond to `#call`
|
8
|
+
class Siphon
|
9
|
+
def initialize(app, siphon_events: nil)
|
10
|
+
@app = app
|
11
|
+
@processors = siphon_events || {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
siphoned, non_siphoned = env.fetch('routemaster.payload', []).partition do |event|
|
16
|
+
topics_to_siphon.include? event['topic']
|
17
|
+
end
|
18
|
+
siphoned.each do |event|
|
19
|
+
@processors[event['topic']].new(event).call
|
20
|
+
end
|
21
|
+
env['routemaster.payload'] = non_siphoned
|
22
|
+
@app.call(env)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def topics_to_siphon
|
28
|
+
@topics_to_siphon ||= @processors.keys.map(&:to_s)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'addressable/template'
|
2
|
+
|
1
3
|
require 'routemaster/api_client'
|
2
4
|
require 'routemaster/responses/hateoas_enumerable_response'
|
3
5
|
require 'routemaster/responses/hateoas_response'
|
@@ -5,40 +7,48 @@ require 'routemaster/responses/hateoas_response'
|
|
5
7
|
module Routemaster
|
6
8
|
module Resources
|
7
9
|
class RestResource
|
8
|
-
attr_reader :url
|
9
|
-
|
10
10
|
def initialize(url, client: nil)
|
11
|
-
@
|
11
|
+
@url_template = Addressable::Template.new(url)
|
12
12
|
@client = client || Routemaster::APIClient.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def create(params)
|
16
16
|
@client.with_response(Responses::HateoasResponse) do
|
17
|
-
@client.post(
|
17
|
+
@client.post(expanded_url, body: params)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
def show(id=nil, enable_caching: true)
|
22
22
|
@client.with_response(Responses::HateoasResponse) do
|
23
|
-
@client.get(
|
23
|
+
@client.get(expanded_url(id: id), options: { enable_caching: enable_caching })
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
def index(params: {}, filters: {}, enable_caching: false)
|
28
28
|
@client.with_response(Responses::HateoasEnumerableResponse) do
|
29
|
-
@client.get(
|
29
|
+
@client.get(expanded_url, params: params.merge(filters), options: { enable_caching: enable_caching })
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def update(id=nil, params)
|
34
34
|
@client.with_response(Responses::HateoasResponse) do
|
35
|
-
@client.patch(
|
35
|
+
@client.patch(expanded_url(id: id), body: params)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def destroy(id=nil)
|
40
40
|
# no response wrapping as DELETE is supposed to 204.
|
41
|
-
@client.delete(
|
41
|
+
@client.delete(expanded_url(id: id))
|
42
|
+
end
|
43
|
+
|
44
|
+
def url
|
45
|
+
@url_template.pattern
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def expanded_url(**params)
|
51
|
+
@url_template.expand(params).to_s
|
42
52
|
end
|
43
53
|
end
|
44
54
|
end
|
data/routemaster-drain.gemspec
CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^spec/})
|
17
17
|
spec.require_paths = %w(lib)
|
18
18
|
|
19
|
+
spec.add_runtime_dependency 'addressable'
|
19
20
|
spec.add_runtime_dependency 'faraday', '>= 0.9.0'
|
20
21
|
spec.add_runtime_dependency 'faraday_middleware'
|
21
22
|
spec.add_runtime_dependency 'typhoeus', '~> 1.1'
|
@@ -111,12 +111,7 @@ describe Routemaster::APIClient do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
let(:callback){
|
114
|
-
subject.on_success
|
115
|
-
callback_spy.success
|
116
|
-
end
|
117
|
-
subject.on_error do
|
118
|
-
callback_spy.error
|
119
|
-
end
|
114
|
+
subject.on_success { callback_spy.success }.zip(subject.on_error { callback_spy.error })
|
120
115
|
}
|
121
116
|
|
122
117
|
context "when successful" do
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec/support/rack_test'
|
3
|
+
require 'spec/support/uses_redis'
|
4
|
+
require 'spec/support/uses_dotenv'
|
5
|
+
require 'spec/support/events'
|
6
|
+
require 'routemaster/drain/cache_busting'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
describe Routemaster::Drain::CacheBusting do
|
10
|
+
uses_dotenv
|
11
|
+
uses_redis
|
12
|
+
|
13
|
+
let(:app) { described_class.new }
|
14
|
+
let(:listener) { double 'listener' }
|
15
|
+
|
16
|
+
before { app.subscribe(listener, prefix: true) }
|
17
|
+
|
18
|
+
let(:path) { '/' }
|
19
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }.to_json }
|
20
|
+
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
21
|
+
let(:perform) { post path, payload, environment }
|
22
|
+
|
23
|
+
before { authorize 'd3m0', 'x' }
|
24
|
+
|
25
|
+
it 'succeeds' do
|
26
|
+
perform
|
27
|
+
expect(last_response.status).to eq(204)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'emits events' do
|
31
|
+
expect(listener).to receive(:on_events_received) do |payload|
|
32
|
+
expect(payload.size).to eq(3)
|
33
|
+
end
|
34
|
+
perform
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'increments the event index' do
|
38
|
+
ei_double = double(increment: 1)
|
39
|
+
allow(Routemaster::EventIndex).to receive(:new).and_return(ei_double)
|
40
|
+
expect(ei_double).to receive(:increment).exactly(3).times
|
41
|
+
perform
|
42
|
+
end
|
43
|
+
end
|
@@ -3,25 +3,31 @@ require 'spec/support/rack_test'
|
|
3
3
|
require 'spec/support/uses_redis'
|
4
4
|
require 'spec/support/uses_dotenv'
|
5
5
|
require 'spec/support/events'
|
6
|
+
require 'spec/support/siphon'
|
7
|
+
|
6
8
|
require 'routemaster/drain/caching'
|
9
|
+
|
7
10
|
require 'json'
|
8
11
|
|
9
12
|
describe Routemaster::Drain::Caching do
|
10
13
|
uses_dotenv
|
11
14
|
uses_redis
|
12
15
|
|
13
|
-
let(:app) { described_class.new }
|
16
|
+
let(:app) { described_class.new options}
|
14
17
|
let(:listener) { double 'listener' }
|
18
|
+
let(:options) { {} }
|
15
19
|
|
16
20
|
before { app.subscribe(listener, prefix: true) }
|
17
21
|
|
18
22
|
let(:path) { '/' }
|
19
|
-
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }
|
23
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) } }
|
20
24
|
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
21
|
-
let(:perform) { post path, payload, environment }
|
25
|
+
let(:perform) { post path, payload.to_json, environment }
|
22
26
|
|
23
27
|
before { authorize 'd3m0', 'x' }
|
24
28
|
|
29
|
+
include_examples 'supports siphon'
|
30
|
+
|
25
31
|
it 'succeeds' do
|
26
32
|
perform
|
27
33
|
expect(last_response.status).to eq(204)
|
@@ -37,7 +43,7 @@ describe Routemaster::Drain::Caching do
|
|
37
43
|
it 'increments the event index' do
|
38
44
|
ei_double = double(increment: 1)
|
39
45
|
allow(Routemaster::EventIndex).to receive(:new).and_return(ei_double)
|
40
|
-
expect(ei_double).to receive(:increment).exactly(
|
46
|
+
expect(ei_double).to receive(:increment).exactly(4).times
|
41
47
|
perform
|
42
48
|
end
|
43
49
|
|
@@ -3,6 +3,7 @@ require 'spec/support/rack_test'
|
|
3
3
|
require 'spec/support/uses_redis'
|
4
4
|
require 'spec/support/uses_dotenv'
|
5
5
|
require 'spec/support/events'
|
6
|
+
require 'spec/support/siphon'
|
6
7
|
require 'routemaster/drain/mapping'
|
7
8
|
require 'json'
|
8
9
|
|
@@ -10,18 +11,21 @@ describe Routemaster::Drain::Mapping do
|
|
10
11
|
uses_dotenv
|
11
12
|
uses_redis
|
12
13
|
|
13
|
-
let(:app) { described_class.new }
|
14
|
+
let(:app) { described_class.new(options) }
|
15
|
+
let(:options) { {} }
|
14
16
|
let(:listener) { double 'listener' }
|
15
|
-
|
17
|
+
|
16
18
|
before { app.subscribe(listener, prefix: true) }
|
17
19
|
|
18
20
|
let(:path) { '/' }
|
19
|
-
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }
|
21
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) } }
|
20
22
|
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
21
|
-
let(:perform) { post path, payload, environment }
|
23
|
+
let(:perform) { post path, payload.to_json, environment }
|
22
24
|
|
23
25
|
before { authorize 'd3m0', 'x' }
|
24
26
|
|
27
|
+
include_examples 'supports siphon'
|
28
|
+
|
25
29
|
it 'succeeds' do
|
26
30
|
perform
|
27
31
|
expect(last_response.status).to eq(204)
|
@@ -35,11 +39,11 @@ describe Routemaster::Drain::Mapping do
|
|
35
39
|
end
|
36
40
|
|
37
41
|
let(:map) { Routemaster::Dirty::Map.new }
|
38
|
-
|
42
|
+
|
39
43
|
it 'uses dirty map' do
|
40
44
|
payload1 = [1,2,3,1].map { |idx| make_event(idx) }.to_json
|
41
45
|
payload2 = [1,4,5,2].map { |idx| make_event(idx) }.to_json
|
42
|
-
|
46
|
+
|
43
47
|
post path, payload1, environment
|
44
48
|
expect(map.count).to eq(3)
|
45
49
|
map.sweep_one("https://example.com/stuff/1") { true }
|
@@ -48,4 +52,3 @@ describe Routemaster::Drain::Mapping do
|
|
48
52
|
expect(map.count).to eq(4) # 2, 3, 4, 5 (1 is a repeat event, filtered out)
|
49
53
|
end
|
50
54
|
end
|
51
|
-
|
@@ -19,11 +19,6 @@ RSpec.describe Routemaster::Middleware::Cache do
|
|
19
19
|
describe '#call' do
|
20
20
|
let(:payload) { ['https://example.com/1'] }
|
21
21
|
|
22
|
-
it 'increments the event_index' do
|
23
|
-
expect(cache).to receive(:invalidate)
|
24
|
-
perform
|
25
|
-
end
|
26
|
-
|
27
22
|
it 'queues a fetch job' do
|
28
23
|
expect(client).to receive(:enqueue).with('routemaster', Routemaster::Jobs::CacheAndSweep, 'https://example.com/1')
|
29
24
|
perform
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec/support/rack_test'
|
3
|
+
require 'spec/support/events'
|
4
|
+
require 'routemaster/middleware/siphon'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
describe Routemaster::Middleware::Siphon do
|
8
|
+
let(:terminator) { ErrorRackApp.new }
|
9
|
+
let(:app) { described_class.new(terminator, options) }
|
10
|
+
|
11
|
+
let(:perform) do
|
12
|
+
post '/whatever', '', 'routemaster.payload' => payload
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#call' do
|
16
|
+
|
17
|
+
let(:options) { { filter:filter } }
|
18
|
+
let(:payload) { [ make_event(1), make_event(1).merge({'topic' => 'notstuff'})] }
|
19
|
+
|
20
|
+
context "if no siphon is defined" do
|
21
|
+
let(:options) { {} }
|
22
|
+
|
23
|
+
it "passes all to the terminator" do
|
24
|
+
perform
|
25
|
+
expect(terminator.last_env['routemaster.payload']).to eq payload
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "if a 'stuff' siphon is defined" do
|
30
|
+
let(:siphon_double) { double(new: siphon_instance) }
|
31
|
+
let(:siphon_instance) { double(call: nil) }
|
32
|
+
let(:options) { { siphon_events: { 'stuff' => siphon_double } } }
|
33
|
+
|
34
|
+
it "calls the siphon with the event" do
|
35
|
+
perform
|
36
|
+
expect(siphon_double).to have_received(:new).with(payload[0])
|
37
|
+
expect(siphon_instance).to have_received(:call)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "passes 'notstuff' to the terminator" do
|
41
|
+
perform
|
42
|
+
expect(terminator.last_env['routemaster.payload']).to eq [payload[1]]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -4,46 +4,55 @@ require 'routemaster/resources/rest_resource'
|
|
4
4
|
module Routemaster
|
5
5
|
module Resources
|
6
6
|
RSpec.describe RestResource do
|
7
|
-
let(:url) { 'test_url' }
|
8
7
|
let(:client) { double('Client') }
|
9
8
|
let(:params) { {} }
|
10
9
|
|
11
|
-
subject { described_class.new(url, client: client) }
|
12
|
-
|
13
10
|
before { allow(client).to receive(:with_response).and_yield }
|
14
11
|
|
15
|
-
describe
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
describe "singular resource" do
|
13
|
+
let(:url) { '/resources/1' }
|
14
|
+
|
15
|
+
subject { described_class.new('/resources/{id}', client: client) }
|
16
|
+
|
17
|
+
describe '#show' do
|
18
|
+
it 'gets to the given url' do
|
19
|
+
expect(client).to receive(:get).with(url, options: { enable_caching: true })
|
20
|
+
subject.show(1)
|
21
|
+
end
|
19
22
|
end
|
20
|
-
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
describe '#update' do
|
25
|
+
it 'updates the given resource' do
|
26
|
+
expect(client).to receive(:patch).with(url, body: params)
|
27
|
+
subject.update(1, params)
|
28
|
+
end
|
26
29
|
end
|
27
|
-
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
describe '#destroy' do
|
32
|
+
it 'destroys the given resource' do
|
33
|
+
expect(client).to receive(:delete).with(url)
|
34
|
+
subject.destroy(1)
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
|
-
describe
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
describe "collection resource" do
|
40
|
+
let(:url) { '/resources' }
|
41
|
+
|
42
|
+
subject { described_class.new('/resources{?page,per_page}', client: client) }
|
43
|
+
|
44
|
+
describe '#create' do
|
45
|
+
it 'posts to the given url' do
|
46
|
+
expect(client).to receive(:post).with(url, body: params)
|
47
|
+
subject.create(params)
|
48
|
+
end
|
40
49
|
end
|
41
|
-
end
|
42
50
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
describe '#index' do
|
52
|
+
it 'gets to the given url' do
|
53
|
+
expect(client).to receive(:get).with(url, params: {}, options: { enable_caching: false })
|
54
|
+
subject.index
|
55
|
+
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
RSpec.shared_examples 'supports siphon' do
|
2
|
+
context "if a siphon is defined" do
|
3
|
+
let(:siphon_double) { double(new: siphon_instance) }
|
4
|
+
let(:siphon_instance) { double(call: nil) }
|
5
|
+
let(:options){ { siphon_events: { payload[0]['topic'] => siphon_double } } }
|
6
|
+
|
7
|
+
it "calls the siphon with the event" do
|
8
|
+
perform
|
9
|
+
expect(siphon_double).to have_received(:new).with(payload[0]).at_least(:once)
|
10
|
+
expect(siphon_instance).to have_received(:call).at_least(:once)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: routemaster-drain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Letessier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: faraday
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +178,7 @@ files:
|
|
164
178
|
- lib/routemaster/dirty/state.rb
|
165
179
|
- lib/routemaster/drain.rb
|
166
180
|
- lib/routemaster/drain/basic.rb
|
181
|
+
- lib/routemaster/drain/cache_busting.rb
|
167
182
|
- lib/routemaster/drain/caching.rb
|
168
183
|
- lib/routemaster/drain/mapping.rb
|
169
184
|
- lib/routemaster/drain/terminator.rb
|
@@ -180,11 +195,14 @@ files:
|
|
180
195
|
- lib/routemaster/middleware/cache.rb
|
181
196
|
- lib/routemaster/middleware/dirty.rb
|
182
197
|
- lib/routemaster/middleware/error_handling.rb
|
198
|
+
- lib/routemaster/middleware/expire_cache.rb
|
183
199
|
- lib/routemaster/middleware/filter.rb
|
184
200
|
- lib/routemaster/middleware/metrics.rb
|
185
201
|
- lib/routemaster/middleware/parse.rb
|
202
|
+
- lib/routemaster/middleware/payload_filter.rb
|
186
203
|
- lib/routemaster/middleware/response_caching.rb
|
187
204
|
- lib/routemaster/middleware/root_post_only.rb
|
205
|
+
- lib/routemaster/middleware/siphon.rb
|
188
206
|
- lib/routemaster/null_logger.rb
|
189
207
|
- lib/routemaster/redis_broker.rb
|
190
208
|
- lib/routemaster/resources/rest_resource.rb
|
@@ -198,6 +216,7 @@ files:
|
|
198
216
|
- spec/routemaster/dirty/map_spec.rb
|
199
217
|
- spec/routemaster/dirty/state_spec.rb
|
200
218
|
- spec/routemaster/drain/basic_spec.rb
|
219
|
+
- spec/routemaster/drain/cache_busting_spec.rb
|
201
220
|
- spec/routemaster/drain/caching_spec.rb
|
202
221
|
- spec/routemaster/drain/mapping_spec.rb
|
203
222
|
- spec/routemaster/drain/terminator_spec.rb
|
@@ -214,6 +233,7 @@ files:
|
|
214
233
|
- spec/routemaster/middleware/filter_spec.rb
|
215
234
|
- spec/routemaster/middleware/parse_spec.rb
|
216
235
|
- spec/routemaster/middleware/root_post_only_spec.rb
|
236
|
+
- spec/routemaster/middleware/siphon_spec.rb
|
217
237
|
- spec/routemaster/redis_broker_spec.rb
|
218
238
|
- spec/routemaster/resources/rest_resource_spec.rb
|
219
239
|
- spec/routemaster/responses/hateoas_enumerable_response_spec.rb
|
@@ -224,6 +244,7 @@ files:
|
|
224
244
|
- spec/support/events.rb
|
225
245
|
- spec/support/rack_test.rb
|
226
246
|
- spec/support/server.rb
|
247
|
+
- spec/support/siphon.rb
|
227
248
|
- spec/support/uses_dotenv.rb
|
228
249
|
- spec/support/uses_redis.rb
|
229
250
|
- spec/support/uses_webmock.rb
|
@@ -258,6 +279,7 @@ test_files:
|
|
258
279
|
- spec/routemaster/dirty/map_spec.rb
|
259
280
|
- spec/routemaster/dirty/state_spec.rb
|
260
281
|
- spec/routemaster/drain/basic_spec.rb
|
282
|
+
- spec/routemaster/drain/cache_busting_spec.rb
|
261
283
|
- spec/routemaster/drain/caching_spec.rb
|
262
284
|
- spec/routemaster/drain/mapping_spec.rb
|
263
285
|
- spec/routemaster/drain/terminator_spec.rb
|
@@ -274,6 +296,7 @@ test_files:
|
|
274
296
|
- spec/routemaster/middleware/filter_spec.rb
|
275
297
|
- spec/routemaster/middleware/parse_spec.rb
|
276
298
|
- spec/routemaster/middleware/root_post_only_spec.rb
|
299
|
+
- spec/routemaster/middleware/siphon_spec.rb
|
277
300
|
- spec/routemaster/redis_broker_spec.rb
|
278
301
|
- spec/routemaster/resources/rest_resource_spec.rb
|
279
302
|
- spec/routemaster/responses/hateoas_enumerable_response_spec.rb
|
@@ -284,6 +307,7 @@ test_files:
|
|
284
307
|
- spec/support/events.rb
|
285
308
|
- spec/support/rack_test.rb
|
286
309
|
- spec/support/server.rb
|
310
|
+
- spec/support/siphon.rb
|
287
311
|
- spec/support/uses_dotenv.rb
|
288
312
|
- spec/support/uses_redis.rb
|
289
313
|
- spec/support/uses_webmock.rb
|