alephant-broker 0.1.6 → 1.0.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/alephant/broker.rb +40 -5
  3. data/lib/alephant/broker/component.rb +74 -0
  4. data/lib/alephant/broker/{call_environment.rb → environment.rb} +11 -7
  5. data/lib/alephant/broker/request.rb +13 -0
  6. data/lib/alephant/broker/request/asset.rb +37 -0
  7. data/lib/alephant/broker/request/batch.rb +38 -0
  8. data/lib/alephant/broker/request/factory.rb +24 -0
  9. data/lib/alephant/broker/request/handler.rb +35 -0
  10. data/lib/alephant/broker/response.rb +23 -0
  11. data/lib/alephant/broker/response/asset.rb +28 -0
  12. data/lib/alephant/broker/response/base.rb +60 -0
  13. data/lib/alephant/broker/response/batch.rb +45 -0
  14. data/lib/alephant/broker/response/factory.rb +27 -0
  15. data/lib/alephant/broker/version.rb +1 -1
  16. data/spec/rack_spec.rb +14 -15
  17. data/spec/spec_helper.rb +0 -1
  18. metadata +14 -27
  19. data/lib/alephant/broker/app.rb +0 -20
  20. data/lib/alephant/broker/app/rack.rb +0 -25
  21. data/lib/alephant/broker/models/request.rb +0 -41
  22. data/lib/alephant/broker/models/request/error_request.rb +0 -11
  23. data/lib/alephant/broker/models/request/get_request.rb +0 -38
  24. data/lib/alephant/broker/models/request/notfound_request.rb +0 -11
  25. data/lib/alephant/broker/models/request/post_request.rb +0 -50
  26. data/lib/alephant/broker/models/request/status_request.rb +0 -11
  27. data/lib/alephant/broker/models/request_factory.rb +0 -26
  28. data/lib/alephant/broker/models/request_handler.rb +0 -50
  29. data/lib/alephant/broker/models/response.rb +0 -27
  30. data/lib/alephant/broker/models/response/asset_response.rb +0 -90
  31. data/lib/alephant/broker/models/response/batch_response.rb +0 -61
  32. data/lib/alephant/broker/models/response_factory.rb +0 -39
  33. data/spec/asset_response_spec.rb +0 -78
  34. data/spec/batch_response_spec.rb +0 -87
  35. data/spec/get_request_spec.rb +0 -72
  36. data/spec/post_request_spec.rb +0 -49
  37. data/spec/response_factory_spec.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7410ac49baac4bf594eabcfde56e669343902682
4
- data.tar.gz: 1ab7c48a49eb1e41182d4968c9cfe14a736032ce
3
+ metadata.gz: 38bbbde873e9befab83b241a575c79c3e60bb587
4
+ data.tar.gz: d6d650f9cb5e9e50ff3b665cc4f9f6759110c279
5
5
  SHA512:
6
- metadata.gz: 197a8602b01a878fd66154c23e4a783f4cc1fc7603c351ac016a55d6df5b9ab87bc07a12ece82a7dbeda6c0ab3f25f76912ce0e2befed2a730525f8bad39e251
7
- data.tar.gz: a5f6f485240d886380682631df0b558377a46b8d65838b87d9c4aa5216d4b5cb39bfb3cf2a2d483b51648585ddc5683d956c3aa74a9d0e609972031d46e476be
6
+ metadata.gz: faf61092ff24d4b65bbeee0dc8915662e731d8ed067ce6a789d0a663d2bc2ada0d6da2640424711decfa3500f97ec54a65a4124d918216dc28bb7bc0ab359079
7
+ data.tar.gz: 78132a0acdd19c4eda3ad0e3a5363bb4ec07081fd37c6364578e09baa786ffb580177b457b4c2ee3c488dd2486564d77dc9ba44d5e156094ece521c05e676519
@@ -1,12 +1,47 @@
1
- require "alephant/broker/version"
2
- require "alephant/broker/models/request_handler"
1
+ require 'alephant/broker/version'
2
+ require 'alephant/broker/request'
3
+ require 'alephant/broker/environment'
4
+ require 'alephant/broker'
3
5
 
4
6
  module Alephant
5
7
  module Broker
6
8
 
7
- def self.handle(config = {})
8
- RequestHandler.new(config).process
9
+ def self.handle(env)
10
+ Request::Handler.process env
9
11
  end
10
- end
11
12
 
13
+ def self.config
14
+ @@configuration
15
+ end
16
+
17
+ def self.config=(c)
18
+ @@configuration = c
19
+ end
20
+
21
+ class Application
22
+ def initialize(c = nil)
23
+ Broker.config = c unless c.nil?
24
+ end
25
+
26
+ def call(env)
27
+ send response_for(environment_for(env))
28
+ end
29
+
30
+ def environment_for(env)
31
+ Environment.new env
32
+ end
33
+
34
+ def response_for(call_environment)
35
+ Broker.handle call_environment
36
+ end
37
+
38
+ def send(response)
39
+ [
40
+ response.status,
41
+ { "Content-Type" => response.content_type },
42
+ [ response.content.to_s ]
43
+ ]
44
+ end
45
+ end
46
+ end
12
47
  end
