Class: Jettywrapper
- Inherits:
-
Object
- Object
- Jettywrapper
- Includes:
- ActiveSupport::Benchmarkable
- Defined in:
- lib/jettywrapper.rb,
lib/jettywrapper/version.rb
Constant Summary collapse
- VERSION =
"2.0.5"
Class Attribute Summary collapse
Instance Attribute Summary collapse
-
#base_path ⇒ Object
The root of the application.
-
#java_command ⇒ Object
Path to the Java executable.
-
#java_opts ⇒ Object
Options to pass to java (ex. [“-Xmx512mb”, “-Xms128mb”]).
-
#java_version ⇒ Object
Minimum java version.
-
#jetty_home ⇒ Object
Jetty’s home directory.
-
#jetty_opts ⇒ Object
Options to pass to jetty (ex. [“etc/my_jetty.xml”, “etc/other.xml”] as in wiki.eclipse.org/Jetty/Reference/jetty.xml_usage.
-
#port ⇒ Object
Jetty’s port.
-
#quiet ⇒ Object
true (default) to reduce Jetty’s output.
-
#solr_home ⇒ Object
Solr’s home directory.
-
#startup_wait ⇒ Object
How many seconds to wait for jetty to spin up.
Class Method Summary collapse
- .app_root ⇒ Object
- .check_java_version!(java_path, required_java_version) ⇒ Object
- .clean ⇒ Object
-
.configure(params = {}) ⇒ Object
Set the jetty parameters.
- .default_environment ⇒ Object
- .download(url = nil) ⇒ Object
- .expanded_zip_dir(tmp_save_dir) ⇒ Object
- .instance ⇒ Object
-
.is_jetty_running?(params) ⇒ Boolean
Determine whether the jetty at the given jetty_home is running.
-
.is_pid_running?(pid) ⇒ Boolean
Check to see if the pid is actually running.
-
.is_port_in_use?(port) ⇒ Boolean
Check to see if the port is open so we can raise an error if we have a conflict.
- .load_config(config_name = env) ⇒ Object
-
.logger ⇒ Object
If ::Rails.logger is defined and is not nil, it will be returned.
- .logger=(logger) ⇒ Object
-
.pid(params) ⇒ Fixnum
Return the pid of the specified jetty, or return nil if it isn’t running.
- .reset_config ⇒ Object
-
.start(params) ⇒ Object
Convenience method for configuring and starting jetty with one command.
-
.stop(params) ⇒ Jettywrapper.instance
Convenience method for configuring and starting jetty with one command.
- .unzip ⇒ Object
-
.wrap(params) ⇒ Object
Wrap the tests.
- .zip_file ⇒ Object
Instance Method Summary collapse
- #check_java_version! ⇒ Object
- #configure(params) ⇒ Object
-
#initialize(params = {}) ⇒ Jettywrapper
constructor
A new instance of Jettywrapper.
- #java_variables ⇒ Object
-
#jetty_command ⇒ Object
What command is being run to invoke jetty?.
-
#jetty_home_to_pid_file(jetty_home) ⇒ String
Take the @jetty_home value and transform it into a legal filename.
-
#logger ⇒ Object
end of class << self.
-
#pid ⇒ Object
the process id of the currently running jetty instance.
-
#pid_dir ⇒ Object
The directory where the pid_file will be written.
-
#pid_file ⇒ Object
The file where the process ID will be written.
-
#pid_file? ⇒ Boolean
Check to see if there is a pid file already.
-
#pid_path ⇒ Object
The fully qualified path to the pid_file.
- #process ⇒ Object
- #reset_process! ⇒ Object
-
#start ⇒ Object
Start the jetty server.
-
#startup_wait! ⇒ Object
Wait for the jetty server to start and begin listening for requests.
-
#stop ⇒ Object
Instance stop method.
Constructor Details
#initialize(params = {}) ⇒ Jettywrapper
Returns a new instance of Jettywrapper.
32 33 34 35 |
# File 'lib/jettywrapper.rb', line 32 def initialize(params = {}) self.base_path = self.class.app_root configure(params) end |
Class Attribute Details
.env ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/jettywrapper.rb', line 145 def env @env ||= begin case when ENV['JETTYWRAPPER_ENV'] ENV['JETTYWRAPPER_ENV'] when defined?(Rails) && Rails.respond_to?(:env) Rails.env when ENV['RAILS_ENV'] ENV['RAILS_ENV'] when ENV['environment'] ENV['environment'] else default_environment end end end |
.hydra_jetty_version ⇒ Object
55 56 57 |
# File 'lib/jettywrapper.rb', line 55 def hydra_jetty_version @hydra_jetty_version ||= 'master' end |
.jetty_dir ⇒ Object
72 73 74 |
# File 'lib/jettywrapper.rb', line 72 def jetty_dir @jetty_dir ||= 'jetty' end |
.tmp_dir ⇒ Object
64 65 66 |
# File 'lib/jettywrapper.rb', line 64 def tmp_dir @tmp_dir ||= 'tmp' end |
.url ⇒ Object
59 60 61 62 |
# File 'lib/jettywrapper.rb', line 59 def url @url ||= defined?(ZIP_URL) ? ZIP_URL : "https://github.com/projecthydra/hydra-jetty/archive/#{hydra_jetty_version}.zip" @url end |
Instance Attribute Details
#base_path ⇒ Object
The root of the application. Used for determining where log files and PID files should go.
26 27 28 |
# File 'lib/jettywrapper.rb', line 26 def base_path @base_path end |
#java_command ⇒ Object
Path to the Java executable
28 29 30 |
# File 'lib/jettywrapper.rb', line 28 def java_command @java_command end |
#java_opts ⇒ Object
Options to pass to java (ex. [“-Xmx512mb”, “-Xms128mb”])
27 28 29 |
# File 'lib/jettywrapper.rb', line 27 def java_opts @java_opts end |
#java_version ⇒ Object
Minimum java version
29 30 31 |
# File 'lib/jettywrapper.rb', line 29 def java_version @java_version end |
#jetty_home ⇒ Object
Jetty’s home directory
21 22 23 |
# File 'lib/jettywrapper.rb', line 21 def jetty_home @jetty_home end |
#jetty_opts ⇒ Object
Options to pass to jetty (ex. [“etc/my_jetty.xml”, “etc/other.xml”] as in wiki.eclipse.org/Jetty/Reference/jetty.xml_usage
30 31 32 |
# File 'lib/jettywrapper.rb', line 30 def jetty_opts @jetty_opts end |
#port ⇒ Object
Jetty’s port. Default is 8888. Note that attribute is named port, but params passed in expect :jetty_port
22 23 24 |
# File 'lib/jettywrapper.rb', line 22 def port @port end |
#quiet ⇒ Object
true (default) to reduce Jetty’s output
24 25 26 |
# File 'lib/jettywrapper.rb', line 24 def quiet @quiet end |
#solr_home ⇒ Object
Solr’s home directory. Default is jetty_home/solr
25 26 27 |
# File 'lib/jettywrapper.rb', line 25 def solr_home @solr_home end |
#startup_wait ⇒ Object
How many seconds to wait for jetty to spin up. Default is 5.
23 24 25 |
# File 'lib/jettywrapper.rb', line 23 def startup_wait @startup_wait end |
Class Method Details
.app_root ⇒ Object
138 139 140 141 142 143 |
# File 'lib/jettywrapper.rb', line 138 def app_root return @app_root if @app_root @app_root = Rails.root if defined?(Rails) and defined?(Rails.root) @app_root ||= APP_ROOT if defined?(APP_ROOT) @app_root ||= '.' end |
.check_java_version!(java_path, required_java_version) ⇒ Object
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/jettywrapper.rb', line 335 def check_java_version! java_path, required_java_version Tempfile.open("java-version-output") do |f| process = ChildProcess.build(java_path, "-version") process.io.stderr = f process.start begin process.poll_for_exit(10) rescue ChildProcess::TimeoutError process.stop # tries increasingly harsher methods to kill the process. end f.rewind err = f.read java_version = if version = err.match(/java version "([^"]+)"/) version[1] else raise "Java not found, or an error was encountered when running `#{java_path} -version`: #{err}" end unless Gem::Dependency.new('', required_java_version.gsub("_", ".")).match?('', java_version.gsub("_", ".")) raise "Java #{required_java_version} is required to run Jetty. Found Java #{java_version} when running `#{java_path} -version`." end end true end |
.clean ⇒ Object
126 127 128 129 |
# File 'lib/jettywrapper.rb', line 126 def clean FileUtils.remove_dir(jetty_dir,true) unzip end |
.configure(params = {}) ⇒ Object
Set the jetty parameters. It accepts a Hash of symbols.
204 205 206 207 208 209 |
# File 'lib/jettywrapper.rb', line 204 def configure(params = {}) jetty_server = self.instance jetty_server.reset_process! jetty_server.configure params return jetty_server end |
.default_environment ⇒ Object
162 163 164 |
# File 'lib/jettywrapper.rb', line 162 def default_environment 'development' end |
.download(url = nil) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/jettywrapper.rb', line 76 def download(url = nil) return if File.exists? zip_file self.url = url if url logger.info "Downloading jetty at #{self.url} ..." FileUtils.mkdir tmp_dir unless File.exists? tmp_dir begin open(self.url) do |io| IO.copy_stream(io,zip_file) end rescue Exception => e abort "Unable to download jetty from #{self.url} #{e.}" end end |
.expanded_zip_dir(tmp_save_dir) ⇒ Object
120 121 122 123 124 |
# File 'lib/jettywrapper.rb', line 120 def (tmp_save_dir) # This old way is more specific, but won't work for blacklight-jetty #expanded_dir = Dir[File.join(tmp_save_dir, "hydra-jetty-*")].first Dir[File.join(tmp_save_dir, "*")].first end |
.instance ⇒ Object
211 212 213 |
# File 'lib/jettywrapper.rb', line 211 def instance @instance ||= Jettywrapper.new end |
.is_jetty_running?(params) ⇒ Boolean
Determine whether the jetty at the given jetty_home is running
283 284 285 286 287 288 |
# File 'lib/jettywrapper.rb', line 283 def is_jetty_running?(params) Jettywrapper.configure(params) pid = Jettywrapper.instance.pid return false unless pid true end |
.is_pid_running?(pid) ⇒ Boolean
Check to see if the pid is actually running. This only works on unix.
327 328 329 330 331 332 333 |
# File 'lib/jettywrapper.rb', line 327 def is_pid_running?(pid) begin return Process.getpgid(pid) != -1 rescue Errno::ESRCH return false end end |
.is_port_in_use?(port) ⇒ Boolean
Check to see if the port is open so we can raise an error if we have a conflict
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/jettywrapper.rb', line 307 def is_port_in_use?(port) begin Timeout::timeout(1) do begin s = TCPSocket.new('127.0.0.1', port) s.close return true rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH return false rescue return false end end rescue Timeout::Error end return false end |
.load_config(config_name = env) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/jettywrapper.rb', line 166 def load_config(config_name = env) @env = config_name jetty_file = "#{app_root}/config/jetty.yml" unless File.exists?(jetty_file) logger.warn "Didn't find expected jettywrapper config file at #{jetty_file}, using default file instead." jetty_file = File.("../config/jetty.yml", File.dirname(__FILE__)) end begin jetty_erb = ERB.new(IO.read(jetty_file)).result(binding) rescue raise("jetty.yml was found, but could not be parsed with ERB. \n#{$!.inspect}") end begin jetty_yml = YAML::load(jetty_erb) rescue raise("jetty.yml was found, but could not be parsed.\n") end if jetty_yml.nil? || !jetty_yml.is_a?(Hash) raise("jetty.yml was found, but was blank or malformed.\n") end config = jetty_yml.with_indifferent_access config[config_name] || config['default'.freeze] end |
.logger ⇒ Object
If ::Rails.logger is defined and is not nil, it will be returned. If no logger has been defined, a new STDOUT Logger will be created.
370 371 372 |
# File 'lib/jettywrapper.rb', line 370 def logger @@logger ||= defined?(::Rails) && Rails.logger ? ::Rails.logger : ::Logger.new(STDOUT) end |
.logger=(logger) ⇒ Object
364 365 366 |
# File 'lib/jettywrapper.rb', line 364 def logger=(logger) @@logger = logger end |
.pid(params) ⇒ Fixnum
Return the pid of the specified jetty, or return nil if it isn’t running
295 296 297 298 299 300 |
# File 'lib/jettywrapper.rb', line 295 def pid(params) Jettywrapper.configure(params) pid = Jettywrapper.instance.pid return nil unless pid pid end |
.reset_config ⇒ Object
131 132 133 134 135 136 |
# File 'lib/jettywrapper.rb', line 131 def reset_config @app_root = nil @env = nil @url = nil @hydra_jetty_version = nil end |
.start(params) ⇒ Object
Convenience method for configuring and starting jetty with one command
258 259 260 261 262 263 |
# File 'lib/jettywrapper.rb', line 258 def start(params) unzip unless File.exists? jetty_dir Jettywrapper.configure(params) Jettywrapper.instance.start return Jettywrapper.instance end |
.stop(params) ⇒ Jettywrapper.instance
Convenience method for configuring and starting jetty with one command. Note that for stopping, only the :jetty_home value is required (including other values won’t hurt anything, though).
272 273 274 275 276 |
# File 'lib/jettywrapper.rb', line 272 def stop(params) Jettywrapper.configure(params) Jettywrapper.instance.stop return Jettywrapper.instance end |
.unzip ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/jettywrapper.rb', line 91 def unzip download unless File.exists? zip_file logger.info "Unpacking #{zip_file}..." tmp_save_dir = File.join tmp_dir, 'jetty_generator' begin Zip::File.open(zip_file) do |zip_file| # Handle entries one by one zip_file.each do |entry| dest_file = File.join(tmp_save_dir,entry.name) FileUtils.remove_entry(dest_file,true) entry.extract(dest_file) end end rescue Exception => e abort "Unable to unzip #{zip_file} into tmp_save_dir/ #{e.}" end # Remove the old jetty directory if it exists FileUtils.remove_dir(jetty_dir,true) # Move the expanded zip file into the final destination. = (tmp_save_dir) begin FileUtils.mv(, jetty_dir) rescue Exception => e abort "Unable to move #{} into #{jetty_dir}/ #{e.}" end end |
.wrap(params) ⇒ Object
Wrap the tests. Startup jetty, yield to the test task, capture any errors, shutdown jetty, and return the error.
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/jettywrapper.rb', line 234 def wrap(params) error = false jetty_server = self.configure(params) begin jetty_server.start yield rescue error = $! logger.error "*** Error starting jetty: #{error}" ensure # puts "stopping jetty server" jetty_server.stop end raise error if error return error end |
.zip_file ⇒ Object
68 69 70 |
# File 'lib/jettywrapper.rb', line 68 def zip_file ENV['JETTY_ZIP'] || File.join(tmp_dir, url.split('/').last) end |
Instance Method Details
#check_java_version! ⇒ Object
390 391 392 393 394 |
# File 'lib/jettywrapper.rb', line 390 def check_java_version! if java_version @checked_java_version ||= Jettywrapper.check_java_version!(java_command, java_version) end end |
#configure(params) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/jettywrapper.rb', line 37 def configure params self.quiet = params[:quiet].nil? ? true : params[:quiet] self.jetty_home = params[:jetty_home ] || File.(File.join(self.base_path, 'jetty')) self.solr_home = params[:solr_home ] || File.join( self.jetty_home, "solr") self.port = params[:jetty_port ] || 8888 self.startup_wait = params[:startup_wait] || 5 self.java_opts = params[:java_opts ] || [] self.java_command = params[:java_command] || default_java_command self.java_version = params[:java_version] self.jetty_opts = params[:jetty_opts ] || [] end |
#java_variables ⇒ Object
385 386 387 388 |
# File 'lib/jettywrapper.rb', line 385 def java_variables ["-Djetty.port=#{@port}", "-Dsolr.solr.home=#{Shellwords.escape(@solr_home)}"] end |
#jetty_command ⇒ Object
What command is being run to invoke jetty?
381 382 383 |
# File 'lib/jettywrapper.rb', line 381 def jetty_command [java_command, java_variables, java_opts, "-jar", "start.jar", jetty_opts].flatten end |
#jetty_home_to_pid_file(jetty_home) ⇒ String
Take the @jetty_home value and transform it into a legal filename
510 511 512 513 514 515 516 |
# File 'lib/jettywrapper.rb', line 510 def jetty_home_to_pid_file(jetty_home) begin jetty_home.gsub(/\//,'_') << "_#{self.class.env}" << ".pid" rescue Exception => e raise "Couldn't make a pid file for jetty_home value #{jetty_home}\n Caused by: #{e}" end end |
#logger ⇒ Object
end of class << self
376 377 378 |
# File 'lib/jettywrapper.rb', line 376 def logger self.class.logger end |
#pid ⇒ Object
the process id of the currently running jetty instance
530 531 532 |
# File 'lib/jettywrapper.rb', line 530 def pid File.open( pid_path ) { |f| return f.gets.to_i } if File.exist?(pid_path) end |
#pid_dir ⇒ Object
The directory where the pid_file will be written
519 520 521 |
# File 'lib/jettywrapper.rb', line 519 def pid_dir File.(File.join(base_path,'tmp','pids')) end |
#pid_file ⇒ Object
The file where the process ID will be written
502 503 504 |
# File 'lib/jettywrapper.rb', line 502 def pid_file jetty_home_to_pid_file(@jetty_home) end |
#pid_file? ⇒ Boolean
Check to see if there is a pid file already
525 526 527 |
# File 'lib/jettywrapper.rb', line 525 def pid_file? File.exist?(pid_path) end |
#pid_path ⇒ Object
The fully qualified path to the pid_file
496 497 498 499 |
# File 'lib/jettywrapper.rb', line 496 def pid_path #need to memoize this, becasuse the base path could be relative and the cwd can change in the yield block of wrap @path ||= File.join(pid_dir, pid_file) end |
#process ⇒ Object
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
# File 'lib/jettywrapper.rb', line 453 def process @process ||= begin process = ChildProcess.build(*jetty_command) if self.quiet process.io.stderr = File.open(File.("jettywrapper.log"), "w+") process.io.stdout = process.io.stderr logger.warn "Logging jettywrapper stdout to #{File.(process.io.stderr.path)}" else process.io.inherit! end process.detach = true process end end |
#reset_process! ⇒ Object
469 470 471 |
# File 'lib/jettywrapper.rb', line 469 def reset_process! @process = nil end |
#start ⇒ Object
Start the jetty server. Check the pid file to see if it is running already, and stop it if so. After you start jetty, write the PID to a file. This is the instance start method. It must be called on Jettywrapper.instance You’re probably better off using Jettywrapper.start(:jetty_home => “/path/to/jetty”)
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/jettywrapper.rb', line 404 def start logger.debug "Starting jetty with these values: " logger.debug "jetty_home: #{@jetty_home}" logger.debug "jetty_command: #{jetty_command.join(' ')}" check_java_version! # Check to see if we can start. # 1. If there is a pid, check to see if it is really running # 2. Check to see if anything is blocking the port we want to use if pid if Jettywrapper.is_pid_running?(pid) raise("Server is already running with PID #{pid}") else logger.warn "Removing stale PID file at #{pid_path}" File.delete(pid_path) end end if Jettywrapper.is_port_in_use?(self.port) raise("Port #{self.port} is already in use.") end benchmark "Started jetty" do Dir.chdir(@jetty_home) do process.start end FileUtils.makedirs(pid_dir) unless File.directory?(pid_dir) begin f = File.new(pid_path, "w") rescue Errno::ENOENT, Errno::EACCES f = File.new(File.join(base_path,'tmp',pid_file),"w") end f.puts "#{process.pid}" f.close logger.debug "Wrote pid file to #{pid_path} with value #{process.pid}" startup_wait! end end |
#startup_wait! ⇒ Object
Wait for the jetty server to start and begin listening for requests
443 444 445 446 447 448 449 450 451 |
# File 'lib/jettywrapper.rb', line 443 def startup_wait! begin Timeout::timeout(startup_wait) do sleep 1 until (Jettywrapper.is_port_in_use? self.port) end rescue Timeout::Error logger.warn "Waited #{startup_wait} seconds for jetty to start, but it is not yet listening on port #{self.port}. Continuing anyway." end end |
#stop ⇒ Object
Instance stop method. Must be called on Jettywrapper.instance You’re probably better off using Jettywrapper.stop(:jetty_home => “/path/to/jetty”)
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/jettywrapper.rb', line 479 def stop logger.debug "Instance stop method called for pid '#{pid}'" if pid if @process @process.stop else Process.kill("KILL", pid) rescue nil end begin File.delete(pid_path) rescue end end end |