kirk 0.1.8-java → 0.2.0.beta.1-java

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. data/lib/kirk.rb +24 -26
  2. data/lib/kirk/cli.rb +1 -1
  3. data/lib/kirk/client.rb +57 -18
  4. data/lib/kirk/client/exchange.rb +146 -26
  5. data/lib/kirk/client/group.rb +94 -0
  6. data/lib/kirk/client/request.rb +42 -6
  7. data/lib/kirk/client/response.rb +20 -4
  8. data/lib/kirk/jetty.rb +22 -14
  9. data/lib/kirk/jetty/{jetty-client-7.2.2.v20101205.jar → jetty-client-7.3.0.v20110203.jar} +0 -0
  10. data/lib/kirk/jetty/jetty-continuation-7.3.0.v20110203.jar +0 -0
  11. data/lib/kirk/jetty/jetty-http-7.3.0.v20110203.jar +0 -0
  12. data/lib/kirk/jetty/jetty-io-7.3.0.v20110203.jar +0 -0
  13. data/lib/kirk/jetty/jetty-server-7.3.0.v20110203.jar +0 -0
  14. data/lib/kirk/jetty/jetty-util-7.3.0.v20110203.jar +0 -0
  15. data/lib/kirk/native.jar +0 -0
  16. data/lib/kirk/native.rb +12 -0
  17. data/lib/kirk/server.rb +11 -1
  18. data/lib/kirk/server/application_config.rb +56 -0
  19. data/lib/kirk/server/bootstrap.rb +59 -0
  20. data/lib/kirk/server/builder.rb +145 -0
  21. data/lib/kirk/{applications → server}/deploy_watcher.rb +1 -1
  22. data/lib/kirk/server/handler.rb +140 -0
  23. data/lib/kirk/server/hot_deployable.rb +63 -0
  24. data/lib/kirk/server/input_stream.rb +114 -0
  25. data/lib/kirk/{applications → server}/redeploy_client.rb +1 -1
  26. data/lib/kirk/version.rb +1 -1
  27. metadata +19 -16
  28. data/lib/kirk/applications/config.rb +0 -50
  29. data/lib/kirk/applications/hot_deployable.rb +0 -65
  30. data/lib/kirk/applications/rack.rb +0 -21
  31. data/lib/kirk/bootstrap.rb +0 -59
  32. data/lib/kirk/builder.rb +0 -143
  33. data/lib/kirk/client/connection.rb +0 -18
  34. data/lib/kirk/client/session.rb +0 -40
  35. data/lib/kirk/handler.rb +0 -129
  36. data/lib/kirk/input_stream.rb +0 -264
  37. data/lib/kirk/jetty/jetty-server-7.2.2.v20101205.jar +0 -0
@@ -1,10 +1,26 @@
1
1
  class Kirk::Client
2
2
  class Response
3
- attr_reader :status, :content
3
+ attr_accessor :version, :status, :body, :headers, :exception
4
4
 
5
- def initialize(content, status)
6
- @content = content
7
- @status = status
5
+ def initialize(buffer_body)
6
+ @status = nil
7
+ @version = nil
8
+ @headers = {}
9
+ @buffer_body = buffer_body
10
+ @body = buffer_body ? "" : nil
11
+ @exception = nil
12
+ end
13
+
14
+ def buffer_body?
15
+ @buffer_body
16
+ end
17
+
18
+ def success?
19
+ @status && @status < 400 && !@exception
20
+ end
21
+
22
+ def exception?
23
+ @exception
8
24
  end
9
25
  end
10
26
  end
data/lib/kirk/jetty.rb CHANGED
@@ -1,23 +1,31 @@
1
- require "kirk/jetty/jetty-client-7.2.2.v20101205"
2
- require "kirk/jetty/jetty-server-7.2.2.v20101205"
3
- require "kirk/jetty/servlet-api-2.5"
1
+ # Only require jars if in the "master" process
2
+ unless Kirk.sub_process?
3
+ require "kirk/jetty/servlet-api-2.5"
4
+
5
+ %w(util http io continuation server client).each do |mod|
6
+ require "kirk/jetty/jetty-#{mod}-7.3.0.v20110203"
7
+ end
8
+ end
4
9
 
5
10
  module Kirk
6
11
  module Jetty
