class RJack::Jetty::ServerFactory

A factory for creating complete org.morbay.jetty.Server instances. Provides a general purpose facade for setup including the Server, a ThreadPool, a Connector, and various Handlers. It is non-exhaustive (not every Jetty facility is provided) but is designed to be easily extended.

Example

factory = Jetty::ServerFactory.new
factory.max_threads = 20
factory.port = 8080

# Set static resource context mapping URI to directory
factory.static_contexts[ '/html' ] = '/var/www/html'

# Implement custom handler and register it.
import 'org.eclipse.jetty.handler.AbstractHandler'
class RedirectHandler < AbstractHandler

  def initialize( redirects )
    super()
    @redirects = redirects
  end

  def handle( target, base_request, request, response )
    goto = @redirects[ target ]
    unless goto.nil?
      response.send_redirect( goto )
      base_request.handled = true
    end
  end
end

def factory.create_pre_handlers
  [ RedirectHandler.new( '/' => '/html/' ) ] + super
end

# Create a webapp context (war file or webapp expanded)
factory.webapp_contexts[ '/test' ] = Jetty::TestServlets::WEBAPP_TEST_WAR

# Create a context for a custom HelloServlet
import 'javax.servlet.http.HttpServlet'
class HelloServlet < HttpServlet
  def doGet( request, response )
    response.content_type = "text/plain"
    response.writer.write( 'Hello World!' )
  end
end

factory.set_context_servlets( '/hello', { '/*' => HelloServlet.new } )

# Create, start, and join (wait for shutdown)
server = factory.create
server.start
server.join

Attributes

connections[RW]

An array of connection options, each member being a hash with the following properties or an equivalent URI string:

:scheme

Values 'tcp' or 'ssl'

:host

The local interface to bind Default: 0.0.0.0 (all)

:port

Port number or 0 to select an available port (Default: top level port for first connection, 0 )

:max_idle_time_ms

See above

:key_store_path

For ssl, the path to the (Java JKS) keystore

:key_store_password

For ssl, the password to the keystore

:inherit_channel

If set to true, use channel based on standard input, if standard input is available and binded to a socket, it can be used for inetd or hot deploy with start_server (Default: false)

URI examples:

tcp://127.0.0.1
ssl://0.0.0.0:8443?key_store_path=test/keystore&key_store_password=399as8d9
tcp://127.0.0.1?inherit_channel=true
host[RW]

Default interface to bind to. Default: nil -> 0.0.0.0 -> all Use connections instead.

max_idle_time_ms[RW]

Default idle time in milliseconds to use for all connections. Default: 10,000 ms

max_threads[RW]

Maximum number of threads. A minimum value of 11 is used, based on the testing with the current Jetty version. Default: 20

min_threads[RW]

Minimum number of threads. A minimum value of 4 is used. Default: #max_threads / 4

port[RW]

Default port number or 0 to use any available port, for a single connection. Default: 0 Deprecated: use connections instead.

request_log_file[RW]

Request log output to :stderr or file name (default: nil, no log)

servlet_contexts[RW]

Hash of request path prefexes to servlet paths. Default: {}

static_contexts[RW]

Hash of request path prefixes to local file systems paths for static content. Default: {}

static_welcome_files[RW]

Array of welcome file names. Default: [ 'index.html' ]

stop_at_shutdown[RW]

Explicitly and gracefully stop the server on shutdown? Default: true

webapp_contexts[RW]

Hash of request path prefexes to java webapp paths Default: {} (none)

Public Class Methods

new() click to toggle source
# File lib/rjack-jetty.rb, line 191
def initialize
  @port                 = 0        # Use any available port
  @host                 = nil
  @max_threads          = 20
  @min_threads          = nil      # Compute from max_threads
  @max_idle_time_ms     = 10000
  @static_contexts      = {}
  @static_welcome_files = [ 'index.html' ]
  @webapp_contexts      = {}
  @request_log_file     = nil
  @servlet_contexts     = {}
  @stop_at_shutdown     = true
  @connections          = nil
end

Public Instance Methods

create() click to toggle source

Returns a new org.morbay.jetty.Server that is ready to be started.

# File lib/rjack-jetty.rb, line 208
def create
  server = Server.new( create_pool )

  server.connectors = create_connectors( server )

  hcol = HandlerCollection.new
  hcol.handlers = create_handlers.compact
  server.handler = hcol

  server.stop_at_shutdown = @stop_at_shutdown

  server
end
create_connectors( server ) click to toggle source

Return array of org.eclipse.jetty.Connector instances.

# File lib/rjack-jetty.rb, line 235
def create_connectors( server )
  first = true
  ( connections || [{ scheme: 'tcp' }] ).map do |opts|
    opts = parse_connection_uri( opts ) if opts.is_a?( String )

    connector = case opts[:scheme]
                when 'ssl'
                  create_https_connector( server, opts )
                when 'tcp'
                  create_http_connector( server, opts )
                else
                  raise "Unsupported connection scheme '#{opts[:scheme]}'"
                end
    h = opts[:host] || @host
    connector.host = h if h
    connector.port = opts[:port] || ( first && @port ) || 0
    connector.idle_timeout = opts[:max_idle_time_ms] || @max_idle_time_ms
    connector.inherit_channel = [true, 'true'].include?(opts[:inherit_channel])
    first = false
    connector
  end
end
create_context_handlers( context_handler_collection ) click to toggle source

Create context handlers on the provided ContextHandlerCollection

This implementation calls #create_static_contexts, #create_webapp_contexts, and create_servlet_context.