@@ -0,0 +1,74 @@
1
+ require 'crimp'
2
+ require 'alephant/logger'
3
+ require 'alephant/cache'
4
+ require 'alephant/lookup'
5
+ require 'alephant/broker/errors/invalid_cache_key'
6
+ require 'alephant/sequencer'
7
+
8
+ module Alephant
9
+ module Broker
10
+ class Component
11
+ include Logger
12
+
13
+ attr_reader :id, :batch_id, :options, :content
14
+
15
+ def initialize(id, batch_id, options)
16
+ @id = id
17
+ @batch_id = batch_id
18
+ @options = symbolize(options || {})
19
+ end
20
+
21
+ def load
22
+ @content ||= cache.get(s3_path)
23
+ end
24
+
25
+ def opts_hash
26
+ @opts_hash ||= Crimp.signature(options)
27
+ end
28
+
29
+ def version
30
+ @version ||= sequencer.get_last_seen
31
+ end
32
+
33
+ private
34
+
35
+ def symbolize(hash)
36
+ Hash[hash.map { |k,v| [k.to_sym, v] }]
37
+ end
38
+
39
+ def cache
40
+ @cache ||= Alephant::Cache.new(
41
+ Broker.config[:s3_bucket_id],
42
+ Broker.config[:s3_object_path]
43
+ )
44
+ end
45
+
46
+ def s3_path
47
+ lookup.read(id, options, version).tap do |lookup_object|
48
+ raise InvalidCacheKey if lookup_object.location.nil?
49
+ end.location unless version.nil?
50
+ end
51
+
52
+ def lookup
53
+ @lookup ||= Alephant::Lookup.create(Broker.config[:lookup_table_name])
54
+ end
55
+
56
+ def key
57
+ batch_id.nil? ? component_key : renderer_key
58
+ end
59
+
60
+ def component_key
61
+ "#{id}/#{opts_hash}"
62
+ end
63
+
64
+ def renderer_key
65
+ "#{batch_id}/#{opts_hash}"
66
+ end
67
+
68
+ def sequencer
69
+ @sequencer ||= Alephant::Sequencer.create(Broker.config[:sequencer_table_name], key)
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -1,8 +1,9 @@
1
1
  require 'json'
2
+ require 'alephant/logger'
2
3
 
3
4
  module Alephant
4
5
  module Broker
5
- class CallEnvironment
6
+ class Environment
6
7
  include Logger
7
8
  attr_reader :settings
8
9
 
@@ -23,15 +24,18 @@ module Alephant
23
24
  end
24
25
 
25
26
  def query
26
- settings['QUERY_STRING']
27
+ settings['QUERY_STRING'] || ""
27
28
  end
28
29
 
29
- def path
30
- settings['PATH_INFO']
30
+ def options
31
+ query.split('&').reduce({}) do |object, key_pair|
32
+ key, value = key_pair.split('=')
33
+ object.tap { |o| o.store(key.to_sym, value) }
34
+ end
31
35
  end
32
36
 
33
- def request_type
34
- path.split('/')[1]
37
+ def path
38
+ settings['PATH_INFO']
35
39
  end
36
40
 
37
41
  def data
@@ -41,7 +45,7 @@ module Alephant
41
45
  private
42
46
 
43
47
  def rack_input
44
- (settings['rack.input'].read).tap { settings['rack.input'].rewind } # http://rack.rubyforge.org/doc/SPEC.html
48
+ (settings['rack.input'].read).tap { settings['rack.input'].rewind }
45
49
  end
46
50
 
47
51
  def parse(json)
