trinidad 1.4.1 → 1.4.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.
@@ -29,7 +29,7 @@ module Trinidad
29
29
 
30
30
  # Load the configuration from the given options and return it.
31
31
  def load!(options)
32
- config = config_file(options[:web_app_dir])
32
+ config = config_file(options[:root_dir] || options[:web_app_dir])
33
33
  if config && File.exist?(config)
34
34
  if yaml = (File.extname(config) == '.yml')
35
35
  require 'yaml'; require 'erb'
@@ -45,10 +45,12 @@ module Trinidad
45
45
  end
46
46
  alias_method :load_configuration, :load!
47
47
 
48
+ DEFAULT_CONFIG_FILE = 'config/trinidad.{yml,rb}'
49
+
48
50
  def config_file(base_dir = nil)
49
51
  base_dir ||= Dir.pwd
50
52
  if @config_file.nil? # false means do not use no config file
51
- Dir.glob(File.join(base_dir, 'config', 'trinidad.{yml,rb}')).first
53
+ Dir.glob(File.join(base_dir, DEFAULT_CONFIG_FILE)).first
52
54
  else
53
55
  @config_file && File.expand_path(@config_file, base_dir)
54
56
  end
@@ -59,79 +61,86 @@ module Trinidad
59
61
  def options_parser
60
62
  require 'optparse'
61
63
  @parser ||= OptionParser.new do |opts|
62
- opts.banner = 'Trinidad server default options:'
64
+ opts.banner = 'Usage: trinidad [server options]'
63
65
  opts.separator ''
64
66
 
65
- opts.on('-d', '--dir WEB_APP_DIRECTORY', 'web app directory path',
66
- "default: #{Dir.pwd}") do |dir|
67
- default_options[:web_app_dir] = dir
67
+ opts.on('-d', '--dir ROOT_DIR', 'web application root directory',
68
+ "default: current working directory") do |dir|
69
+ default_options[:root_dir] = dir
68
70
  end
69
71
 
70
- opts.on('-e', '--env ENVIRONMENT', '(rails) environment',
71
- "default: #{default_options[:environment]}") do |env|
72
+ opts.on('-e', '--env ENVIRONMENT', 'rack (rails) environment',
73
+ "default: #{default(:environment)}") do |env|
72
74
  default_options[:environment] = env
73
75
  end
74
-
75
- opts.on('-p', '--port PORT', 'port to bind to',
76
- "default: #{default_options[:port]}") do |port|
77
- default_options[:port] = port
76
+
77
+ opts.on('-r', '--rackup [RACKUP_FILE]', 'rackup configuration file',
78
+ "default: config.ru") do |rackup|
79
+ default_options[:rackup] = rackup || 'config.ru'
78
80
  end
79
81
 
82
+ opts.on('--public', '--public PUBLIC_DIR', 'web application public root',
83
+ "default: #{default(:public)}") do |public|
84
+ default_options[:public] = public
85
+ end
86
+
80
87
  opts.on('-c', '--context CONTEXT_PATH', 'application context path',
81
- "default: #{default_options[:context_path]}") do |path|
88
+ "default: #{default(:context_path)}") do |path|
82
89
  default_options[:context_path] = path
83
90
  end
84
-
85
- opts.on('--lib', '--jars LIBS_DIR', 'directory containing java jars used by the application',
86
- "default: #{default_options[:libs_dir]}") do |dir|
87
- default_options[:libs_dir] = dir
88
- end
89
-
90
- opts.on('--classes', '--classes CLASSES_DIR', 'directory containing java classes used by the application',
91
- "default: #{default_options[:classes_dir]}") do |dir|
92
- default_options[:classes_dir] = dir
91
+
92
+ opts.on('--monitor', '--monitor MONITOR_FILE', 'monitor for application re-deploys',
93
+ "default: tmp/restart.txt") do |monitor|
94
+ default_options[:monitor] = monitor
93
95
  end
