Story... ;)
Last week I thought to improve my appzone application. Its a message alert system. Which has some groups and users can join to those groups. Then they will recieves messages every morning. The improvement is i just want to set separatem trigger times for each group. Currently i used quartz in spring context file. I created one schedular factory bean, one trigger bean, and one job bean. So simply what i have to do is create each one of those for each group. But its not possible it another group will added. hmmm.... I need a dynamic and more configurable way. Before explain the solution i'll show my old codes.
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="alertMessageTrigger"/>
</list>
</property>
</bean>
<bean id="alertMessageTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="alertMessageTimeTrackJob"/>
<property name="cronExpression" value="0 0 8 * * ?"/>
</bean>
<bean name="alertMessageTimeTrackJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="dailyAlertManager"/>
<property name="targetMethod" value="startDaily"/>
</bean>
<bean id="dailyAlertManager" class="myroad.util.impl.AlertManagerImpl">
<property name="limit" value="${sms.data.retreive.batch.size}"/>
</bean>
"AlertManagerImpl" class has a method called "startDaily". So that message will executes by the cron when trigger time occurs. To understand the cron expression please check my old posts.
Ok.. now the solution. I create new class "MySchedularFactoryBean" by extending "SchedularFactoryBean". So to initialize create a bean of that class inside the context file. Now the context.xml has only this.
<bean class="myroad.say.util.impl.SaySchedulerFactoryBean">
<property name="groupService" ref="groupService"/>
</bean>
This is my class.
public class MySchedulerFactoryBean extends SchedulerFactoryBean {
private Log logger = LogFactory.getLog(MySchedulerFactoryBean.class);
private GroupService groupService;
@Override
protected void startScheduler(Scheduler scheduler, int startupDelay) throws SchedulerException {
logger.info("Scheduler starting...");
try {
List<Group> groups = groupService.getAllGroups();
logger.debug("Number of groups in database = " + groups.size());
for (Group group : groups) {
if (null == group.getQtzExpression() || group.getQtzExpression().equals("")) {
continue;
}
JobDetail jobDetail = new JobDetail();
jobDetail.setName(group.getShortName());
jobDetail.setJobClass(GroupMsgSendJob.class);
CronTriggerBean triggerBean = new CronTriggerBean();
triggerBean.setName(group.getShortName() + "Trigger");
try {
triggerBean.setCronExpression(group.getQtzExpression());
} catch (ParseException e) {
logger.error("Exception while parsing quartz expression for " + group.getShortName() + "Group.", e);
}
scheduler.scheduleJob(jobDetail, triggerBean);
}
} catch (myroad.say.exception.DBException e) {
logger.error("DB exception occurs while searching groups for load schedules.", e);
} catch (SQLException e) {
logger.error("SQL exception occurs while searching groups for load schedules.", e);
}
super.startScheduler(scheduler, startupDelay);
}
public void setGroupService(GroupService groupService) {
this.groupService = groupService;
}
}
For your convienience I'll show my "Group" pojo.
public class Group {
private int id;
private String shortName;
private String description;
private List<String> synonyms;
private String successMessage;
private String responseMsg1;
private String qtzExpression;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<String> getSynonyms() {
return synonyms;
}
public void setSynonyms(List<String> synonyms) {
this.synonyms = synonyms;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSuccessMessage() {
return successMessage;
}
public void setSuccessMessage(String successMessage) {
this.successMessage = successMessage;
}
public String getResponseMsg1() {
return responseMsg1;
}
public void setResponseMsg1(String responseMsg1) {
this.responseMsg1 = responseMsg1;
}
public String getQtzExpression() {
return qtzExpression;
}
public void setQtzExpression(String qtzExpression) {
this.qtzExpression = qtzExpression;
}
}
This one solves my problem. But i have to restart the system after adding new group into the database. mmm... its not a big issue. Because I may add new group once a two or three months ;)
However there is a solution even for that. We can set data source for quarts. Then it will handle the cron expressions dynamically. Also it consumes less proccessing power than my solution.
No comments:
Post a Comment