alephant-broker 3.10.2 → 3.11.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/alephant-broker.gemspec +1 -0
- data/lib/alephant/broker/environment.rb +6 -6
- data/lib/alephant/broker/request/batch.rb +22 -9
- data/lib/alephant/broker/request/factory.rb +4 -4
- data/lib/alephant/broker/response/base.rb +2 -1
- data/lib/alephant/broker/version.rb +1 -1
- data/spec/integration/rack_spec.rb +129 -4
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58251bb948e3620c95b0c67e8643e60426c25818
|
4
|
+
data.tar.gz: c355b17fe2d366043fbd84f5e284377f9d353a44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbdaf0f97e7c873b030be8418d6b7b7a076826fcd576d7f60b9c5f734f4ac8a13db6af1cb4744b222b48ee01abd267c6df051f22fac85dd8285b53b36128ce2c
|
7
|
+
data.tar.gz: a143fb0fbca1a39ab62a1a7facd718f9f38221a53daae7514ca82d1f9b7a42b3992ba06f8b427da717a919a50801f9877bb56d7c4b34e7adeae69702c5d63fde
|
data/alephant-broker.gemspec
CHANGED
@@ -13,23 +13,23 @@ module Alephant
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def method
|
16
|
-
settings[
|
16
|
+
settings["REQUEST_METHOD"]
|
17
17
|
end
|
18
18
|
|
19
19
|
def post?
|
20
|
-
settings[
|
20
|
+
settings["REQUEST_METHOD"] == "POST"
|
21
21
|
end
|
22
22
|
|
23
23
|
def get?
|
24
|
-
settings[
|
24
|
+
settings["REQUEST_METHOD"] == "GET"
|
25
25
|
end
|
26
26
|
|
27
27
|
def query
|
28
|
-
settings[
|
28
|
+
settings["QUERY_STRING"] || ""
|
29
29
|
end
|
30
30
|
|
31
31
|
def path
|
32
|
-
settings[
|
32
|
+
settings["PATH_INFO"]
|
33
33
|
end
|
34
34
|
|
35
35
|
def if_none_match
|
@@ -51,7 +51,7 @@ module Alephant
|
|
51
51
|
private
|
52
52
|
|
53
53
|
def rack_input
|
54
|
-
(settings[
|
54
|
+
(settings["rack.input"].read).tap { settings["rack.input"].rewind }
|
55
55
|
end
|
56
56
|
|
57
57
|
def parse(json)
|
@@ -10,24 +10,37 @@ module Alephant
|
|
10
10
|
attr_reader :batch_id, :components, :load_strategy
|
11
11
|
|
12
12
|
def initialize(component_factory, env)
|
13
|
-
|
13
|
+
if env.data
|
14
|
+
@batch_id = env.data["batch_id"]
|
15
|
+
else
|
16
|
+
@batch_id = env.options.fetch("batch_id", nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
logger.info "Request::Batch#initialize: id: #{batch_id}"
|
14
20
|
|
15
|
-
@batch_id = env.data["batch_id"] if env.data
|
16
21
|
@component_factory = component_factory
|
17
|
-
|
22
|
+
|
23
|
+
@components = env.post? ? components_post(env) : components_get(env)
|
18
24
|
end
|
19
25
|
|
20
26
|
private
|
21
27
|
|
22
|
-
def
|
28
|
+
def components_post(env)
|
23
29
|
((env.data || {}).fetch("components", []) || []).map do |c|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
create_component(c["component"], batch_id, c["options"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def components_get(env)
|
35
|
+
(env.options.fetch("components", []) || []).map do |c|
|
36
|
+
options = c[1].fetch("options", {}) || {}
|
37
|
+
create_component(c[1]["component"], batch_id, options)
|
29
38
|
end
|
30
39
|
end
|
40
|
+
|
41
|
+
def create_component(component, batch_id, options)
|
42
|
+
@component_factory.create(component, batch_id, options)
|
43
|
+
end
|
31
44
|
end
|
32
45
|
end
|
33
46
|
end
|
@@ -6,18 +6,18 @@ module Alephant
|
|
6
6
|
module Request
|
7
7
|
class Factory
|
8
8
|
def self.request_type_from(env)
|
9
|
-
env.path.split(
|
9
|
+
env.path.split("/")[1]
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.request_for(load_strategy, env)
|
13
13
|
component_factory = ComponentFactory.new load_strategy
|
14
14
|
|
15
15
|
case request_type_from(env)
|
16
|
-
when
|
16
|
+
when "component"
|
17
17
|
Asset.new(component_factory, env)
|
18
|
-
when
|
18
|
+
when "components"
|
19
19
|
Batch.new(component_factory, env)
|
20
|
-
when
|
20
|
+
when "status"
|
21
21
|
Status.new
|
22
22
|
else
|
23
23
|
NotFound.new
|
@@ -12,7 +12,7 @@ module Alephant
|
|
12
12
|
|
13
13
|
attr_reader :content, :headers, :status
|
14
14
|
|
15
|
-
NOT_MODIFIED_STATUS_CODE =
|
15
|
+
NOT_MODIFIED_STATUS_CODE = 304
|
16
16
|
|
17
17
|
STATUS_CODE_MAPPING = {
|
18
18
|
200 => "ok",
|
@@ -62,6 +62,7 @@ module Alephant
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def self.component_not_modified(headers, request_env)
|
65
|
+
return false if request_env.post?
|
65
66
|
return false if request_env.if_modified_since.nil? && request_env.if_none_match.nil?
|
66
67
|
|
67
68
|
last_modified_match = !request_env.if_modified_since.nil? && headers["Last-Modified"] == request_env.if_modified_since
|
@@ -117,7 +117,7 @@ describe Alephant::Broker::Application do
|
|
117
117
|
specify { expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT") }
|
118
118
|
end
|
119
119
|
|
120
|
-
describe "Components endpoint '/components'" do
|
120
|
+
describe "Components endpoint '/components' POST" do
|
121
121
|
let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
|
122
122
|
let(:batch_json) do
|
123
123
|
IO.read("#{fixture_path}/batch.json").strip
|
@@ -169,7 +169,7 @@ describe Alephant::Broker::Application do
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
-
describe "Components unmodified '/components' response" do
|
172
|
+
describe "Components POST unmodified '/components' response" do
|
173
173
|
let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
|
174
174
|
let(:batch_json) { IO.read("#{fixture_path}/batch.json").strip }
|
175
175
|
let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
|
@@ -216,8 +216,8 @@ describe Alephant::Broker::Application do
|
|
216
216
|
"HTTP_IF_NONE_MATCH" => etag)
|
217
217
|
end
|
218
218
|
|
219
|
-
specify { expect(last_response.status).to eql
|
220
|
-
specify { expect(last_response.body).to eq
|
219
|
+
specify { expect(last_response.status).to eql 200 }
|
220
|
+
specify { expect(last_response.body).to eq batch_compiled_json }
|
221
221
|
|
222
222
|
describe "response should have headers" do
|
223
223
|
it "should have a Content-Type header" do
|
@@ -241,6 +241,131 @@ describe Alephant::Broker::Application do
|
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
244
|
+
describe "Components endpoint '/components' GET" do
|
245
|
+
let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
|
246
|
+
let(:batch_compiled_json) do
|
247
|
+
IO.read("#{fixture_path}/batch_compiled.json").strip
|
248
|
+
end
|
249
|
+
let(:s3_double_batch) { instance_double("Alephant::Storage") }
|
250
|
+
|
251
|
+
before do
|
252
|
+
allow(s3_double_batch).to receive(:get).and_return(
|
253
|
+
content,
|
254
|
+
AWS::Core::Data.new(
|
255
|
+
:content_type => "test/content",
|
256
|
+
:content => "Test",
|
257
|
+
:meta => {
|
258
|
+
:head_ETag => "\"abc\"",
|
259
|
+
:"head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
|
260
|
+
}
|
261
|
+
)
|
262
|
+
)
|
263
|
+
|
264
|
+
allow(Alephant::Storage).to receive(:new) { s3_double_batch }
|
265
|
+
end
|
266
|
+
|
267
|
+
context "when using valid batch asset data" do
|
268
|
+
let(:path) { "/components/batch?batch_id=baz&components[ni_council_results_table][component]=ni_council_results_table&components[ni_council_results_table][options][foo]=bar&components[ni_council_results_table_no_options][component]=ni_council_results_table" }
|
269
|
+
let(:content_type) { "application/json" }
|
270
|
+
|
271
|
+
before { get path, {}, "CONTENT_TYPE" => content_type }
|
272
|
+
|
273
|
+
specify { expect(last_response.status).to eql 200 }
|
274
|
+
specify { expect(last_response.body).to eq batch_compiled_json }
|
275
|
+
|
276
|
+
describe "response should have headers" do
|
277
|
+
it "should have content headers" do
|
278
|
+
expect(last_response.headers["Content-Type"]).to eq("application/json")
|
279
|
+
expect(last_response.headers["Content-Length"]).to eq("266")
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should have ETag cache header" do
|
283
|
+
expect(last_response.headers["ETag"]).to eq('"34774567db979628363e6e865127623f"')
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should have most recent Last-Modified header" do
|
287
|
+
expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "Components GET unmodified '/components' response" do
|
294
|
+
let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
|
295
|
+
let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
|
296
|
+
let(:s3_double_with_etag) { instance_double("Alephant::Storage") }
|
297
|
+
let(:lookup_location_double_for_options_request) do
|
298
|
+
instance_double("Alephant::Lookup::Location", :location => "test/location/with/options")
|
299
|
+
end
|
300
|
+
|
301
|
+
before do
|
302
|
+
allow(lookup_helper_double).to receive(:read)
|
303
|
+
.with("ni_council_results_table", { :foo => "bar" }, "111")
|
304
|
+
.and_return(lookup_location_double_for_options_request)
|
305
|
+
|
306
|
+
allow(s3_double_with_etag).to receive(:get)
|
307
|
+
.with("test/location")
|
308
|
+
.and_return(
|
309
|
+
content
|
310
|
+
)
|
311
|
+
|
312
|
+
allow(s3_double_with_etag).to receive(:get)
|
313
|
+
.with("test/location/with/options")
|
314
|
+
.and_return(
|
315
|
+
AWS::Core::Data.new(
|
316
|
+
:content_type => "test/content",
|
317
|
+
:content => "Test",
|
318
|
+
:meta => {
|
319
|
+
"head_ETag" => "abc",
|
320
|
+
"head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
|
321
|
+
}
|
322
|
+
)
|
323
|
+
)
|
324
|
+
|
325
|
+
allow(Alephant::Storage).to receive(:new) { s3_double_with_etag }
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when requesting an unmodified response with GET" do
|
329
|
+
let(:path) { "/components/batch?batch_id=baz&components[ni_council_results_table][component]=ni_council_results_table&components[ni_council_results_table][options][foo]=bar&components[ni_council_results_table_no_options][component]=ni_council_results_table" }
|
330
|
+
let(:content_type) { "application/json" }
|
331
|
+
let(:etag) { '"34774567db979628363e6e865127623f"' }
|
332
|
+
|
333
|
+
before do
|
334
|
+
get(
|
335
|
+
path,
|
336
|
+
{},
|
337
|
+
{
|
338
|
+
"CONTENT_TYPE" => content_type,
|
339
|
+
"HTTP_IF_NONE_MATCH" => etag
|
340
|
+
}
|
341
|
+
)
|
342
|
+
end
|
343
|
+
|
344
|
+
specify { expect(last_response.status).to eql not_modified_status_code }
|
345
|
+
specify { expect(last_response.body).to eq "" }
|
346
|
+
|
347
|
+
describe "response should have headers" do
|
348
|
+
it "should not have a Content-Type header" do
|
349
|
+
expect(last_response.headers).to_not include("Content-Type")
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should have ETag cache header" do
|
353
|
+
expect(last_response.headers["ETag"]).to eq(etag)
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should have most recent Last-Modified header" do
|
357
|
+
expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
|
358
|
+
end
|
359
|
+
|
360
|
+
it "shoud not have no cache headers" do
|
361
|
+
expect(last_response.headers).to_not include("Cache-Control")
|
362
|
+
expect(last_response.headers).to_not include("Pragma")
|
363
|
+
expect(last_response.headers).to_not include("Expires")
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
244
369
|
describe "S3 headers" do
|
245
370
|
let(:content) do
|
246
371
|
AWS::Core::Data.new(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alephant-broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- BBC News
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -262,6 +262,20 @@ dependencies:
|
|
262
262
|
- - '>='
|
263
263
|
- !ruby/object:Gem::Version
|
264
264
|
version: '0'
|
265
|
+
- !ruby/object:Gem::Dependency
|
266
|
+
requirement: !ruby/object:Gem::Requirement
|
267
|
+
requirements:
|
268
|
+
- - ~>
|
269
|
+
- !ruby/object:Gem::Version
|
270
|
+
version: 3.0.0
|
271
|
+
name: listen
|
272
|
+
prerelease: false
|
273
|
+
type: :runtime
|
274
|
+
version_requirements: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - ~>
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: 3.0.0
|
265
279
|
description: Brokers requests for alephant components
|
266
280
|
email:
|
267
281
|
- FutureMediaNewsRubyGems@bbc.co.uk
|