94
-
95
- opts.on('-s', '--ssl [SSL_PORT]', 'enable secure socket layout',
96
- "default port: 8443") do |port|
97
- default_options[:ssl] = { :port => (port || 8443).to_i }
96
+
97
+ opts.on('-t', '--threadsafe', 'force thread-safe mode (use single runtime)') do
98
+ default_options[:jruby_min_runtimes] = 1
99
+ default_options[:jruby_max_runtimes] = 1
98
100
  end
99
-
100
- opts.on('-a', '--ajp [AJP_PORT]', 'enable ajp connections (deprecated)',
101
- "default port: 8009") do |port|
102
- default_options[:ajp] = { :port => (port || 8009).to_i }
101
+
102
+ opts.on('--runtimes MIN:MAX', 'use given number of min/max jruby runtimes',
103
+ "default: #{default(:jruby_min_runtimes)}:#{default(:jruby_max_runtimes)}") do
104
+ |min_max| min, max = min_max.split(':')
105
+ default_options[:jruby_min_runtimes] = min.to_i if min
106
+ default_options[:jruby_max_runtimes] = max.to_i if max
103
107
  end
104
-
108
+
105
109
  opts.on('-f', '--config [CONFIG_FILE]', 'configuration file',
106
- "default: config/trinidad.{yml,rb}") do |file|
110
+ "default: #{DEFAULT_CONFIG_FILE}") do |file|
107
111
  self.config_file = file
108
112
  end
109
-
110
- opts.on('-r', '--rackup [RACKUP_FILE]', 'rackup configuration file',
111
- 'default: config.ru') do |rackup|
112
- default_options[:rackup] = rackup || 'config.ru'
113
+
114
+ opts.on('--address', '--address ADDRESS', 'host address',
115
+ "default: #{default(:address)}") do |address|
116
+ default_options[:address] = address
113
117
  end
114
-
115
- opts.on('--public', '--public DIRECTORY', 'public directory', 'default: public') do |public|
116
- default_options[:public] = public
118
+
119
+ opts.on('-p', '--port PORT', 'port to bind to',
120
+ "default: #{default(:port)}") do |port|
121
+ default_options[:port] = port
117
122
  end
118
123
 
119
- opts.on('-t', '--threadsafe', 'force thread-safe mode') do
120
- default_options[:jruby_min_runtimes] = 1
121
- default_options[:jruby_max_runtimes] = 1
124
+ opts.on('-s', '--ssl [SSL_PORT]', 'enable secure socket layout',
125
+ "default port: 8443") do |port|
126
+ default_options[:ssl] = { :port => (port || 8443).to_i }
122
127
  end
123
128
 
124
- opts.on('--address', '--address ADDRESS', 'host address', 'default: localhost') do |address|
125
- default_options[:address] = address
129
+ opts.on('-a', '--ajp [AJP_PORT]', 'enable the AJP web protocol',
130
+ "default port: 8009") do |port|
131
+ default_options[:ajp] = { :port => (port || 8009).to_i }
126
132
  end
127
133
 
128
- opts.on('-g', '--log LEVEL', 'log level', 'default: INFO') do |log|
129
- default_options[:log] = log
134
+ opts.on('--java_lib LIB_DIR', '--lib LIB_DIR (deprecated use --java_lib)',
135
+ 'contains .jar files used by the app',
136
+ "default: #{default(:java_lib)}") do |lib|
137
+ default_options[:java_lib] = lib
130
138
  end
131
139
 
132
- opts.on('-v', '--version', 'display the current version') do
133
- puts "trinidad #{Trinidad::VERSION} (tomcat #{Trinidad::TOMCAT_VERSION})"
134
- exit
140
+ opts.on('--java_classes CLASSES_DIR', '--classes CLASSES_DIR (deprecated use --java_classes)',
141
+ 'contains java classes used by the app',
142
+ "default: #{default_java_classes}") do |classes|
143
+ default_options[:java_classes] = classes
135
144
  end
136
145
 
137
146
  opts.on('-l', '--load EXTENSION_NAMES', Array, 'load options for extensions') do |ext_names|
@@ -140,20 +149,37 @@ module Trinidad
140
149
  end
141
150
  end
142
151
 