7
12
  # Gimme Jetty
8
- import "org.eclipse.jetty.client.HttpClient"
9
- import "org.eclipse.jetty.client.HttpExchange"
13
+ java_import "org.eclipse.jetty.client.HttpClient"
14
+ java_import "org.eclipse.jetty.client.HttpExchange"
15
+ java_import "org.eclipse.jetty.client.ContentExchange"
16
+
17
+ java_import "org.eclipse.jetty.io.ByteArrayBuffer"
10
18
 
11
- import "org.eclipse.jetty.server.nio.SelectChannelConnector"
12
- import "org.eclipse.jetty.server.handler.AbstractHandler"
13
- import "org.eclipse.jetty.server.handler.ContextHandler"
14
- import "org.eclipse.jetty.server.handler.ContextHandlerCollection"
15
- import "org.eclipse.jetty.server.Server"
19
+ java_import "org.eclipse.jetty.server.nio.SelectChannelConnector"
20
+ java_import "org.eclipse.jetty.server.handler.AbstractHandler"
21
+ java_import "org.eclipse.jetty.server.handler.ContextHandler"
22
+ java_import "org.eclipse.jetty.server.handler.ContextHandlerCollection"
23
+ java_import "org.eclipse.jetty.server.Server"
16
24
 
17
- import "org.eclipse.jetty.util.component.LifeCycle"
18
- import "org.eclipse.jetty.util.log.Log"
19
- import "org.eclipse.jetty.util.log.JavaUtilLog"
25
+ java_import "org.eclipse.jetty.util.component.LifeCycle"
26
+ java_import "org.eclipse.jetty.util.log.Log"
27
+ java_import "org.eclipse.jetty.util.log.JavaUtilLog"
20
28
 
21
- Log.set_log Jetty::JavaUtilLog.new
29
+ Log.set_log Jetty::JavaUtilLog.new unless Kirk.sub_process?
22
30
  end
23
31
  end
data/lib/kirk/native.jar CHANGED
Binary file
@@ -0,0 +1,12 @@
1
+ require 'kirk/native.jar'
2
+
3
+ module Kirk
4
+ Jetty # Trigger the jetty autoload
5
+
6
+ module Native
7
+ java_import "com.strobecorp.kirk.ApplicationConfig"
8
+ java_import "com.strobecorp.kirk.HotDeployableApplication"
9
+ java_import "com.strobecorp.kirk.LogFormatter"
10
+ java_import "com.strobecorp.kirk.RewindableInputStream"
11
+ end
12
+ end
data/lib/kirk/server.rb CHANGED
@@ -1,5 +1,15 @@
1
+ require 'kirk'
2
+
1
3
  module Kirk
2
4
  class Server
5
+ autoload :ApplicationConfig, 'kirk/server/application_config'
6
+ autoload :Builder, 'kirk/server/builder'
7
+ autoload :DeployWatcher, 'kirk/server/deploy_watcher'
8
+ autoload :Handler, 'kirk/server/handler'
9
+ autoload :HotDeployable, 'kirk/server/hot_deployable'
10
+ autoload :InputStream, 'kirk/server/input_stream'
11
+ autoload :RedeployClient, 'kirk/server/redeploy_client'
12
+
3
13
  def self.build(file = nil, &blk)
4
14
  root = File.dirname(file) if file
5
15
  builder = Builder.new(root)
@@ -27,7 +37,7 @@ module Kirk
27
37
  if Jetty::AbstractHandler === handler
28
38
  @handler = handler
29
39
  elsif handler.respond_to?(:call)
30
- @handler = Applications::Rack.new(handler)
40
+ @handler = Handler.new(handler)
31
41
  else
32
42
  raise "#{handler.inspect} is not a valid Rack application"
33
43
  end
