Package org.jboss.soa.esb.services.jbpm.integration.timer

Source Code of org.jboss.soa.esb.services.jbpm.integration.timer.QuartzSchedulerService$QuartzSchedulerServiceJob

package org.jboss.soa.esb.services.jbpm.integration.timer;

import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.db.JobSession;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.job.Job;
import org.jbpm.job.Timer;
import org.jbpm.scheduler.SchedulerService;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;

/**
* Implementation of the jBPM scheduler service targeting quartz.
*
* @author <a href='kevin.conner@jboss.com'>Kevin Conner</a>
*/
public class QuartzSchedulerService implements SchedulerService
{
    /**
     * Serial Version UID for this class.
     */
    private static final long serialVersionUID = -5573189923313779260L;
   
    /**
     * Quartz group name for jBPM tasks.
     */
    private static final String JBPM_GROUP = "jBPMGroup" ;
    /**
     * Name of the timer id within the quartz map.
     */
    private static final String TIMER_ID = "id" ;
    /**
     * Name of the max refire count within the quartz map.
     */
    private static final String MAX_REFIRE_COUNT = "maxRefireCount" ;
   
    /**
     * The associated quartz scheduler.
     */
    private final Scheduler scheduler ;
    /**
     * The maximum refire count.
     */
    private final int maxRefireCount ;
    /**
     * The associated jBPM job session.
     */
    private final JobSession jobSession ;
   
    /**
     * Create the scheduler service.
     * @param jbpmContext The associated jBPM context.
     * @param scheduler The quartz scheduler.
     */
    public QuartzSchedulerService(final JbpmContext jbpmContext, final Scheduler scheduler, final int maxRefireCount)
    {
        this.scheduler = scheduler ;
        this.maxRefireCount = maxRefireCount ;
        jobSession = jbpmContext.getJobSession();
    }
   
    /**
     * Create a timer.
     * @param timer the timer to create.
     */
    public void createTimer(final Timer timer)
    {
        // Force initialisation of any proxy, JBESB-2720
        Hibernate.initialize(timer) ;
        jobSession.saveJob(timer) ;
        final String name = getTimerName(timer) ;
        final Trigger trigger = new SimpleTrigger(name, JBPM_GROUP, timer.getDueDate()) ;
        final JobDetail jobDetail = new JobDetail(name, JBPM_GROUP, QuartzSchedulerServiceJob.class) ;

        final JobDataMap jobDataMap = new JobDataMap() ;
        jobDataMap.put(TIMER_ID, new Long(timer.getId())) ;
        jobDataMap.put(MAX_REFIRE_COUNT, Integer.valueOf(maxRefireCount)) ;
        jobDetail.setJobDataMap(jobDataMap) ;
       
        try
        {
            scheduler.scheduleJob(jobDetail, trigger) ;
        }
       
        catch (final SchedulerException se)
        {
            throw new JbpmException("Failed to schedule quartz job", se) ;
        }
    }

    /**
     * Delete a specific timer.
     * @param timer The timer to delete.
     */
    public void deleteTimer(final Timer timer)
    {
        deleteJob(timer) ;
        jobSession.deleteJob(timer) ;
    }

    /**
     * Delete a specific timer given a name and associated jBPM token.
     * @param timerName The name of the timer to delete.
     * @param token The token associated with the timer.
     */
    public void deleteTimersByName(final String timerName, final Token token)
    {
        final List<Job> jobs = jobSession.findJobsByToken(token) ;
        if (jobs != null)
        {
            for(Job job: jobs)
            {
                if (job instanceof Timer)
                {
                    final Timer timer = (Timer)job ;
                    if (timerName.equals(timer.getName()))
                    {
                        deleteJob(timer) ;
                    }
                }
            }
        }
        jobSession.deleteTimersByName(timerName, token) ;
    }

    /**
     * Delete timers associated with a jBPM process instance.
     * @param processInstance The process instance associated with the timers.
     */
    public void deleteTimersByProcessInstance(final ProcessInstance processInstance)
    {
        final List<?> tokens = processInstance.findAllTokens() ;
        if (tokens != null)
        {
            final Iterator<?> tokenIter = tokens.iterator() ;
            while(tokenIter.hasNext())
            {
                final Token token = (Token)tokenIter.next();
                final List<Job> jobs = jobSession.findJobsByToken(token) ;
                if (jobs != null)
                {
                    for(Job job: jobs)
                    {
                        if (job instanceof Timer)
                        {
                            final Timer timer = (Timer)job ;
                            deleteJob(timer) ;
                        }
                    }
                }
            }
        }
        jobSession.deleteJobsForProcessInstance(processInstance) ;
    }

    /**
     * Close the scheduler service.
     */
    public void close()
    {
    }
   
    /**
     * Generate a name for the timer.
     * @param timer the timer.
     */
    private String getTimerName(final Timer timer)
    {
        return Long.toString(timer.getId()) ;
    }
   
    /**
     * Delete a quartz job associated with a timer.
     * @param The timer to delete.
     */
    private void deleteJob(final Timer timer)
    {
        try
        {
            scheduler.deleteJob(getTimerName(timer), JBPM_GROUP) ;
        }
        catch (final SchedulerException se)
        {
            throw new JbpmException("Failed to delete quartz job", se) ;
        }
    }
   
    /**
     * The quartz job associated with executing a jBPM timer.
     * @author kevin
     */
    public static final class QuartzSchedulerServiceJob implements org.quartz.Job
    {
        /**
         * The logger for this class.
         */
        private static final Logger LOGGER = Logger.getLogger(QuartzSchedulerServiceJob.class) ;
       
        /**
         * Execute the quartz job.
         * @param context The quartz execution context.
         */
        public void execute(final JobExecutionContext context)
            throws JobExecutionException
        {
            final JobDetail jobDetail = context.getJobDetail() ;
            if (jobDetail != null)
            {
                final JobDataMap jobDataMap = jobDetail.getJobDataMap() ;
                if (jobDataMap != null)
                {
                    final Long jobId = (Long) jobDataMap.get(TIMER_ID) ;
                    if (jobId != null)
                    {
                        final JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext() ;
                        Job job = null ;
                        try
                        {
                            job = jbpmContext.getJobSession().loadJob(jobId) ;
                            if (job != null)
                            {
                                jbpmContext.getServices().getMessageService().send(job) ;
                                if (LOGGER.isDebugEnabled())
                                {
                                    LOGGER.debug("Firing job " + jobId) ;
                                }
                                return ;
                            }
                        }
                        catch (final RuntimeException re)
                        {
                            final Integer maxRefireCount = (Integer) jobDataMap.get(MAX_REFIRE_COUNT) ;
                            if ((maxRefireCount != null) && (maxRefireCount > context.getRefireCount()))
                            {
                                final JobExecutionException jobEx = new JobExecutionException(re, true);
                                jobEx.setErrorCode(JobExecutionException.ERR_JOB_EXECUTION_THREW_EXCEPTION);
                                throw jobEx ;
                            }
                            else
                            {
                                if (job != null)
                                {
                                    // zero the retries to remove from the list of outstanding jobs.
                                    job.setRetries(0) ;
                                }
                                throw re ;
                            }
                        }
                        finally
                        {
                            jbpmContext.close() ;
                        }
                    }
                }
            }
            if (LOGGER.isDebugEnabled())
            {
                LOGGER.debug("Failed to locate job from context " + context) ;
            }
        }
    }
}
TOP

Related Classes of org.jboss.soa.esb.services.jbpm.integration.timer.QuartzSchedulerService$QuartzSchedulerServiceJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.