@@ -0,0 +1,13 @@
1
+ module Alephant
2
+ module Broker
3
+ module Request
4
+ require 'alephant/broker/request/asset'
5
+ require 'alephant/broker/request/batch'
6
+ require 'alephant/broker/request/factory'
7
+ require 'alephant/broker/request/handler'
8
+
9
+ class NotFound; end
10
+ class Status; end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ require 'alephant/logger'
2
+ require 'alephant/broker/component'
3
+ require 'alephant/broker/errors/invalid_asset_id'
4
+
5
+ module Alephant
6
+ module Broker
7
+ module Request
8
+ class Asset
9
+ include Logger
10
+
11
+ attr_reader :component
12
+
13
+ def initialize(env)
14
+ logger.info("Request::Asset#initialize(#{env.settings})")
15
+ component_id = component_id_for env.path
16
+
17
+ @component = Component.new(
18
+ component_id,
19
+ nil,
20
+ env.options
21
+ )
22
+
23
+ logger.info("Request::Asset#initialize: id: #{component_id}")
24
+ raise InvalidAssetId.new("No Asset ID specified") if component_id.nil?
25
+ end
26
+
27
+ private
28
+
29
+ def component_id_for(path)
30
+ path.split('/')[2] || nil
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,38 @@
1
+ require 'alephant/logger'
2
+ require 'alephant/broker/component'
3
+
4
+
5
+ module Alephant
6
+ module Broker
7
+ module Request
8
+ class Batch
9
+ include Logger
10
+
11
+ attr_reader :batch_id, :components
12
+
13
+ def initialize(env)
14
+ logger.info("Request::Batch#initialize(#{env.settings})")
15
+
16
+ @batch_id = env.data['batch_id']
17
+ @components = components_for env
18
+
19
+ logger.info("Request::Batch#initialize: id: #{@batch_id}")
20
+ end
21
+
22
+ private
23
+
24
+ def components_for(env)
25
+ env.data['components'].map do |c|
26
+ Component.new(
27
+ c['component'],
28
+ batch_id,
29
+ c['options']
30
+ )
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,24 @@
1
+ require 'alephant/broker/request'
2
+
3
+ module Alephant::Broker::Request
4
+ class Factory
5
+
6
+ def self.request_type_from(env)
7
+ env.path.split('/')[1]
8
+ end
9
+
10
+ def self.request_for(env)
11
+ case request_type_from(env)
12
+ when 'component'
13
+ Asset.new(env)
14
+ when 'components'
15
+ Batch.new(env)
16
+ when 'status'
17
+ Status.new
18
+ else
19
+ NotFound.new
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,35 @@
1
+ require 'alephant/logger'
2
+
3
+ require 'alephant/broker/request'
4
+ require 'alephant/broker/response'
5
+ require 'alephant/broker/request/factory'
6
+ require 'alephant/broker/response/factory'
7
+
8
+ module Alephant
9
+ module Broker
10
+ module Request
11
+ class Handler
12
+ extend Logger
13
+
14
+ def self.request_for(env)
15
+ Request::Factory.request_for env
16
+ end
17
+
18
+ def self.response_for(request)
19
+ Response::Factory.response_for request
20
+ end
21
+
22
+ def self.process(env)
23
+ begin
24
+ response_for request_for(env)
25
+ rescue Exception => e
26
+ logger.info("Broker.requestHandler.process: Exception raised (#{e.message}, #{e.backtrace.join('\n')})")
27
+ Response::Factory.error
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,23 @@
1
+ module Alephant
2
+ module Broker
3
+ module Response
4
+ require 'alephant/broker/response/base'
5
+ require 'alephant/broker/response/asset'
6
+ require 'alephant/broker/response/batch'
7
+ require 'alephant/broker/response/factory'
8
+
9
+ class NotFound < Base
10
+ def initialize; super(404) end
11
+ end
12
+
13
+ class Status < Base
14
+ def initialize; super(200) end
15
+ end
16
+
17
+ class ServerError < Base
18
+ def initialize; super(500) end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,28 @@
1
+ require 'alephant/broker/errors/invalid_cache_key'
2
+ require 'alephant/logger'
3
+
4
+ module Alephant
5
+ module Broker
6
+ module Response
7
+ class Asset < Base
8
+ include Logger
9
+
10
+ attr_reader :component
11
+
12
+ def initialize(component)
13
+ @component = component
14
+ super()
15
+ end
16
+
17
+ def setup
18
+ result = load(component)
19
+
20
+ @status = result['status']
21
+ @content = result['body']
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,60 @@
1
+ require 'aws-sdk'
2
+
3
+ module Alephant
4
+ module Broker
5
+ module Response
6
+ class Base
7
+ attr_accessor :status, :content, :content_type
8
+
9
+ STATUS_CODE_MAPPING = {
10
+ 200 => 'ok',
11
+ 404 => 'Not found',
12
+ 500 => 'Error retrieving content'
13
+ }
14
+
15
+ def initialize(status = 200, content_type = "text/html")
16
+ @content_type = content_type
17
+ @status = status
18
+ @content = STATUS_CODE_MAPPING[status]
19
+
20
+ setup
21
+ end
22
+
23
+ protected
24
+
25
+ def setup; end
26
+
27
+ def load(component)
28
+ begin
29
+ body = component.load
30
+ status = 200
31
+ rescue AWS::S3::Errors::NoSuchKey, InvalidCacheKey => e
32
+ body = "#{error_for(e)}"
33
+ status = 404
34
+ rescue StandardError => e
35
+ body = "#{error_for(e)}"
36
+ status = 500
37
+ end
38
+
39
+ log(component, status, e)
40
+
41
+ { 'body' => body, 'status' => status }
42
+ end
43
+
44
+ def log(c, status, e = nil)
45
+ logger.info("Broker: Component loaded: #{details_for(c)} (#{status}) #{error_for(e)}")
46
+ end
47
+
48
+ def details_for(c)
49
+ "#{c.id}/#{c.opts_hash}/#{c.version} #{c.batch_id.nil? ? '' : "batched"} (#{c.options})"
50
+ end
51
+
52
+ def error_for(e)
53
+ e.nil? ? nil : "#{e.message}\n#{e.backtrace.join('\n')}"
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
60
+