Download Word - Terracotta Project Issue Tracker

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
[QTZ-252] Provide rfc2445 format to represent recurrence rules of triggers
Created: 28/Nov/11 Updated: 07/Jan/14
Status:
Project:
Component/s:
Affects
Version/s:
Fix Version/s:
New
Quartz Scheduler (Historical - Do Not File New Issues Here - See GitHub)
Triggers
2.2
Type:
Reporter:
Resolution:
Labels:
Remaining
Estimate:
Time Spent:
Original
Estimate:
New Feature
Philip Weber
Unresolved
None
Not Specified
Attachments:
quartz-rfc5545_20131212.zip
quartz-rfc5545_20131213.zip
rfc5545.zip
Pending
Terracotta
Target:
3.0
Priority:
Assignee:
Votes:
2 Major
James House
8
Not Specified
Not Specified
quartz-rfc5545_20131212.zip
quartz-rfc5545.zip
quartz-
Description
Quartz scheduler does provide the creation of a trigger by cronSchedule like this:
trigger = newTrigger()
.withIdentity("trigger3", "group1")
.startNow()
.withSchedule(cronSchedule("0 0 15 ? * WED")) // fire every wednesday at
15:00
.build();
Because it is not possible to represent every recurrence rule of triggers by CronTrigger as
described in http://www.quartz-scheduler.org/documentation/quartz2.1.x/cookbook/BiDailyTrigger it would be nice to have support for rfc2445 format that should
cover every possible rule. Please have a look at tools.ietf.org/html/rfc2445#section-4.3.10 for
further information.
Example:
trigger = newTrigger()
.withIdentity("trigger3", "group1")
.startAt(todayAt(15, 0, 0))
// at 15:00
.withSchedule(rfcSchedule("RRULE:FREQ=WEEKLY;BYDAY=WE")) // fire every
wednesday
.build();
Concerning persistence of a trigger, it also would be useful to have an export to rfc2445 format.
Comments
Comment by Nestor Urquiza [ 08/Apr/13 ]
Hi,
This is marked as "Fix Version 3.0" however I do not see a branch for that version in http://svn.terracotta.org/svn
starting this feature?
This is a highly needed feature as far as I can tell.
Thanks!

