1 25 package org.ofbiz.service.job; 26 27 import java.io.IOException ; 28 import java.sql.Timestamp ; 29 import java.util.Calendar ; 30 import java.util.Date ; 31 import java.util.HashMap ; 32 import java.util.Map ; 33 34 import javax.xml.parsers.ParserConfigurationException ; 35 36 import org.ofbiz.base.util.Debug; 37 import org.ofbiz.base.util.UtilDateTime; 38 import org.ofbiz.base.util.UtilMisc; 39 import org.ofbiz.base.util.UtilProperties; 40 import org.ofbiz.base.util.UtilValidate; 41 import org.ofbiz.entity.GenericDelegator; 42 import org.ofbiz.entity.GenericEntityException; 43 import org.ofbiz.entity.GenericValue; 44 import org.ofbiz.entity.serialize.SerializeException; 45 import org.ofbiz.entity.serialize.XmlSerializer; 46 import org.ofbiz.service.DispatchContext; 47 import org.ofbiz.service.GenericRequester; 48 import org.ofbiz.service.ServiceUtil; 49 import org.ofbiz.service.calendar.RecurrenceInfo; 50 import org.ofbiz.service.config.ServiceConfigUtil; 51 import org.xml.sax.SAXException ; 52 53 60 public class PersistedServiceJob extends GenericServiceJob { 61 62 public static final String module = PersistedServiceJob.class.getName(); 63 64 private transient GenericDelegator delegator = null; 65 private Timestamp storedDate = null; 66 private long nextRecurrence = -1; 67 private long maxRetry = -1; 68 69 75 public PersistedServiceJob(DispatchContext dctx, GenericValue jobValue, GenericRequester req) { 76 super(jobValue.getString("jobId"), jobValue.getString("jobName")); 77 this.delegator = dctx.getDelegator(); 78 this.requester = req; 79 this.dctx = dctx; 80 this.storedDate = jobValue.getTimestamp("runTime"); 81 this.runtime = storedDate.getTime(); 82 this.maxRetry = jobValue.get("maxRetry") != null ? jobValue.getLong("maxRetry").longValue() : -1; 83 } 84 85 public void queue() throws InvalidJobException { 86 super.queue(); 87 88 GenericValue jobValue = null; 90 try { 91 jobValue = this.getJob(); 92 jobValue.refresh(); 93 } catch (GenericEntityException e) { 94 runtime = -1; 95 throw new InvalidJobException("Unable to refresh Job object", e); 96 } 97 98 if (runtime != -1) { 100 Timestamp cancelTime = jobValue.getTimestamp("cancelDateTime"); 101 Timestamp startTime = jobValue.getTimestamp("startDateTime"); 102 if (cancelTime != null || startTime != null) { 103 runtime = -1; 105 throw new InvalidJobException("Job [" + getJobId() + "] is not available"); 106 107 } else { 108 jobValue.set("startDateTime", UtilDateTime.nowTimestamp()); 110 jobValue.set("statusId", "SERVICE_RUNNING"); 111 try { 112 jobValue.store(); 113 } catch (GenericEntityException e) { 114 runtime = -1; 115 throw new InvalidJobException("Unable to set the startDateTime on the current job [" + getJobId() + "]; not running!", e); 116 117 } 118 } 119 } 120 } 121 122 125 protected void init() throws InvalidJobException { 126 super.init(); 127 128 GenericValue job = this.getJob(); 130 RecurrenceInfo recurrence = JobManager.getRecurrenceInfo(job); 131 132 String instanceId = UtilProperties.getPropertyValue("general.properties", "unique.instanceId", "ofbiz0"); 133 if (!instanceId.equals(job.getString("runByInstanceId"))) { 134 throw new InvalidJobException("Job has been accpeted by a different instance!"); 135 } 136 137 try { 138 if (recurrence != null) { 139 recurrence.incrementCurrentCount(); 140 long next = recurrence.next(); 141 createRecurrence(job, next); 142 } 143 } catch (GenericEntityException e) { 144 throw new RuntimeException (e.getMessage()); 145 } 146 if (Debug.infoOn()) Debug.logInfo(this.toString() + "[" + getJobId() + "] -- Next runtime: " + nextRecurrence, module); 147 } 148 149 private void createRecurrence(GenericValue job, long next) throws GenericEntityException { 150 if (Debug.verboseOn()) Debug.logVerbose("Next runtime returned: " + next, module); 151 152 if (next > runtime) { 153 String newJobId = job.getDelegator().getNextSeqId("JobSandbox"); 154 String pJobId = job.getString("parentJobId"); 155 if (pJobId == null) { 156 pJobId = job.getString("jobId"); 157 } 158 GenericValue newJob = GenericValue.create(job); 159 newJob.set("jobId", newJobId); 160 newJob.set("previousJobId", job.getString("jobId")); 161 newJob.set("parentJobId", pJobId); 162 newJob.set("statusId", "SERVICE_PENDING"); 163 newJob.set("startDateTime", null); 164 newJob.set("runByInstanceId", null); 165 newJob.set("runTime", new java.sql.Timestamp (next)); 166 nextRecurrence = next; 167 delegator.create(newJob); 168 if (Debug.verboseOn()) Debug.logVerbose("Created next job entry: " + newJob, module); 169 } 170 } 171 172 175 protected void finish() throws InvalidJobException { 176 super.finish(); 177 178 GenericValue job = getJob(); 180 String status = job.getString("statusId"); 181 if (status == null || "SERVICE_RUNNING".equals(status)) { 182 job.set("statusId", "SERVICE_FINISHED"); 183 } 184 job.set("finishDateTime", UtilDateTime.nowTimestamp()); 185 try { 186 job.store(); 187 } catch (GenericEntityException e) { 188 Debug.logError(e, "Cannot update the job [" + getJobId() + "] sandbox", module); 189 } 190 } 191 192 195 protected void failed(Throwable t) throws InvalidJobException { 196 super.failed(t); 197 198 if (nextRecurrence == -1) { 200 if (this.canRetry()) { 201 Calendar cal = Calendar.getInstance(); 203 cal.setTime(new Date ()); 204 cal.add(Calendar.MINUTE, ServiceConfigUtil.getFailedRetryMin()); 205 long next = cal.getTimeInMillis(); 206 GenericValue job = getJob(); 207 try { 208 createRecurrence(job, next); 209 } catch (GenericEntityException gee) { 210 Debug.logError(gee, "ERROR: Unable to re-schedule job [" + getJobId() + "] to re-run : " + job, module); 211 } 212 213 job.set("statusId", "SERVICE_FAILED"); 215 try { 216 job.store(); 217 } catch (GenericEntityException e) { 218 Debug.logError(e, "Cannot update the job sandbox", module); 219 } 220 Debug.log("Persisted Job [" + getJobId() + "] Failed Re-Scheduling : " + next, module); 221 } else { 222 Debug.logWarning("Persisted Job [" + getJobId() + "] Failed - Max Retry Hit; not re-scheduling", module); 223 } 224 } 225 } 226 227 230 protected String getServiceName() throws InvalidJobException { 231 GenericValue jobObj = getJob(); 232 if (jobObj == null || jobObj.get("serviceName") == null) { 233 return null; 234 } 235 return jobObj.getString("serviceName"); 236 } 237 238 241 protected Map getContext() throws InvalidJobException { 242 Map context = null; 243 try { 244 GenericValue jobObj = getJob(); 245 if (!UtilValidate.isEmpty(jobObj.getString("runtimeDataId"))) { 246 GenericValue contextObj = jobObj.getRelatedOne("RuntimeData"); 247 if (contextObj != null) { 248 context = (Map ) XmlSerializer.deserialize(contextObj.getString("runtimeInfo"), delegator); 249 } 250 } 251 252 if (context == null) { 253 context = new HashMap (); 254 } 255 256 if (!UtilValidate.isEmpty(jobObj.get("runAsUser"))) { 258 context.put("userLogin", ServiceUtil.getUserLogin(dctx, context, jobObj.getString("runAsUser"))); 259 } 260 } catch (GenericEntityException e) { 261 Debug.logError(e, "PersistedServiceJob.getContext(): Entity Exception", module); 262 } catch (SerializeException e) { 263 Debug.logError(e, "PersistedServiceJob.getContext(): Serialize Exception", module); 264 } catch (ParserConfigurationException e) { 265 Debug.logError(e, "PersistedServiceJob.getContext(): Parse Exception", module); 266 } catch (SAXException e) { 267 Debug.logError(e, "PersistedServiceJob.getContext(): SAXException", module); 268 } catch (IOException e) { 269 Debug.logError(e, "PersistedServiceJob.getContext(): IOException", module); 270 } 271 if (context == null) { 272 Debug.logError("Job context is null", module); 273 } 274 275 return context; 276 } 277 278 private GenericValue getJob() throws InvalidJobException { 280 try { 281 Map fields = UtilMisc.toMap("jobId", getJobId()); 282 GenericValue jobObj = delegator.findByPrimaryKey("JobSandbox", fields); 283 284 if (jobObj == null) { 285 throw new InvalidJobException("Job [" + getJobId() + "] came back null from datasource"); 286 } 287 return jobObj; 288 } catch (GenericEntityException e) { 289 throw new InvalidJobException("Cannot get job definition [" + getJobId() + "] from entity", e); 290 } 291 } 292 293 private long getRetries() throws InvalidJobException { 295 GenericValue job = this.getJob(); 296 String pJobId = job.getString("parentJobId"); 297 if (pJobId == null) { 298 return 0; 299 } 300 301 Map fields = UtilMisc.toMap("parentJobId", pJobId, "statusId", "SERVICE_FAILED"); 302 long count = 0; 303 try { 304 count = delegator.findCountByAnd("JobSandbox", fields); 305 } catch (GenericEntityException e) { 306 Debug.logError(e, module); 307 } 308 309 return count + 1; } 311 312 private boolean canRetry() throws InvalidJobException { 313 if (maxRetry == -1) { 314 return true; 315 } 316 if (this.getRetries() < maxRetry) { 317 return true; 318 } 319 return false; 320 } 321 } 322 | Popular Tags |