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.
- 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
|
+
|