143
- opts.on('--apps', '--apps APPS_BASE_DIR', 'applications base directory') do |path|
144
- default_options[:apps_base] = path
152
+ opts.on('--apps_base APPS_BASE_DIR', '--apps APPS_BASE_DIR (deprecated use --apps_base)',
153
+ 'set applications base directory') do |apps_base|
154
+ default_options[:apps_base] = apps_base
145
155
  end
146
-
147
- opts.on('--monitor' '--monitor MONITOR_FILE', 'monitor file for hot deployments') do |monitor|
148
- default_options[:monitor] = monitor
156
+
157
+ opts.on('-g', '--log LEVEL', 'set logging level') do |log|
158
+ default_options[:log] = log
149
159
  end
150
160
 
151
- opts.on('-h', '--help', 'display the help') do
161
+ opts.on('-v', '--version', 'show server version') do
162
+ puts "Trinidad #{Trinidad::VERSION} (Tomcat #{Trinidad::TOMCAT_VERSION})"
163
+ exit
164
+ end
165
+
166
+ opts.on('-h', '--help', 'display this help') do
152
167
  puts opts
153
168
  exit
154
169
  end
155
170
  end
156
171
  end
157
172
 
173
+ private
174
+
175
+ def default(key)
176
+ default_options[key] || Configuration::DEFAULTS[key]
177
+ end
178
+
179
+ def default_java_classes
180
+ default(:java_classes) ||
181
+ ( default(:java_lib) && File.join(default(:java_lib), 'classes') )
182
+ end
183
+
158
184
  end
159
185
  end
@@ -9,10 +9,10 @@ module Trinidad
9
9
  config = ( self.configuration ||= Configuration.new )
10
10
  args.compact!
11
11
  if options = args.shift
12
- options = Trinidad::Configuration.symbolize_options(options)
12
+ options = Configuration.symbolize_options(options)
13
13
  args.each do |opts|
14
- opts = Trinidad::Configuration.symbolize_options(opts)
15
- options = Trinidad::Configuration.merge_options(options, opts)
14
+ opts = Configuration.symbolize_options(opts)
15
+ options = Configuration.merge_options(options, opts)
16
16
  end
17
17
  config.update!(options)
18
18
  end
@@ -32,20 +32,22 @@ module Trinidad
32
32
  # the instance using Trinidad#configuration
33
33
  class Configuration
34
34
 
35
+ DEFAULTS = {
36
+ :port => 3000,
37
+ :address => 'localhost',
38
+ :environment => 'development',
39
+ :context_path => '/',
40
+ :public => 'public',
41
+ :java_lib => 'lib/java',
42
+ :default_web_xml => 'config/web.xml',
43
+ :jruby_min_runtimes => 1,
44
+ :jruby_max_runtimes => 5,
45
+ :log => 'INFO',
46
+ :trap => true
47
+ }
48
+
35
49
  def initialize(options = {})
36
- @config = {
37
- :port => 3000,
38
- :address => 'localhost',
39
- :environment => 'development',
40
- :context_path => '/',
41
- :libs_dir => 'lib',
42
- :classes_dir => 'classes',
43
- :default_web_xml => 'config/web.xml',
44
- :jruby_min_runtimes => 1,
45
- :jruby_max_runtimes => 5,
46
- :log => 'INFO',
47
- :trap => true
48
- }
50
+ @config = DEFAULTS.clone
49
51
  update!(options)
50
52
  end
51
53
 
@@ -77,15 +79,16 @@ module Trinidad
77
79
  end
78
80
 
79
81
  %w{ port address environment context_path
80
- libs_dir classes_dir default_web_xml
81
- jruby_min_runtimes jruby_max_runtimes
82
- rackup servlet public hosts
82
+ java_lib libs_dir java_classes classes_dir default_web_xml
83
+ jruby_min_runtimes jruby_max_runtimes jruby_compat_version
84
+ rackup servlet rack_servlet default_servlet public hosts
83
85
  http ajp ssl extensions
84
86
  apps_base web_apps web_app_dir
85
- monitor log trap }.each do |method|
87
+ monitor reload_strategy log trap }.each do |method|
86
88
  class_eval "def #{method}; self[:'#{method}']; end"
