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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 223acfc17ab349160c5dbf9597213a35b9cdc33a
4
- data.tar.gz: abb1103b13b95e494096b531ad8c109d2c965bdc
3
+ metadata.gz: 58251bb948e3620c95b0c67e8643e60426c25818
4
+ data.tar.gz: c355b17fe2d366043fbd84f5e284377f9d353a44
5
5
  SHA512:
6
- metadata.gz: ec8f97f5911fef1ca5d4bfee7694fee0c9173d4c2275dec58ae3d2161b0d6b19ccf6faee403d00beaa54c7bcaec8dcbeaa80a584d0f45da1e05e0277a6856d28
7
- data.tar.gz: 89841c9e7fa8bcc92e2d20da30834e0b63d80f8cca322a0e65b1ad0455390dba3161a61d5ac03ab7d585968b5b693f34ac1be6d3294cfa135359f968be608867
6
+ metadata.gz: dbdaf0f97e7c873b030be8418d6b7b7a076826fcd576d7f60b9c5f734f4ac8a13db6af1cb4744b222b48ee01abd267c6df051f22fac85dd8285b53b36128ce2c
7
+ data.tar.gz: a143fb0fbca1a39ab62a1a7facd718f9f38221a53daae7514ca82d1f9b7a42b3992ba06f8b427da717a919a50801f9877bb56d7c4b34e7adeae69702c5d63fde
@@ -38,4 +38,5 @@ Gem::Specification.new do |spec|
38
38
  spec.add_runtime_dependency "dalli-elasticache"
39
39
  spec.add_runtime_dependency "faraday"
40
40
  spec.add_runtime_dependency "crimp"
41
+ spec.add_runtime_dependency "listen", "~> 3.0.0"
41
42
  end
@@ -13,23 +13,23 @@ module Alephant
13
13
  end
14
14
 
15
15
  def method
16
- settings['REQUEST_METHOD']
16
+ settings["REQUEST_METHOD"]
17
17
  end
18
18
 
19
19
  def post?
20
- settings['REQUEST_METHOD'] == 'POST'
20
+ settings["REQUEST_METHOD"] == "POST"
21
21
  end
22
22
 
23
23
  def get?
24
- settings['REQUEST_METHOD'] == 'GET'
24
+ settings["REQUEST_METHOD"] == "GET"
25
25
  end
26
26
 
27
27
  def query
28
- settings['QUERY_STRING'] || ""
28
+ settings["QUERY_STRING"] || ""
29
29
  end
30
30
 
31
31
  def path
32
- settings['PATH_INFO']
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['rack.input'].read).tap { settings['rack.input'].rewind }
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
- logger.info "Request::Batch#initialize: id: #{env.data['batch_id']}" if env.data
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
- @components = components_for env
22
+
23
+ @components = env.post? ? components_post(env) : components_get(env)
18
24
  end
19
25
 
20
26
  private
21
27
 
22
- def components_for(env)
28
+ def components_post(env)
23
29
  ((env.data || {}).fetch("components", []) || []).map do |c|
24
- @component_factory.create(
25
- c["component"],
26
- batch_id,
27
- c["options"]
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('/')[1]
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 'component'
16
+ when "component"
17
17
  Asset.new(component_factory, env)
18
- when 'components'
18
+ when "components"
19
19
  Batch.new(component_factory, env)
20
- when 'status'
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 = 202
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
@@ -1,5 +1,5 @@
1
1
  module Alephant
2
2
  module Broker
3
- VERSION = "3.10.2"
3
+ VERSION = "3.11.0"
4
4
  end
5
5
  end
@@ -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 not_modified_status_code }
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.10.2
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-22 00:00:00.000000000 Z
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