# File lib/rjack-jetty.rb, line 332
def create_context_handlers( context_handler_collection )
  create_static_contexts( context_handler_collection )
  create_webapp_contexts( context_handler_collection )
  create_servlet_contexts( context_handler_collection )
end
create_handlers() click to toggle source

Returns an Array of org.eclipse.jetty.Handler instances.

This implementation concatenates #create_pre_handlers and create_post_handlers.

# File lib/rjack-jetty.rb, line 298
def create_handlers
  ( create_pre_handlers + create_post_handlers )
end
create_http_connector( server, opts = {} ) click to toggle source
# File lib/rjack-jetty.rb, line 272
def create_http_connector( server, opts = {} )
  ServerConnector.new( server )
end
create_https_connector( server, opts = {} ) click to toggle source
# File lib/rjack-jetty.rb, line 276
def create_https_connector( server, opts = {} )
  ctx_f = SslContextFactory.new
  if opts[:key_store_path]
    ctx_f.key_store_path = opts[:key_store_path]
  end
  if opts[:key_store_password]
    ctx_f.key_store_password = opts[:key_store_password]
  end
  ssl_con_f = SslConnectionFactory.new(ctx_f, HttpVersion::HTTP_1_1.to_s)

  conf = HttpConfiguration.new
  conf.add_customizer( SecureRequestCustomizer.new )
  http_con_f = HttpConnectionFactory.new( conf )

  ServerConnector.new( server, ssl_con_f, http_con_f )

end
create_pool() click to toggle source

Return a org.eclipse.thread.ThreadPool implementation.

This implementation creates a QueuedThreadPool with #min_threads (default #max_threads / 4), and #max_threads (default 20).

# File lib/rjack-jetty.rb, line 227
def create_pool
  pool = QueuedThreadPool.new
  pool.min_threads = [ @min_threads || ( @max_threads / 4 ), 4 ].max
  pool.max_threads = [ @max_threads, 11 ].max
  pool
end
create_post_handlers() click to toggle source

Returns an Array of “post” org.eclipse.jetty.Handler instances.

This implementation returns a DefaultHandler instance, and any handler returned by create_request_log_handler.

# File lib/rjack-jetty.rb, line 323
def create_post_handlers
  [ DefaultHandler.new, # Handle errors, etc.
    create_request_log_handler ]
end
create_pre_handlers() click to toggle source

Returns an Array of “pre” org.eclipse.jetty.Handler instances.

This implementation returns an array containing a single ContextHandlerCollection which itself contains the context handlers set by #create_context_handlers, or an empty array if no context handlers were set.

# File lib/rjack-jetty.rb, line 308
def create_pre_handlers
  ctx_handlers = ContextHandlerCollection.new
  create_context_handlers( ctx_handlers )
  h = ctx_handlers.handlers
  if( h.nil? || h.length == 0 )
    [ ]
  else
    [ ctx_handlers ]
  end
end
create_request_log( log_file ) click to toggle source

Create a NCSARequestLog to append to log_file

# File lib/rjack-jetty.rb, line 383
def create_request_log( log_file )
  log = if log_file == :stderr
          NCSARequestLog.new
        else
          NCSARequestLog.new( log_file )
        end
  log.log_time_zone = java.util.TimeZone::getDefault.getID
  log.append = true;
  log
end
create_request_log_handler() click to toggle source

Create RequestLogHandler from any set #request_log_file

# File lib/rjack-jetty.rb, line 374
def create_request_log_handler
  if @request_log_file
    log_handler = RequestLogHandler.new
    log_handler.request_log = create_request_log( @request_log_file )
    log_handler
  end
end
create_servlet_contexts( context_handler_collection ) click to toggle source

Create context handlers from servlet_contexts.

# File lib/rjack-jetty.rb, line 356
def create_servlet_contexts( context_handler_collection )
  @servlet_contexts.each do |ctx, s_o|
    servlets, options = s_o
    context = ServletContextHandler.new( context_handler_collection, ctx, options )
    servlets.each do |path, servlet|
      context.add_servlet( ServletHolder.new( servlet ), path )
    end
  end
end
create_static_contexts( context_handler_collection ) click to toggle source

Create context handlers for static resources from #static_contexts

# File lib/rjack-jetty.rb, line 339
def create_static_contexts( context_handler_collection )
  @static_contexts.each do |ctx, rpath|
    ch = ContextHandler.new( context_handler_collection, ctx )
    ch.resource_base = rpath
    ch.handler = ResourceHandler.new
    ch.handler.welcome_files = @static_welcome_files
  end
end
create_webapp_contexts( context_handler_collection ) click to toggle source

Create webapp context handlers from webapp_contexts.

# File lib/rjack-jetty.rb, line 367
def create_webapp_contexts( context_handler_collection )
  @webapp_contexts.each do |ctx, webapp_path|
    WebAppContext.new( context_handler_collection, webapp_path, ctx )
  end
end
parse_connection_uri( uri ) click to toggle source
# File lib/rjack-jetty.rb, line 258
def parse_connection_uri( uri )
  u = URI.parse( uri )
  opts = { scheme: u.scheme,
           host: u.host,
           port: u.port }

  if u.query
    params = URI.decode_www_form( u.query )
    params = params.inject({}) { |m,(k,v)| m[k.to_sym] = v; m }
    opts.merge!( params )
  end

  opts
end
set_context_servlets( context_path, servlets, options = ServletContextHandler::NO_SESSIONS ) click to toggle source

Set a context of servlets given context_path, a servlets hash (mapping path to Servlet), and options.

# File lib/rjack-jetty.rb, line 350
def set_context_servlets( context_path, servlets,
                          options = ServletContextHandler::NO_SESSIONS )
  @servlet_contexts[ context_path ] = [ servlets, options ]
end