alephant-broker 0.1.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/alephant/broker.rb +40 -5
- data/lib/alephant/broker/component.rb +74 -0
- data/lib/alephant/broker/{call_environment.rb → environment.rb} +11 -7
- data/lib/alephant/broker/request.rb +13 -0
- data/lib/alephant/broker/request/asset.rb +37 -0
- data/lib/alephant/broker/request/batch.rb +38 -0
- data/lib/alephant/broker/request/factory.rb +24 -0
- data/lib/alephant/broker/request/handler.rb +35 -0
- data/lib/alephant/broker/response.rb +23 -0
- data/lib/alephant/broker/response/asset.rb +28 -0
- data/lib/alephant/broker/response/base.rb +60 -0
- data/lib/alephant/broker/response/batch.rb +45 -0
- data/lib/alephant/broker/response/factory.rb +27 -0
- data/lib/alephant/broker/version.rb +1 -1
- data/spec/rack_spec.rb +14 -15
- data/spec/spec_helper.rb +0 -1
- metadata +14 -27
- data/lib/alephant/broker/app.rb +0 -20
- data/lib/alephant/broker/app/rack.rb +0 -25
- data/lib/alephant/broker/models/request.rb +0 -41
- data/lib/alephant/broker/models/request/error_request.rb +0 -11
- data/lib/alephant/broker/models/request/get_request.rb +0 -38
- data/lib/alephant/broker/models/request/notfound_request.rb +0 -11
- data/lib/alephant/broker/models/request/post_request.rb +0 -50
- data/lib/alephant/broker/models/request/status_request.rb +0 -11
- data/lib/alephant/broker/models/request_factory.rb +0 -26
- data/lib/alephant/broker/models/request_handler.rb +0 -50
- data/lib/alephant/broker/models/response.rb +0 -27
- data/lib/alephant/broker/models/response/asset_response.rb +0 -90
- data/lib/alephant/broker/models/response/batch_response.rb +0 -61
- data/lib/alephant/broker/models/response_factory.rb +0 -39
- data/spec/asset_response_spec.rb +0 -78
- data/spec/batch_response_spec.rb +0 -87
- data/spec/get_request_spec.rb +0 -72
- data/spec/post_request_spec.rb +0 -49
- data/spec/response_factory_spec.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38bbbde873e9befab83b241a575c79c3e60bb587
|
4
|
+
data.tar.gz: d6d650f9cb5e9e50ff3b665cc4f9f6759110c279
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faf61092ff24d4b65bbeee0dc8915662e731d8ed067ce6a789d0a663d2bc2ada0d6da2640424711decfa3500f97ec54a65a4124d918216dc28bb7bc0ab359079
|
7
|
+
data.tar.gz: 78132a0acdd19c4eda3ad0e3a5363bb4ec07081fd37c6364578e09baa786ffb580177b457b4c2ee3c488dd2486564d77dc9ba44d5e156094ece521c05e676519
|
data/lib/alephant/broker.rb
CHANGED
@@ -1,12 +1,47 @@
|
|
1
|
-
require
|
2
|
-
require
|
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(
|
8
|
-
|
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
|
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
|
30
|
-
|
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
|
34
|
-
|
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
|
-
|
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
|
+
|