@@ -0,0 +1,56 @@
1
+ module Kirk
2
+ class Server::ApplicationConfig
3
+ include Native::ApplicationConfig
4
+
5
+ attr_accessor :env,
6
+ :hosts,
7
+ :listen,
8
+ :watch,
9
+ :rackup,
10
+ :application_path,
11
+ :bootstrap_path
12
+
13
+ def initialize
14
+ @env = {}
15
+ @hosts = []
16
+ @listen = listen
17
+ end
18
+
19
+ def application_path
20
+ @application_path || File.dirname(rackup)
21
+ end
22
+
23
+ # Handle the java interface
24
+ alias getApplicationPath application_path
25
+ alias getRackupPath rackup
26
+ alias getBootstrapPath bootstrap_path
27
+
28
+ def getEnvironment
29
+ map = java.util.HashMap.new
30
+ env = ENV.dup
31
+
32
+ self.env.each do |key, val|
33
+ env[key.to_s] = val
34
+ end
35
+
36
+ env.each do |key, val|
37
+ next unless val
38
+
39
+ key = key.to_java_string
40
+ val = val.to_s.to_java_string
41
+
42
+ map.put(key, val)
43
+ end
44
+
45
+ map
46
+ end
47
+
48
+ def getKirkVersionStamper
49
+ <<-RUBY
50
+ module Kirk
51
+ PARENT_VERSION = #{VERSION.inspect}.freeze
52
+ end
53
+ RUBY
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ require 'java'
2
+
3
+ module Kirk
4
+ class Server
5
+ class Bootstrap
6
+ def warmup(application_path)
7
+ Dir.chdir File.expand_path(application_path)
8
+
9
+ load_rubygems
10
+
11
+ load_bundle.tap do
12
+ add_kirk_to_load_path
13
+
14
+ load_rack
15
+ load_kirk
16
+ end
17
+ end
18
+
19
+ def run(rackup)
20
+ app, options = Rack::Builder.parse_file(rackup)
21
+
22
+ Handler.new(app)
23
+ end
24
+
25
+ private
26
+
27
+ def load_rubygems
28
+ require 'rubygems'
29
+ end
30
+
31
+ def load_bundle
32
+ if File.exist?('Gemfile')
33
+ require 'bundler/setup'
34
+
35
+ if File.exist?('Gemfile.lock')
36
+ require 'digest/sha1'
37
+ str = File.read('Gemfile') + File.read('Gemfile.lock')
38
+ Digest::SHA1.hexdigest(str)
39
+ end
40
+ end
41
+ end
42
+
43
+ def add_kirk_to_load_path
44
+ $:.unshift File.expand_path('../../..', __FILE__)
45
+ end
46
+
47
+ def load_rack
48
+ gem "rack", ">= 1.0.0"
49
+ require 'rack'
50
+ end
51
+
52
+ def load_kirk
53
+ require 'kirk/server'
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ Kirk::Server::Bootstrap.new
@@ -0,0 +1,145 @@
1
+ module Kirk
2
+ class MissingConfigFile < RuntimeError ; end
3
+ class MissingRackupFile < RuntimeError ; end
4
+
5
+ class Server
6
+ class Builder
7
+
8
+ VALID_LOG_LEVELS = %w(severe warning info config fine finer finest all)
9
+
10
+ attr_reader :options
11
+
12
+ def initialize(root = nil)
13
+ @root = root || Dir.pwd
14
+ @current = nil
15
+ @configs = []
16
+ @options = {
17
+ :watcher => DeployWatcher.new("/tmp/kirk.sock")
18
+ }
19
+ end
20
+
21
+ def load(glob)
22
+ glob = expand_path(glob)
23
+
24
+ files = Dir[glob].select { |f| File.file?(f) }
25
+
26
+ if files.empty?
27
+ raise MissingConfigFile, "glob `#{glob}` did not match any files"
28
+ end
29
+
30
+ files.each do |file|
31
+ with_root File.dirname(file) do
32
+ instance_eval(File.read(file), file)
33
+ end
34
+ end
35
+ end
36
+
37
+ def log(opts = {})
38
+ level = opts[:level]
39
+ raise "Invalid log level" unless VALID_LOG_LEVELS.include?(level.to_s)
40
+ @options[:log_level] = level.to_s
41
+ end
42
+
43
+ def rack(rackup)
44
+ rackup = expand_path(rackup)
45
+
46
+ unless File.exist?(rackup)
47
+ raise MissingRackupFile, "rackup file `#{rackup}` does not exist"
48
+ end
49
+
50
+ @current = new_config
51
+ @current.rackup = rackup
52
+
53
+ yield if block_given?
54
+
55
+ ensure
56
+ @configs << @current
57
+ @current = nil
58
+ end
59
+
60
+ def env(env)
61
+ @current.env.merge!(env)
62
+ end
63
+
64
+ def hosts(*hosts)
65
+ @current.hosts.concat hosts
66
+ end
67
+
68
+ def listen(listen)
69
+ listen = listen.to_s
70
+ listen = ":#{listen}" unless listen.index(':')
71
+ listen = "0.0.0.0#{listen}" if listen.index(':') == 0
72
+
73
+ @current.listen = listen
74
+ end
75
+
76
+ def watch(*watch)
77
+ @current.watch = watch
78
+ end
79
+
80
+ def to_handler
81
+ handlers = @configs.map do |c|
82
+ Jetty::ContextHandler.new.tap do |ctx|
83
+ # Set the virtual hosts
84
+ unless c.hosts.empty?
85
+ ctx.set_virtual_hosts(c.hosts)
86
+ end
87
+
88
+ application = HotDeployable.new(c)
89
+ application.add_watcher(watcher)
90
+
91
+ ctx.set_connector_names [c.listen]
92
+ ctx.set_handler application
93
+ end
94
+ end
95
+
96
+ Jetty::ContextHandlerCollection.new.tap do |collection|
97
+ collection.set_handlers(handlers)
98
+ end
99
+ end
100
+
101
+ def to_connectors
102
+ @connectors = {}
103
+
104
+ @configs.each do |config|
105
+ next if @connectors.key?(config.listen)
106
+
107
+ host, port = config.listen.split(':')
108
+
109
+ connector = Jetty::SelectChannelConnector.new
110
+ connector.set_host(host)
111
+ connector.set_port(port.to_i)
112
+
113
+ @connectors[config.listen] = connector
114
+ end
115
+
116
+ @connectors.values
117
+ end
118
+
119
+ private
120
+
121
+ def watcher
122
+ @options[:watcher]
123
+ end
124
+
125
+ def with_root(root)
126
+ old, @root = @root, root
127
+ yield
128
+ ensure
129
+ @root = old
130
+ end
131
+
132
+ def expand_path(path)
133
+ File.expand_path(path, @root)
134
+ end
135
+
136
+ def new_config
137
+ ApplicationConfig.new.tap do |config|
138
+ config.listen = '0.0.0.0:9090'
139
+ config.watch = [ ]
140
+ config.bootstrap_path = File.expand_path('../bootstrap.rb', __FILE__)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -1,7 +1,7 @@
1
1
  require 'socket'