Nestor
Comment by James House [ 08/Apr/13 ]
This feature is unlikely to be worked on in the next calendar year - unless a community member wants to donate
Comment by Nestor Urquiza [ 08/Apr/13 ]
Thanks you James for the fast response. http://tools.ietf.org/html/rfc5545 has made obsolete rfc2445, then there
http://sourceforge.net/projects/ical4j/ which could be used to parse ics files.
You can filter events through http://wiki.modularity.net.au/ical4j/index.php?title=Examples#Filtering_events so
matches the ICS entry.
So I guess there are two questions:
1. Will the ical4j license (http://build.mnode.org/projects/ical4j/license.html) be OK to become a candidate for a
2. As a raw estimate how long would it take to use Filtering Events from Quartz in a way that a stored RRC2445
Thanks again for your feedback,

Nestor
Comment by Olivier Queyrut [ 19/Jun/13 ]
Hi,
I am new in this community but very interested in the Quartz features.
For one of my project, I'd like to have a trigger based on the recurrence rule as defined by RFC 5545 because I fi
expression.
I tried to use ical4j but the results are not those I expected (from my point of view and according to the tests I did
algorithm implemented in the Recur class).
So, I decided to implement the RFC 5545 "RRULE" from scratch. I also implemented a trigger named Recurren
Here is the result of my job that I can donate if you are interested in !
Please send me your feedbacks.
Comment by James House [ 20/Jun/13 ]
Thanks for your participation!
To consider acceptance of your contribution, we would need you to fill-out and return a contributor's agreement.
http://www.terracotta.org/confluence/download/attachments/27918462/Individual+Contributor+Agreement.pdf?
Comment by Olivier Queyrut [ 21/Jun/13 ]
Hi,
Since Wednesday, I have done some other tests of the RecurrenceRuleTrigger and I have fixed a few bugs. Now
The updated source code is attached.
Regards,
Olivier
Comment by Narayanan Raghuvaran [ 06/Dec/13 ]
Hi Olivier
Thanks a million for the source code for recurrence rules. Howevere when I tried to save the recurrence rule to Q
exception. The recurrence rule is "FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU"
Please help
and the exception I get is org.quartz.JobPersistenceException: Couldn't store trigger 'DEFAULT.6da64b5bd2ee'DEFAULT. A Simple Task_junituser_1_1_1393448440' job:org.quartz.RecurrenceRule$ByDay [See nested ex
org.quartz.RecurrenceRule$ByDay]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1212)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$2.execute(JobStoreSupport.java:1052)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$45.execute(JobStoreSupport.java:3726)
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInLock(JobStoreSupport.java:3722)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJobAndTrigger(JobStoreSupport.java:1047)
at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:840)
at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:250)
at com.riverbed.ucx.job.service.JobServiceImpl._submitJob(JobServiceImpl.java:180)
at com.riverbed.ucx.job.service.JobServiceImpl.submitJob(JobServiceImpl.java:103)
at com.riverbed.ucx.job.service.JobServiceImpl.submitJob(JobServiceImpl.java:876)
at com.riverbed.ucx.job.service.JobServiceImpl$$FastClassByCGLIB$$cb8d23b2.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.
at com.riverbed.ucx.job.service.JobServiceImpl$$EnhancerByCGLIB$$c22adc9d.submitJob(<generated>)
at com.riverbed.ucx.scheduler.service.TaskServiceImpl.addTask(TaskServiceImpl.java:176)
at com.riverbed.ucx.scheduler.service.TaskServiceImpl$$FastClassByCGLIB$$fff0d8b4.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProx
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.
at com.riverbed.ucx.scheduler.service.TaskServiceImpl$$EnhancerByCGLIB$$38b6c35f.addTask(<generated>
at com.riverbed.ucx.scheduler.service.TaskServiceTest.testCreateTask(TaskServiceTest.java:367)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestM
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMe
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:23
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestCla
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassC
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.io.NotSerializableException: org.quartz.RecurrenceRule$ByDay
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.ArrayList.writeObject(ArrayList.java:710)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertBlobTrigger(StdJDBCDelegate.java:1131)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertTrigger(StdJDBCDelegate.java:1100)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1209)
... 54 more
Comment by Olivier Queyrut [ 11/Dec/13 ]
Hello,
I have updated the source code so that the RecurrenceRule class is properly serialized / deserialized.
Unfortunately, I haven't a test case with a database.
Could you please try the updated version and send me a feedback ?
Question to the quartz team : any idea when this feature could be integrated in the Quartz library ?
Thanks,
Olivier
Comment by Olivier Queyrut [ 11/Dec/13 ]
Erratum with previous zip file. Use this one.
Sorry for inconvenience.
Comment by Narayanan Raghuvaran [ 12/Dec/13 ]
Hi Olivier
Thanks a million for the help so far. With the change, serialization of by day works, but deserialization of any re
cannot be deserialized i.e. when I call nextFireTime, it is failing for any recurrence rule (not just by day) We are
Raghu
Comment by Narayanan Raghuvaran [ 12/Dec/13 ]
So the serialization issues are with
Daily, recur every week day
weekly i.e Monday, Tuesday etc
Monthly every first weekday, first sunday of the month etc
Comment by Narayanan Raghuvaran [ 12/Dec/13 ]
Olivier
Here is what I found out, when I deserialize , the vaidateRecurreneRule gets called and then it calls isNumericVa
returns a list. It is suppossed to return a empty list, but since dayList is transient now, it is set to null, so we are g
Comment by Narayanan Raghuvaran [ 12/Dec/13 ]
Hi Oliver
Thanks for your help so far. I fixed the issue. In readObject of RecurrenceRule, I am initializing the collections i
transient keyword fix for byday
Here is the code
private void initCollections() {
if (secondList == null)
{ secondList = new BoundedIntegerList(MIN_SECOND, MAX_SECOND,false); }
if (minuteList == null)
{ minuteList = new BoundedIntegerList(MIN_MINUTE, MAX_MINUTE,false); }
if (hourList == null)
{ hourList = new BoundedIntegerList(MIN_HOUR, MAX_HOUR, false); }
if (dayList == null)
{ dayList = new ArrayList<ByDay>(); }
if (monthDayList == null)
{ monthDayList = new BoundedIntegerList(MIN_MONTHDAY, MAX_MONTHDAY, true); }
if (yearDayList == null)
{ yearDayList = new BoundedIntegerList(MIN_YEARDAY, MAX_YEARDAY, true); }
if (weekNoList == null)
{ weekNoList = new BoundedIntegerList(MIN_WEEKNO, MAX_WEEKNO, true); }
if (monthList == null)
{ monthList = new BoundedIntegerList(MIN_MONTH, MAX_MONTH, false); }
if (setPosList == null)
{ setPosList = new BoundedIntegerList(MIN_SETPOS, MAX_SETPOS, true); }
}
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initCollections();
try
{ buildRecurrenceRule(recurrenceRuleExpr); }
catch (ParseException ignore)
{ // never happens }
}
Comment by Olivier Queyrut [ 13/Dec/13 ]
Hi Raghu,
Thanks a lot for your help debugging the code.
I have just posted an update of the source code with an extra junit test that verify serialization/deserialization of
Regards, Olivier
Comment by Chaitra Suresh [ 23/Dec/13 ]
Hi,
There is a getTimesTriggered() on a SimpleTrigger. But I don't see such a method on RecurrenceTrigger. I want
rule trigger fired. Is there a way to find that out?
Thanks,
Chaitra
Comment by Olivier Queyrut [ 07/Jan/14 ]
Hi,
Currently there is no way to get the number of times the trigger has fired. This is probably a feature that lacks... b
Probably, it would also be useful to extend the RecurrenceRuleTrigger behavior upon a mis-fire situation, such a
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT,
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT,
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT,
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT. This is not so e
RecurrenceRule.
As soon as I have time, I take a look at it !
Regards,
Olivier
Generated at Sat Apr 29 12:36:14 PDT 2017 using JIRA 6.2.4#6261sha1:4d2e6f6f26064845673c8e7ffe9b6b84b45a6e79.
Related documents