jruby-quartz 1.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright (c) 2009 Nick Zalabak
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ Unless required by applicable law or agreed to in writing, software distributed under
7
+ the License is distributed on an "AS IS" BASIS,
8
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9
+ either express or implied.
10
+ See the License for the specific language governing permissions and
11
+ limitations under the License.
data/README ADDED
@@ -0,0 +1,74 @@
1
+ = jruby-quartz
2
+
3
+ == Instructions
4
+
5
+ Requires the following jars in your application container and if running with just jruby place these in your $JRUBY_HOME/lib
6
+
7
+ commons-collections-3.2.x.jar
8
+ commons-logging.jar
9
+ log4j.jar
10
+ quartz-1.6.x.jar
11
+
12
+ If you are running a current version of JBoss you already have these!
13
+ If you are running an alternative container you will need to check it's lib
14
+ directory for the presence of these jars.
15
+
16
+ If you need these jars you can find them within the apache commons project and
17
+ the quartz jar on opensymphony
18
+
19
+ == Installation
20
+
21
+ gem install git://github.com/techwhizbang/jruby-quartz.git
22
+
23
+ == Usage
24
+
25
+ The best way to leverage jruby-quartz is to simply extend the BaseScheduler and
26
+ implement any number of jobs you need to run.
27
+
28
+ For example all you need to do is specify some basic attributes including the
29
+ cron expression representing the frequency of the job(s) you want to with it:
30
+
31
+ class IntegrationScheduler < BaseScheduler
32
+
33
+ def initialize(cron_expression)
34
+ super
35
+ @cron_expression = cron_expression
36
+ @base_jobs_group = "IntegrationJobs"
37
+ @base_triggers_group = "IntegrationTriggers"
38
+ end
39
+ end
40
+
41
+ Then just extend the base job by putting all of the work you want to perform inside the
42
+ perform_job method.
43
+
44
+ class IntegrationJob < Jobs::BaseJob
45
+
46
+ def perform_job
47
+ worker_one = mock('worker class one', :whatever => "123")
48
+ worker_two = mock('worker class two', :whatever => '123')
49
+ end
50
+ end
51
+
52
+ If you are running Rails you can throw the schedule! method into a custom initializer.
53
+ An example of this would be like so:
54
+ Notice the Rails.env /container/, I defined custom environments that only run when
55
+ inside a Java container so that the schedule! method doesn't get fired off during
56
+ testing.
57
+
58
+
59
+ if RUBY_PLATFORM =~ /java/
60
+
61
+ LoggerOneScheduler.new("0 0/1 * * * ?").schedule!(Jobs::LoggerOneJob)
62
+ LoggerTwoScheduler.new("0 0/2 * * * ?").schedule!(Jobs::LoggerTwoJob)
63
+
64
+ end
65
+
66
+ If you are planning on using this with a Rails stack, I would recommend using this
67
+ only with Rails 2.2 or higher because thread safety == 1 runtime
68
+
69
+ 1 runtime means your schedule initializer is only called once.
70
+
71
+ === Other
72
+
73
+ Problems, comments, and suggestions all welcome. techwhizbang@gmail.com or visit my blog
74
+ http://techwhizbang.com
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/rdoctask'
4
+
5
+ task :default => :test
6
+
7
+ task :test do
8
+ require File.dirname(__FILE__) + '/test/all_tests.rb'
9
+ end
10
+
11
+ desc 'Generate RDoc'
12
+ Rake::RDocTask.new do |task|
13
+ task.main = 'README'
14
+ task.title = 'jruby-quartz'
15
+ task.rdoc_dir = 'doc'
16
+ task.options << "--line-numbers" << "--inline-source"
17
+ task.rdoc_files.include('README', 'lib/**/*.rb')
18
+ end
19
+
20
+ specification = Gem::Specification.new do |s|
21
+ s.name = "jruby-quartz"
22
+ s.summary = "Jruby-Quartz is a wrapper library for the Java based Quartz scheduling framework."
23
+ s.version = "1.2"
24
+ s.author = 'Nick Zalabak'
25
+ s.description = "Jruby-Quartz is a wrapper library for the Java based Quartz scheduling framework."
26
+ s.email = 'techwhizbang@gmail.com'
27
+ s.homepage = 'http://techwhizbang.com'
28
+ s.rubyforge_project = 'Jruby-Quartz'
29
+
30
+ s.has_rdoc = true
31
+ s.extra_rdoc_files = ['README']
32
+ s.rdoc_options << '--title' << 'Jruby-Quartz' << '--main' << 'README' << '--line-numbers'
33
+
34
+ s.autorequire = 'jruby-quartz'
35
+ s.files = FileList['{lib,test}/**/*.rb', 'LICENSE', 'README', 'Rakefile'].to_a
36
+ s.test_file = "test/all_tests.rb"
37
+ end
38
+
39
+ Rake::GemPackageTask.new(specification) do |package|
40
+ package.need_zip = false
41
+ package.need_tar = false
42
+ end
Binary file
Binary file
data/java/log4j.jar ADDED
Binary file
Binary file
@@ -0,0 +1,81 @@
1
+ java_import org.quartz.SchedulerFactory
2
+ java_import org.quartz.SchedulerException
3
+ java_import org.quartz.Scheduler
4
+ java_import org.quartz.JobDetail
5
+ java_import org.quartz.CronTrigger
6
+ java_import org.quartz.SimpleTrigger
7
+ java_import org.quartz.impl.StdSchedulerFactory
8
+
9
+ class BaseScheduler
10
+ attr_reader :scheduler_factory
11
+
12
+ attr_accessor :base_jobs_group, :base_triggers_group
13
+ attr_accessor :job_name, :trigger_name, :cron_expression
14
+
15
+ def initialize(cron_expression=nil)
16
+ @scheduler_factory = initialize_scheduler_factory
17
+ @base_jobs_group = "BaseJobsGroup"
18
+ @base_triggers_group = "BaseTriggersGroup"
19
+ @job_name = "BaseJob"
20
+ @trigger_name = "BaseTrigger"
21
+ @cron_expression = cron_expression
22
+ end
23
+
24
+ def fire!(job_class, options={})
25
+ begin
26
+ scheduler = scheduler_factory.get_scheduler
27
+ scheduler.trigger_job(self.job_name, self.base_jobs_group)
28
+ rescue Exception => e
29
+ raise SchedulerError.new(e)
30
+ end
31
+ end
32
+
33
+ def schedule!(job_class, options={})
34
+ begin
35
+ scheduler = scheduler_factory.get_scheduler
36
+ detail = job_detail_setup(scheduler, job_class)
37
+ current_trigger = cron_trigger.new(self.trigger_name,
38
+ self.base_triggers_group,
39
+ self.job_name,
40
+ self.base_jobs_group,
41
+ self.cron_expression)
42
+ scheduler.schedule_job(detail, current_trigger)
43
+ rescue Exception => e
44
+ raise SchedulerError.new(e)
45
+ end
46
+ end
47
+
48
+ protected
49
+
50
+ def job_detail_setup(scheduler, job_class)
51
+ scheduler.set_job_factory(job_factory.new)
52
+ detail = job_detail.new(self.job_name,
53
+ self.base_jobs_group,
54
+ job_class.new())
55
+ detail
56
+ end
57
+
58
+ def trigger
59
+ SimpleTrigger
60
+ end
61
+
62
+ def initialize_scheduler_factory(options={})
63
+ StdSchedulerFactory.new
64
+ end
65
+
66
+ def job_factory
67
+ Jobs::BaseJobFactory
68
+ end
69
+
70
+ def job_detail
71
+ Jobs::BaseJobDetail
72
+ end
73
+
74
+ def cron_trigger
75
+ CronTrigger
76
+ end
77
+
78
+ class SchedulerError < StandardError; end
79
+
80
+ end
81
+
@@ -0,0 +1,30 @@
1
+ java_import org.quartz.Job
2
+ java_import org.quartz.JobExecutionContext
3
+ java_import org.quartz.JobExecutionException
4
+
5
+ module Jobs
6
+ class BaseJob
7
+ include org.quartz.Job
8
+ implement org.quartz.Job
9
+
10
+ def initialize(); end
11
+
12
+ def execute(context)
13
+ begin
14
+ perform_job
15
+ rescue Exception => e
16
+ raise JobError.new(e)
17
+ end
18
+ end
19
+
20
+ def perform_job
21
+ raise "Subclass must implement the perform job method"
22
+ end
23
+
24
+ end
25
+
26
+ class JobError < StandardError ; end
27
+ end
28
+
29
+
30
+
@@ -0,0 +1,27 @@
1
+ java_import org.quartz.JobDetail
2
+ java_import org.quartz.SchedulerException
3
+
4
+ module Jobs
5
+ class BaseJobDetail < org.quartz.JobDetail
6
+
7
+ attr_accessor :job
8
+
9
+ def initialize(name, group, job)
10
+ super()
11
+ set_name name
12
+ set_group group
13
+ @job = job
14
+ end
15
+
16
+ def validate
17
+ raise org.quartz.SchedulerException.new("Job's name cannot be null",
18
+ org.quartz.SchedulerException.ERR_CLIENT_ERROR) if get_name == nil
19
+ raise org.quartz.SchedulerException.new("Job's group cannot be null",
20
+ org.quartz.SchedulerException.ERR_CLIENT_ERROR) if get_group == nil
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+
27
+
@@ -0,0 +1,15 @@
1
+ java_import org.quartz.spi.JobFactory
2
+ java_import org.quartz.spi.TriggerFiredBundle
3
+ java_import org.quartz.JobDetail
4
+
5
+ module Jobs
6
+ class BaseJobFactory
7
+ include org.quartz.spi.JobFactory
8
+
9
+ def new_job bundle
10
+ bundle.get_job_detail.job
11
+ end
12
+ end
13
+ end
14
+
15
+
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/base_scheduler')
2
+ require File.expand_path(File.dirname(__FILE__) + '/jobs/base_job')
3
+ require File.expand_path(File.dirname(__FILE__) + '/jobs/base_job_detail')
4
+ require File.expand_path(File.dirname(__FILE__) + '/jobs/base_job_factory')
5
+
6
+ module JrubyQuartz
7
+ VERSION = '1.2'
8
+ end
data/test/all_tests.rb ADDED
@@ -0,0 +1 @@
1
+ Dir['**/*_test.rb'].each { |test_case| require test_case }
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class IntegrationScheduler < BaseScheduler
4
+
5
+ def initialize(cron_expression)
6
+ super
7
+ @job_name = "IntegrationJob"
8
+ @trigger_name = "IntegrationTrigger"
9
+ @base_jobs_group = "IntegrationJobs"
10
+ @base_triggers_group = "IntegrationTriggers"
11
+ @cron_expression = cron_expression
12
+ end
13
+ end
14
+
15
+ class IntegrationJob < Jobs::BaseJob
16
+
17
+ def perform_job
18
+ worker_one = mock('worker class one', :whatever => "123")
19
+ worker_two = mock('worker class two', :whatever => '123')
20
+ end
21
+ end
22
+
23
+ class JrubyQuartzIntegrationTest < Test::Unit::TestCase
24
+
25
+ def test_scheduler_implementation
26
+ integration_scheduler = IntegrationScheduler.new "0 0/1 * * * ?"
27
+
28
+ #must stub the scheduler and scheduler factory to avoid invokation of real Quartz thread pool, etc.
29
+ scheduler = mock('scheduler')
30
+ scheduler_factory = mock('scheduler factory', :get_scheduler => scheduler)
31
+
32
+ scheduler.expects(:schedule_job)
33
+ scheduler.expects(:set_job_factory)
34
+
35
+ integration_scheduler.expects(:scheduler_factory).returns(scheduler_factory)
36
+ integration_scheduler.schedule!(IntegrationJob)
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'mocha'
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/jruby-quartz")
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class BaseJobDetailTest < Test::Unit::TestCase
4
+
5
+ def test_initialization
6
+ assert_instance_of(Jobs::BaseJobDetail, Jobs::BaseJobDetail.new("Name", "Group", "Job"))
7
+ end
8
+
9
+ def test_initialization_with_failed_validation
10
+ assert_raise(NativeException) { Jobs::BaseJobDetail.new(nil, nil, nil) }
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class BaseJobFactoryTest < Test::Unit::TestCase
4
+
5
+ def test_new_job
6
+ job = mock('job')
7
+ job_detail = mock('job detail', :job => job)
8
+ bundle = mock('bundle', :get_job_detail => job_detail)
9
+ Jobs::BaseJobFactory.new.new_job(bundle)
10
+ end
11
+
12
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class BaseJobTest < Test::Unit::TestCase
4
+
5
+ def test_initialize
6
+ assert_instance_of(Jobs::BaseJob, Jobs::BaseJob.new)
7
+ end
8
+
9
+ def test_quartz_job_implement
10
+ assert_kind_of(org.quartz.Job, Jobs::BaseJob.new)
11
+ end
12
+
13
+ def test_execute
14
+ context = mock('context')
15
+ job = Jobs::BaseJob.new
16
+ job.expects(:perform_job)
17
+ job.execute(context)
18
+ end
19
+
20
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class BaseSchedulerTest < Test::Unit::TestCase
4
+
5
+ # def test_singleton_initialization
6
+ # assert_raise(NoMethodError) { BaseScheduler.new }
7
+ # assert_not_nil(BaseScheduler.instance)
8
+ # end
9
+
10
+ def test_scheduler_instance_variables
11
+ scheduler = BaseScheduler.new "0 0/1 * * * ?"
12
+ assert_equal scheduler.base_jobs_group, "BaseJobsGroup"
13
+ assert_equal scheduler.job_name, "BaseJob"
14
+ assert_equal scheduler.base_triggers_group, "BaseTriggersGroup"
15
+ assert_equal scheduler.trigger_name, "BaseTrigger"
16
+ assert_equal scheduler.cron_expression, "0 0/1 * * * ?"
17
+ end
18
+
19
+ def test_trigger_class
20
+ scheduler = BaseScheduler.new stub
21
+ assert_kind_of(org.quartz.SimpleTrigger, scheduler.send(:trigger).new)
22
+ end
23
+
24
+ def test_job_factory_class
25
+ scheduler = BaseScheduler.new stub
26
+ assert_kind_of(Jobs::BaseJobFactory, scheduler.send(:job_factory).new)
27
+ end
28
+
29
+ def test_job_detail_class
30
+ scheduler = BaseScheduler.new stub
31
+ assert_kind_of(Jobs::BaseJobDetail, scheduler.send(:job_detail).new("JobName",
32
+ 'JobGroup',
33
+ 'JobClass'))
34
+ end
35
+
36
+ def test_scheduler_factory_class
37
+ scheduler = BaseScheduler.new stub
38
+ assert_kind_of(StdSchedulerFactory, scheduler.send(:initialize_scheduler_factory))
39
+ end
40
+
41
+ def test_cron_trigger_class
42
+ scheduler = BaseScheduler.new stub
43
+ assert_kind_of(CronTrigger, scheduler.send(:cron_trigger).new)
44
+ end
45
+
46
+ def test_schedule_method
47
+ base_scheduler = BaseScheduler.new stub
48
+ base_job = mock("base job")
49
+ scheduler = mock('scheduler')
50
+ job_factory = mock('job factory')
51
+ job_detail = mock('job detail')
52
+ cron_trigger = mock('cron trigger')
53
+ scheduler_factory = mock('scheduler factory', :get_scheduler => scheduler)
54
+
55
+ base_scheduler.expects(:scheduler_factory).returns(scheduler_factory)
56
+
57
+ job_factory.expects(:new).returns(job_factory)
58
+ base_job.expects(:new).returns(base_job)
59
+ job_detail.expects(:new).returns(job_detail)
60
+ cron_trigger.expects(:new).returns(cron_trigger)
61
+
62
+ scheduler.expects(:set_job_factory).with(job_factory)
63
+ scheduler.expects(:schedule_job).with(job_detail, cron_trigger)
64
+
65
+ base_scheduler.stubs(:job_detail).returns(job_detail)
66
+ base_scheduler.stubs(:job_factory).returns(job_factory)
67
+ base_scheduler.stubs(:cron_trigger).returns(cron_trigger)
68
+ base_scheduler.schedule!(base_job)
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jruby-quartz
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.2"
5
+ platform: ruby
6
+ authors:
7
+ - Nick Zalabak
8
+ autorequire: jruby-quartz
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-17 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Jruby-Quartz is a wrapper library for the Java based Quartz scheduling framework.
17
+ email: techwhizbang@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - lib/base_scheduler.rb
26
+ - lib/jruby-quartz.rb
27
+ - lib/jobs/base_job.rb
28
+ - lib/jobs/base_job_detail.rb
29
+ - lib/jobs/base_job_factory.rb
30
+ - test/integration/jruby_quartz_integration_test.rb
31
+ - test/unit/base_job_detail_test.rb
32
+ - test/unit/base_job_factory_test.rb
33
+ - test/unit/base_job_test.rb
34
+ - test/unit/base_scheduler_test.rb
35
+ - test/all_tests.rb
36
+ - test/test_helper.rb
37
+ - java/commons-collections-3.2.1.jar
38
+ - java/commons-logging.jar
39
+ - java/log4j.jar
40
+ - java/quartz-1.6.4.jar
41
+ - LICENSE
42
+ - README
43
+ - Rakefile
44
+ has_rdoc: true
45
+ homepage: http://techwhizbang.com
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --title
51
+ - Jruby-Quartz
52
+ - --main
53
+ - README
54
+ - --line-numbers
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: A JRuby implementation of the Quartz scheduling framework that makes it easy to integrate into Ruby and Rails based projects.
76
+ test_files: []
77
+