wildcloud-router 0.0.2 → 0.0.3
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.
- data/CHANGELOG.md +7 -0
- data/bin/wildcloud-router +8 -0
- data/lib/wildcloud/router/cache.rb +23 -0
- data/lib/wildcloud/router/client.rb +41 -21
- data/lib/wildcloud/router/configuration.rb +7 -5
- data/lib/wildcloud/router/core.rb +5 -4
- data/lib/wildcloud/router/logger.rb +6 -3
- data/lib/wildcloud/router/monitor.rb +52 -0
- data/lib/wildcloud/router/proxy.rb +35 -30
- data/lib/wildcloud/router/version.rb +1 -1
- metadata +12 -10
data/CHANGELOG.md
CHANGED
data/bin/wildcloud-router
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Wildcloud
|
2
|
+
module Router
|
3
|
+
class Cache
|
4
|
+
|
5
|
+
def self.put(target, connection)
|
6
|
+
@connections ||= {}
|
7
|
+
@connections[target] ||= []
|
8
|
+
@connections << connection
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get(target)
|
12
|
+
@connections ||= {}
|
13
|
+
@connections[target] ||= []
|
14
|
+
@connections[target].shift
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.inspect
|
18
|
+
@connections.inspect
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -18,52 +18,72 @@ module Wildcloud
|
|
18
18
|
module Router
|
19
19
|
module Client
|
20
20
|
|
21
|
-
def initialize(
|
22
|
-
@
|
21
|
+
def initialize(target)
|
22
|
+
@target = target
|
23
23
|
@closed = false
|
24
|
-
@parser = Http::Parser.new(self)
|
25
|
-
@buffer = []
|
26
|
-
@time = Time.now
|
27
24
|
end
|
28
25
|
|
29
|
-
|
30
|
-
@closed
|
31
|
-
end
|
26
|
+
# EventMachine
|
32
27
|
|
33
28
|
def post_init
|
34
|
-
|
35
|
-
@proxy.request_headers.each do |name, value|
|
36
|
-
send_line("#{name}: #{value}")
|
37
|
-
end
|
38
|
-
send_line('')
|
39
|
-
send_data(@proxy.buffer)
|
40
|
-
EventMachine.enable_proxy(@proxy, self)
|
29
|
+
@parser = Http::ResponseParser.new(self)
|
41
30
|
end
|
42
31
|
|
43
32
|
def receive_data(data)
|
33
|
+
@outbound += data.size
|
44
34
|
@parser << data
|
45
35
|
rescue Http::Parser::Error => error
|
46
36
|
Router.logger.debug('Proxy client') { "Error #{error}" }
|
47
37
|
end
|
48
38
|
|
39
|
+
def unbind
|
40
|
+
@parser = nil
|
41
|
+
@stop_time = Time.now
|
42
|
+
Router.monitor.request(@target, @stop_time - @proxy.start_time, @inbound, @outbound)
|
43
|
+
@closed = true
|
44
|
+
@proxy.close_connection(true) if @proxy and !@proxy.closed?
|
45
|
+
end
|
46
|
+
|
47
|
+
# HTTP parser
|
48
|
+
|
49
49
|
def on_headers_complete(headers)
|
50
50
|
@proxy.send_line("HTTP/#{@parser.http_version.join('.')} #{@parser.status_code} #{CODE[@parser.status_code]}")
|
51
51
|
headers.each do |name, value|
|
52
52
|
@proxy.send_line("#{name}: #{value}")
|
53
53
|
end
|
54
54
|
@proxy.send_line('')
|
55
|
-
EventMachine.enable_proxy(self, @proxy)
|
56
|
-
end
|
57
|
-
|
58
|
-
def unbind
|
59
|
-
@closed = true
|
60
|
-
@proxy.close_connection(true) if @proxy and !@proxy.closed?
|
61
55
|
end
|
62
56
|
|
63
57
|
def on_body(chunk)
|
64
58
|
@proxy.send_data(chunk)
|
65
59
|
end
|
66
60
|
|
61
|
+
def on_message_complete
|
62
|
+
close_connection
|
63
|
+
end
|
64
|
+
|
65
|
+
# Tools
|
66
|
+
|
67
|
+
def make_request(proxy, version, method, url, headers)
|
68
|
+
@proxy = proxy
|
69
|
+
@inbound = 0
|
70
|
+
@outbound = 0
|
71
|
+
send_line("#{method} #{url} HTTP/#{version}")
|
72
|
+
headers.each do |name, value|
|
73
|
+
send_line("#{name}: #{value}")
|
74
|
+
end
|
75
|
+
send_line('')
|
76
|
+
end
|
77
|
+
|
78
|
+
def send_data(data)
|
79
|
+
@inbound += data.size
|
80
|
+
super(data)
|
81
|
+
end
|
82
|
+
|
83
|
+
def closed?
|
84
|
+
@closed
|
85
|
+
end
|
86
|
+
|
67
87
|
def send_line(data)
|
68
88
|
send_data("#{data}\r\n")
|
69
89
|
end
|
@@ -14,17 +14,19 @@
|
|
14
14
|
require 'yaml'
|
15
15
|
|
16
16
|
require 'wildcloud/router/logger'
|
17
|
+
require 'wildcloud/configuration'
|
17
18
|
|
18
19
|
module Wildcloud
|
19
20
|
module Router
|
21
|
+
|
20
22
|
def self.configuration
|
21
23
|
return @configuration if @configuration
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
config = Wildcloud::Configuration.load('router')
|
25
|
+
config.sources.each do |source|
|
26
|
+
self.logger.info('Configuration', "Loaded configuration from #{source}")
|
25
27
|
end
|
26
|
-
|
27
|
-
@configuration = YAML.load_file(file)
|
28
|
+
@configuration = config.configuration
|
28
29
|
end
|
30
|
+
|
29
31
|
end
|
30
32
|
end
|
@@ -41,6 +41,7 @@ module Wildcloud
|
|
41
41
|
def connect_amqp
|
42
42
|
Router.logger.info('Core') { "Connecting to broker" }
|
43
43
|
@amqp = AMQP.connect(Router.configuration["amqp"])
|
44
|
+
Router.logger_add_amqp(@amqp)
|
44
45
|
@channel = AMQP::Channel.new(@amqp)
|
45
46
|
# Communication infrastructure
|
46
47
|
@topic = @channel.topic('wildcloud.router')
|
@@ -64,12 +65,12 @@ module Wildcloud
|
|
64
65
|
@routes = data['routes']
|
65
66
|
end
|
66
67
|
|
67
|
-
def parse_target(
|
68
|
-
target =
|
68
|
+
def parse_target(raw_target)
|
69
|
+
target = raw_target.split(':')
|
69
70
|
if target.size == 1
|
70
|
-
{ "socket" => target[0]
|
71
|
+
{ "socket" => target[0]}
|
71
72
|
else
|
72
|
-
{ "address" => target[0], "port" => target[1]
|
73
|
+
{ "address" => target[0], "port" => target[1]}
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
@@ -27,12 +27,15 @@ module Wildcloud
|
|
27
27
|
@logger = Wildcloud::Logger::Logger.new
|
28
28
|
@logger.application = 'wildcloud.router'
|
29
29
|
@logger.add(Wildcloud::Logger::Middleware::Console)
|
30
|
-
@logger.add(Wildcloud::Logger::Middleware::Json)
|
31
|
-
@topic = AMQP::Channel.new(Core.instance.amqp).topic('wildcloud.logger')
|
32
|
-
@logger.add(Wildcloud::Logger::Middleware::Amqp, :exchange => @topic, :routing_key => 'wildcloud.router')
|
33
30
|
end
|
34
31
|
@logger
|
35
32
|
end
|
36
33
|
|
34
|
+
def self.logger_add_amqp(amqp)
|
35
|
+
logger.add(Wildcloud::Logger::Middleware::Json)
|
36
|
+
@topic = AMQP::Channel.new(amqp).topic('wildcloud.logger')
|
37
|
+
logger.add(Wildcloud::Logger::Middleware::Amqp, :exchange => @topic, :routing_key => 'wildcloud.router')
|
38
|
+
end
|
39
|
+
|
37
40
|
end
|
38
41
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Wildcloud
|
2
|
+
module Router
|
3
|
+
|
4
|
+
def self.monitor
|
5
|
+
@monitor ||= Monitor.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Monitor
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@channel = AMQP::Channel.new(Core.instance.amqp)
|
12
|
+
@topic = @channel.topic('wildcloud.monitor')
|
13
|
+
@data = setup
|
14
|
+
EventMachine.add_periodic_timer(1, &method(:report))
|
15
|
+
end
|
16
|
+
|
17
|
+
def report
|
18
|
+
data, @data = @data, setup
|
19
|
+
puts data.inspect
|
20
|
+
@topic.publish(JSON.dump(data), :routing_key => 'router')
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
{
|
25
|
+
:published_at => Time.now.to_i,
|
26
|
+
:node => Router.configuration['node']['name'],
|
27
|
+
:count => 0,
|
28
|
+
:inbound => 0,
|
29
|
+
:outbound => 0,
|
30
|
+
:time => 0,
|
31
|
+
:target => {},
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def request(target, time, inbound, outbound)
|
36
|
+
return unless target
|
37
|
+
target = "#{target['address']}:#{target['port']}"
|
38
|
+
@data[:count] += 1
|
39
|
+
@data[:inbound] += inbound
|
40
|
+
@data[:outbound] += outbound
|
41
|
+
@data[:time] += time
|
42
|
+
#@data[:target][target] ||= {:count => 0, :outbound => 0, :inbound => 0, :time => 0}
|
43
|
+
#@data[:target][target][:count] += 1
|
44
|
+
#@data[:target][target][:time] += time
|
45
|
+
#@data[:target][target][:inbound] += inbound
|
46
|
+
#@data[:target][target][:outbound] += outbound
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -15,39 +15,27 @@
|
|
15
15
|
require 'http/parser'
|
16
16
|
|
17
17
|
require 'wildcloud/router/client'
|
18
|
+
require 'wildcloud/router/monitor'
|
18
19
|
|
19
20
|
module Wildcloud
|
20
21
|
module Router
|
21
22
|
module Proxy
|
22
23
|
|
23
|
-
attr_reader :core, :
|
24
|
+
attr_reader :core, :start_time
|
24
25
|
|
25
26
|
def initialize(core)
|
26
27
|
@core = core
|
27
|
-
@parser = Http::Parser.new(self)
|
28
|
-
@buffer = []
|
29
28
|
@closed = false
|
30
|
-
@time = Time.now
|
31
|
-
@request_headers = nil
|
32
29
|
end
|
33
30
|
|
34
|
-
|
35
|
-
end
|
31
|
+
# EventMachine
|
36
32
|
|
37
|
-
def
|
38
|
-
@closed
|
33
|
+
def post_init
|
39
34
|
end
|
40
35
|
|
41
36
|
def receive_data(data)
|
42
|
-
|
43
|
-
|
44
|
-
@buffer = data[offset..-1]
|
45
|
-
if @target["socket"]
|
46
|
-
@client = EventMachine.connect(@target["socket"], Router::Client, self)
|
47
|
-
else
|
48
|
-
@client = EventMachine.connect(@target["address"], @target["port"], Router::Client, self)
|
49
|
-
end
|
50
|
-
end
|
37
|
+
@parser ||= Http::RequestParser.new(self)
|
38
|
+
@parser << data
|
51
39
|
rescue HTTP::Parser::Error => error
|
52
40
|
Router.logger.debug('Proxy') { "Error during parsing #{error.message}" }
|
53
41
|
end
|
@@ -57,15 +45,36 @@ module Wildcloud
|
|
57
45
|
@client.close_connection(true) if @client and !@client.closed?
|
58
46
|
end
|
59
47
|
|
48
|
+
# HTTP parser
|
49
|
+
|
50
|
+
def on_message_begin
|
51
|
+
@start_time = Time.now
|
52
|
+
end
|
53
|
+
|
60
54
|
def on_headers_complete(headers)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
55
|
+
return bad_request unless headers['Host']
|
56
|
+
target = @core.resolve(headers['Host'])
|
57
|
+
return bad_request unless target
|
58
|
+
if target["socket"]
|
59
|
+
@client = EventMachine.connect(target["socket"], Router::Client, target)
|
60
|
+
else
|
61
|
+
@client = EventMachine.connect(target["address"], target["port"], Router::Client, target)
|
62
|
+
end
|
63
|
+
@client.make_request(self, @parser.http_version.join('.'), @parser.http_method, @parser.request_url, headers)
|
64
|
+
end
|
65
|
+
|
66
|
+
def on_body(chunk)
|
67
|
+
@client.send_data(chunk)
|
68
|
+
end
|
69
|
+
|
70
|
+
def on_message_complete
|
71
|
+
@parser = nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# Tools
|
75
|
+
|
76
|
+
def closed?
|
77
|
+
@closed
|
69
78
|
end
|
70
79
|
|
71
80
|
def bad_request
|
@@ -73,10 +82,6 @@ module Wildcloud
|
|
73
82
|
:stop
|
74
83
|
end
|
75
84
|
|
76
|
-
def on_body(chunk)
|
77
|
-
@buffer << chunk
|
78
|
-
end
|
79
|
-
|
80
85
|
def send_line(data)
|
81
86
|
send_data("#{data}\r\n")
|
82
87
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wildcloud-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amqp
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153214940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153214940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: http_parser.rb
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153214200 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.5.3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153214200
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: json
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153213680 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - =
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.6.4
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153213680
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: wildcloud-logger
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153213220 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - =
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 0.0.1
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153213220
|
58
58
|
description: Routes requests across the platform
|
59
59
|
email:
|
60
60
|
- marek@jelen.biz
|
@@ -64,10 +64,12 @@ extensions: []
|
|
64
64
|
extra_rdoc_files: []
|
65
65
|
files:
|
66
66
|
- bin/wildcloud-router
|
67
|
+
- lib/wildcloud/router/cache.rb
|
67
68
|
- lib/wildcloud/router/client.rb
|
68
69
|
- lib/wildcloud/router/configuration.rb
|
69
70
|
- lib/wildcloud/router/core.rb
|
70
71
|
- lib/wildcloud/router/logger.rb
|
72
|
+
- lib/wildcloud/router/monitor.rb
|
71
73
|
- lib/wildcloud/router/proxy.rb
|
72
74
|
- lib/wildcloud/router/server.rb
|
73
75
|
- lib/wildcloud/router/version.rb
|