87
89
  class_eval "def #{method}=(value); self[:'#{method}'] = value; end"
88
90
  end
91
+ # TODO #deprecate libs_dir classes_dir servlet
89
92
 
90
93
  # a Hash like #symbolize helper
91
94
  def self.symbolize_options(options, deep = true)
@@ -1,3 +1,5 @@
1
+ require 'trinidad/lifecycle/base'
2
+
1
3
  module Trinidad
2
4
  module Lifecycle
3
5
  # A host lifecycle listener - monitors deployed web apps.
@@ -1,3 +1,6 @@
1
+ require 'trinidad/lifecycle/base'
2
+ require 'trinidad/lifecycle/web_app/shared'
3
+
1
4
  module Trinidad
2
5
  module Lifecycle
3
6
  module WebApp
@@ -14,47 +17,65 @@ module Trinidad
14
17
  configure_context_params(context)
15
18
  configure_context_loader(context)
16
19
  end
17
-
20
+
21
+ def before_init(event)
22
+ super
23
+ set_context_xml event.lifecycle
24
+ # AFTER_INIT_EVENT ContextConfig#init() will pick this up
25
+ end
26
+
18
27
  protected
19
28
 
29
+ @@_add_context_config = true # due backward compatibility
30
+
20
31
  def configure_deployment_descriptor(context)
21
- if descriptor = web_app.deployment_descriptor
32
+ descriptor = web_app.deployment_descriptor
33
+ if descriptor && File.exist?(descriptor)
22
34
  listeners = context.findLifecycleListeners
23
35
  context_config = listeners && listeners.find do |listener|
24
36
  listener.is_a?(Trinidad::Tomcat::ContextConfig)
25
37
  end
26
38
 
27
- unless context_config
28
- context_config = Trinidad::Tomcat::ContextConfig.new
29
- context.addLifecycleListener(context_config)
39
+ if context_config.nil?
40
+ if @@_add_context_config
41
+ context_config = Trinidad::Tomcat::ContextConfig.new
42
+ context.addLifecycleListener(context_config)
43
+ else
44
+ raise "initialized context is missing a ContextConfig listener"
45
+ end
30
46
  end
31
47
 
32
48
  context_config.setDefaultWebXml(descriptor)
49
+ descriptor
33
50
  end
34
- descriptor
35
51
  end
36
52
 
37
53
  def configure_rack_servlet(context)
38
54
  wrapper = context.create_wrapper
39
- if web_app.rack_servlet[:instance]
40
- wrapper.servlet = web_app.rack_servlet[:instance]
55
+ rack_servlet = web_app.rack_servlet
56
+ if rack_servlet[:instance]
57
+ wrapper.servlet = rack_servlet[:instance]
41
58
  else
42
- wrapper.servlet_class = web_app.rack_servlet[:class]
43
- wrapper.async_supported = web_app.rack_servlet[:async_supported]
59
+ wrapper.servlet_class = rack_servlet[:class]
60
+ wrapper.async_supported = rack_servlet[:async_supported]
61
+ wrapper.load_on_startup = rack_servlet[:load_on_startup]
62
+ add_init_params wrapper, rack_servlet[:init_params]
44
63
  end
45
- wrapper.name = web_app.rack_servlet[:name]
64
+ name = wrapper.name = rack_servlet[:name]
46
65
 
47
66
  context.add_child(wrapper)
48
- context.add_servlet_mapping('/*', wrapper.name)
67
+ add_servlet_mapping(context, rack_servlet[:mapping], name)
49
68
  end
50
69
 
51
70
  def configure_rack_listener(context)
52
- context.addApplicationListener(web_app.rack_listener) unless web_app.rack_servlet[:instance]
71
+ unless web_app.rack_servlet[:instance]
72
+ context.add_application_listener(web_app.rack_listener)
73
+ end
53
74
  end
54
75
 
55
76
  def configure_context_params(context)
56
77
  web_app.context_params.each do |name, value|
57
- context.addParameter(name, value)
78
+ context.add_parameter(name, value)
58
79
  end
59
80
  end