2
2
 
3
3
  module Kirk
4
- class Applications::DeployWatcher
4
+ class Server::DeployWatcher
5
5
  include Jetty::LifeCycle::Listener
6
6
 
7
7
  def initialize(unix_socket_path = nil)
@@ -0,0 +1,140 @@
1
+ module Kirk
2
+ class Server
3
+ class Handler < Jetty::AbstractHandler
4
+ java_import 'java.util.zip.GZIPInputStream'
5
+ java_import 'java.util.zip.InflaterInputStream'
6
+
7
+ # Trigger the autoload so that the first access to the class
8
+ # does not happen in a thread.
9
+ InputStream
10
+
11
+ # Required environment variable keys
12
+ REQUEST_METHOD = 'REQUEST_METHOD'.freeze
13
+ SCRIPT_NAME = 'SCRIPT_NAME'.freeze
14
+ PATH_INFO = 'PATH_INFO'.freeze
15
+ QUERY_STRING = 'QUERY_STRING'.freeze
16
+ SERVER_NAME = 'SERVER_NAME'.freeze
17
+ SERVER_PORT = 'SERVER_PORT'.freeze
18
+ CONTENT_TYPE = 'CONTENT_TYPE'.freeze
19
+ CONTENT_LENGTH = 'CONTENT_LENGTH'.freeze
20
+ REQUEST_URI = 'REQUEST_URI'.freeze
21
+ REMOTE_HOST = 'REMOTE_HOST'.freeze
22
+ REMOTE_ADDR = 'REMOTE_ADDR'.freeze
23
+ REMOTE_USER = 'REMOTE_USER'.freeze
24
+
25
+ # Rack specific variable keys
26
+ RACK_VERSION = 'rack.version'.freeze
27
+ RACK_URL_SCHEME = 'rack.url_scheme'.freeze
28
+ RACK_INPUT = 'rack.input'.freeze
29
+ RACK_ERRORS = 'rack.errors'.freeze
30
+ RACK_MULTITHREAD = 'rack.multithread'.freeze
31
+ RACK_MULTIPROCESS = 'rack.multiprocess'.freeze
32
+ RACK_RUN_ONCE = 'rack.run_once'.freeze
33
+ HTTP_PREFIX = 'HTTP_'.freeze
34
+
35
+ # Rack response header names
36
+ CONTENT_TYPE_RESP = 'Content-Type'
37
+ CONTENT_LENGTH_RESP = 'Content-Length'
38
+
39
+ # Kirk information
40
+ SERVER = "#{NAME} #{VERSION}".freeze
41
+ SERVER_SOFTWARE = 'SERVER_SOFTWARE'.freeze
42
+
43
+ DEFAULT_RACK_ENV = {
44
+ SERVER_SOFTWARE => SERVER,
45
+
46
+ # Rack stuff
47
+ RACK_ERRORS => STDERR,
48
+ RACK_MULTITHREAD => true,
49
+ RACK_MULTIPROCESS => false,
50
+ RACK_RUN_ONCE => false,
51
+ }
52
+
53
+ CONTENT_LENGTH_TYPE_REGEXP = /^Content-(?:Type|Length)$/i
54
+
55
+ def self.new(app)
56
+ inst = super()
57
+ inst.app = app
58
+ inst
59
+ end
60
+
61
+ attr_accessor :app
62
+
63
+ def handle(target, base_request, request, response)
64
+ begin
65
+ env = DEFAULT_RACK_ENV.merge(
66
+ SCRIPT_NAME => "",
67
+ PATH_INFO => request.get_path_info,
68
+ REQUEST_URI => request.getRequestURI,
69
+ REQUEST_METHOD => request.get_method || "GET",
70
+ RACK_URL_SCHEME => request.get_scheme || "http",
71
+ QUERY_STRING => request.get_query_string || "",
72
+ SERVER_NAME => request.get_server_name || "",
73
+ REMOTE_HOST => request.get_remote_host || "",
74
+ REMOTE_ADDR => request.get_remote_addr || "",
75
+ REMOTE_USER => request.get_remote_user || "",
76
+ SERVER_PORT => request.get_server_port.to_s,
77
+ RACK_VERSION => ::Rack::VERSION)
78
+
79
+ # Process the content length
80
+ if (content_length = request.get_content_length) >= 0
81
+ env[CONTENT_LENGTH] = content_length.to_s
82
+ else
83
+ env[CONTENT_LENGTH] = "0"
84
+ end
85
+
86
+ if (content_type = request.get_content_type)
87
+ env[CONTENT_TYPE] = content_type unless content_type == ''
88
+ end
89
+
90
+ request.get_header_names.each do |header|
91
+ next if header =~ CONTENT_LENGTH_TYPE_REGEXP
92
+ value = request.get_header(header)
93
+
94
+ header.tr! '-', '_'
95
+ header.upcase!
96
+
97
+ header = "#{HTTP_PREFIX}#{header}"
98
+ env[header] = value unless env.key?(header) || value == ''
99
+ end
100
+
101
+ input = request.get_input_stream
102
+
103
+ case env['HTTP_CONTENT_ENCODING']
104
+ when 'deflate' then input = InflaterInputStream.new(input)
105
+ when 'gzip' then input = GZIPInputStream.new(input)
106
+ end
107
+
108
+ input = InputStream.new(input)
109
+ env[RACK_INPUT] = input
110
+
111
+ # Dispatch the request
112
+ status, headers, body = @app.call(env)
113
+
114
+ response.set_status(status.to_i)
115
+
116
+ headers.each do |header, value|
117
+ case header
118
+ when CONTENT_TYPE_RESP
119
+ response.set_content_type(value)
120
+ when CONTENT_LENGTH_RESP
121
+ response.set_content_length(value.to_i)
122
+ else
123
+ response.set_header(header, value)
124
+ end
125
+ end
126
+
127
+ buffer = response.get_output_stream
128
+ body.each do |s|
129
+ buffer.write(s.to_java_bytes)
130
+ end
131
+
132
+ body.close if body.respond_to?(:close)
133
+ ensure
134
+ input.recycle if input.respond_to?(:recycle)
135
+ request.set_handled(true)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end