/** * */ package org.apache.ode.dao.jpa.scheduler; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ode.bpel.iapi.Scheduler.JobDetails; import org.apache.ode.dao.jpa.JpaConnection; import org.apache.ode.dao.jpa.JpaOperator; import org.apache.ode.dao.scheduler.DatabaseException; import org.apache.ode.dao.scheduler.JobDAO; import org.apache.ode.dao.scheduler.SchedulerDAOConnection; import org.apache.ode.utils.GUID; /** * @author jeffyu * */ public class SchedulerDAOConnectionImpl extends JpaConnection implements SchedulerDAOConnection { private static final Log __log = LogFactory.getLog(SchedulerDAOConnectionImpl.class); static final ThreadLocal<SchedulerDAOConnectionImpl> _connections = new ThreadLocal<SchedulerDAOConnectionImpl>(); private static final int UPDATE_SCHEDULED_SLOTS = 10; public SchedulerDAOConnectionImpl(EntityManager mgr, TransactionManager txMgr, JpaOperator operator) { super(mgr, txMgr, operator); } public static ThreadLocal<SchedulerDAOConnectionImpl> getThreadLocal() { return _connections; } public boolean deleteJob(String jobid, String nodeId) throws DatabaseException { _txCtx.begin(); Query q = _em.createNamedQuery("deleteJobs"); q.setParameter("job", jobid); q.setParameter("node", nodeId); boolean ret = q.executeUpdate() == 1 ? true : false; _txCtx.commit(); return ret; } public List<JobDAO> dequeueImmediate(String nodeId, long maxtime, int maxjobs) throws DatabaseException { _txCtx.begin(); Query q = _em.createNamedQuery("dequeueImmediate"); q.setParameter("node", nodeId); q.setParameter("time", maxtime); q.setMaxResults(maxjobs); List<JobDAO> ret = (List<JobDAO>) q.getResultList(); //For compatibility reasons, we check whether there are entries inside //jobDetailsExt blob, which correspond to extracted entries. If so, we //use them. for (JobDAO dao : ret) { JobDAOImpl daoImpl = (JobDAOImpl) dao; Map<String, Object> detailsExt = daoImpl.getDetails().getDetailsExt(); if (detailsExt.get("type") != null) { daoImpl.setType((String) detailsExt.get("type")); } if (detailsExt.get("iid") != null) { daoImpl.setInstanceId((Long) detailsExt.get("iid")); } if (detailsExt.get("pid") != null) { daoImpl.setProcessId((String) detailsExt.get("pid")); } if (detailsExt.get("inmem") != null) { daoImpl.setInMem((Boolean) detailsExt.get("inmem")); } if (detailsExt.get("ckey") != null) { daoImpl.setCorrelationKeySet((String) detailsExt.get("ckey")); } if (detailsExt.get("channel") != null) { daoImpl.setChannel((String) detailsExt.get("channel")); } if (detailsExt.get("mexid") != null) { daoImpl.setMexId((String) detailsExt.get("mexid")); } if (detailsExt.get("correlatorId") != null) { daoImpl.setCorrelatorId((String) detailsExt.get("correlatorId")); } if (detailsExt.get("retryCount") != null) { daoImpl.setRetryCount(Integer.parseInt((String) detailsExt.get("retryCount"))); } } // mark jobs as scheduled, UPDATE_SCHEDULED_SLOTS at a time int j = 0; int updateCount = 0; q = _em.createNamedQuery("updateScheduled"); for (int updates = 1; updates <= (ret.size() / UPDATE_SCHEDULED_SLOTS) + 1; updates++) { for (int i = 1; i <= UPDATE_SCHEDULED_SLOTS; i++) { q.setParameter(i, j < ret.size() ? ret.get(j).getJobId() : ""); j++; } updateCount += q.executeUpdate(); } if (updateCount != ret.size()) { __log.error("Updating scheduled jobs failed to update all jobs; expected=" + ret.size() + " actual=" + updateCount); return null; } _txCtx.commit(); return ret; } public List<String> getNodeIds() throws DatabaseException { _txCtx.begin(); Query q = _em.createNamedQuery("nodeIds"); List<String> ret = (List<String>) q.getResultList(); _txCtx.commit(); return ret; } public boolean insertJob(JobDAO job, String nodeId, boolean loaded) throws DatabaseException { _txCtx.begin(); JobDAOImpl theJob = (JobDAOImpl)job; theJob.setNodeId(nodeId); theJob.setScheduled(loaded); _em.persist(theJob); _txCtx.commit(); return true; } public int updateAssignToNode(String nodeId, int i, int numNodes, long maxtime) throws DatabaseException { _txCtx.begin(); Query q = _em.createNamedQuery("updateAssignToNode"); q.setParameter("node", nodeId); q.setParameter("numNode", numNodes); q.setParameter("i", i); q.setParameter("maxTime", maxtime); int ret = q.executeUpdate(); _txCtx.commit(); return ret; } public boolean updateJob(JobDAO job) throws DatabaseException { _txCtx.begin(); JobDAOImpl theJob = _em.find(JobDAOImpl.class, job.getJobId()); if (theJob == null) { throw new DatabaseException("the updated job is not existed! job detail is: " + job); } theJob.setScheduledDate(job.getScheduledDate()); theJob.getDetails().setRetryCount(job.getDetails().getRetryCount()); theJob.setScheduled(job.isScheduled()); _txCtx.commit(); return true; } public int updateReassign(String oldnode, String newnode) throws DatabaseException { _txCtx.begin(); Query q = _em.createNamedQuery("updateReassign"); q.setParameter("newNode", newnode); q.setParameter("oldNode", oldnode); int ret = q.executeUpdate(); _txCtx.commit(); return ret; } public JobDAO createJob(String jobId, boolean transacted, JobDetails jobDetails, boolean persisted, long scheduledDate) { JobDAOImpl theJob = new JobDAOImpl(); theJob.setJobId(jobId); theJob.setTransacted(transacted); theJob.setDetails(jobDetails); theJob.setPersisted(persisted); theJob.setTimestamp(scheduledDate); return theJob; } public JobDAO createJob(boolean transacted, JobDetails jobDetails, boolean persisted, long scheduledDate) { String jobId = new GUID().toString(); return createJob(jobId, transacted, jobDetails, persisted, scheduledDate); } }