60
81
  # @deprecated use {#configure_context_params}
@@ -63,28 +84,41 @@ module Trinidad
63
84
  def configure_context_loader(context)
64
85
  class_loader = web_app.class_loader
65
86
 
66
- add_application_jars(class_loader)
67
87
  add_application_java_classes(class_loader)
88
+ add_application_jars(class_loader) # classes takes precedence !
68
89
 
69
90
  loader = Trinidad::Tomcat::WebappLoader.new(class_loader)
70
91
  context.loader = loader # does loader.container = context
71
92
  end
72
93
 
73
94
  def add_application_jars(class_loader)
74
- return unless web_app.libs_dir
75
-
76
- resources_dir = File.join(web_app.web_app_dir, web_app.libs_dir, '**', '*.jar')
77
-
78
- Dir[resources_dir].each do |resource|
79
- class_loader.addURL(java.io.File.new(resource).to_url)
95
+ return unless lib_dir = web_app.java_lib_dir
96
+ Dir[ File.join(lib_dir, "**/*.jar") ].each do |jar|
97
+ logger.debug "[#{web_app.context_path}] adding jar: #{jar}"
98
+ class_loader.addURL java.io.File.new(jar).to_url
80
99
  end
81
100
  end
82
101
 
83
102
  def add_application_java_classes(class_loader)
84
- return unless web_app.classes_dir
85
-
86
- resources_dir = File.join(web_app.web_app_dir, web_app.classes_dir)
87
- class_loader.addURL(java.io.File.new(resources_dir).to_url)
103
+ return unless classes_dir = web_app.java_classes_dir
104
+ class_loader.addURL java.io.File.new(classes_dir).to_url
105
+ end
106
+
107
+ def set_context_xml(context)
108
+ # behave similar to a .war - checking /META-INF/context.xml on CP
109
+ context_xml = web_app.context_xml
110
+ context_xml = 'META-INF/context.xml' if context_xml.nil?
111
+ if context_xml
112
+ # NOTE: make it absolute to ContextConfig to not use a baseDir :
113
+ unless java.io.File.new(context_xml).absolute?
114
+ if web_app.java_classes_dir
115
+ context_xml = File.join(web_app.java_classes_dir, context_xml)
116
+ else
117
+ context_xml = File.expand_path(context_xml, web_app.root_dir)
118
+ end
119
+ end
120
+ context.setDefaultContextXml(context_xml)
121
+ end
88
122
  end
89
123
 
90
124
  end
@@ -17,37 +17,138 @@ module Trinidad
17
17
  super
18
18
  configure(event.lifecycle)
19
19
  end
20
-
20
+
21
21
  # Configure the web application before it's started.
22
22
  def configure(context)
23
+ adjust_context(context)
23
24
  remove_defaults(context)
25
+ configure_default_servlet(context)
26
+ configure_jsp_servlet(context)
24
27
  configure_logging(context)
25
28
  end
26
29
 
27
30
  protected
28
-
31
+
32
+ def adjust_context(context)
33
+ context.name = web_app.context_name if web_app.context_name
34
+ context.doc_base = web_app.doc_base if web_app.doc_base
35
+ context.work_dir = web_app.work_dir if web_app.work_dir
36
+ context.aliases = web_app.aliases if web_app.aliases
37
+
38
+ context.caching_allowed = web_app.caching_allowed?
39
+ context.cache_ttl = web_app.cache_ttl if web_app.cache_ttl
40
+ if max_size = web_app.cache_max_size
41
+ context.cache_max_size = max_size
42
+ end
43
+ if object_max_size = web_app.cache_object_max_size
44
+ context.cache_object_max_size = object_max_size
45
+ end
46
+ end
47
+
48
+ def configure_default_servlet(context)
49
+ configure_builtin_servlet(context,
50
+ web_app.default_servlet,
51
+ Trinidad::WebApp::DEFAULT_SERVLET_NAME
52
+ )
53
+ end
54
+
55
+ def configure_jsp_servlet(context)
56
+ wrapper = configure_builtin_servlet(context,
57
+ web_app.jsp_servlet,
58
+ Trinidad::WebApp::JSP_SERVLET_NAME
59
+ )
60
+ if wrapper == false # jsp servlet removed
61
+ context.process_tlds = false
62
+ end
63
+ wrapper
64
+ end
65
+
29
66
  def configure_logging(context)
30
67
  Trinidad::Logging.configure_web_app(web_app, context)
31
68
  end
32
-
69
+
33
70
  private
34
71
 
72
+ def configure_builtin_servlet(context, servlet_config, name)
73
+ name_wrapper = context.find_child(name)
74
+ case servlet_config
75
+ when true
76
+ return true # nothing to do leave built-in servlet as is
77
+ when false
78
+ # remove what Tomcat set-up (e.g. use one from web.xml)
79
+ remove_servlet_mapping(context, name)
80
+ context.remove_child(name_wrapper)
81
+ return false
82
+ else
83
+ wrapper, name = name_wrapper, name
84
+ if servlet = servlet_config[:instance]
85
+ wrapper = context.create_wrapper
86
+ wrapper.name = name = servlet_config[:name] || name
87
+ wrapper.servlet = servlet
88
+ context.remove_child(name_wrapper)
89
+ context.add_child(wrapper)
90
+ elsif servlet_class = servlet_config[:class]
91
+ wrapper.servlet_class = servlet_class
92
+ end
93
+ # do not remove wrapper but only "update" the default :
94
+ wrapper.load_on_startup = ( servlet_config[:load_on_startup] ||
95
+ name_wrapper.load_on_startup ).to_i
96
+ add_init_params(wrapper, servlet_config[:init_params])
97
+ if mapping = servlet_config[:mapping]
98
+ # NOTE: we override the default mapping :
99
+ remove_servlet_mapping(context, name)
100
+ add_servlet_mapping(context, mapping, name)
101
+ # else keep the servlet mapping as is ...
102
+ end
103
+ wrapper
104
+ end
105
+ end
106
+
35
107
  def remove_defaults(context)
36
- context.remove_welcome_file('index.jsp')
37
108
  context.remove_welcome_file('index.htm')
38
109
  context.remove_welcome_file('index.html')
39
-
40
- jsp_servlet = context.find_child('jsp')
41
- context.remove_child(jsp_servlet) if jsp_servlet
42
-
43
- context.remove_servlet_mapping('*.jspx')
44
- context.remove_servlet_mapping('*.jsp')
45
-
46
- context.process_tlds = false
47
- context.xml_validation = false
110
+ context.remove_welcome_file('index.jsp')
111
+ end
112
+
113
+ def add_init_params(wrapper, params)
114
+ return unless params
115
+ params.each do |param, value|
116
+ val = value.to_s unless value.nil?
117
+ wrapper.add_init_parameter(param.to_s, val)
118
+ end
119
+ end
120
+
121
+ def add_servlet_mapping(context, mapping, name)
122
+ if mapping.is_a?(String) || mapping.is_a?(Symbol)
123
+ context.add_servlet_mapping(mapping.to_s, name)
124
+ else
125
+ mapping.each { |m| add_servlet_mapping(context, m, name) }
126
+ end
127
+ end
128
+
129
+ # Remove all servlet mappings for given (servlet) name.
130
+ def remove_servlet_mapping(context, name)
131
+ find_servlet_mapping(context, name).each do
132
+ |pattern| context.remove_servlet_mapping(pattern)
133
+ end
134
+ end
135
+
136
+ # Find all servlet mappings for given (servlet) name.
137
+ def find_servlet_mapping(context, name)
138
+ name_mapping = []
139
+ context.find_servlet_mappings.each do |pattern|
140
+ mapping_for = context.find_servlet_mapping(pattern)
141
+ name_mapping << pattern if mapping_for == name
142
+ end
143
+ name_mapping
144
+ end
145
+
146
+ def logger
147
+ @logger ||= Trinidad::Logging::LogFactory.
148
+ getLog('org.apache.catalina.core.StandardContext')
48
149
  end
49
150
 
50
151
  end
51
- end
152
+ end
52
153
  end
53
154
  end