001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.oozie;
020
021import java.io.DataInput;
022import java.io.DataOutput;
023import java.io.IOException;
024import java.sql.Timestamp;
025import java.text.MessageFormat;
026import java.util.ArrayList;
027import java.util.Date;
028import java.util.List;
029
030import javax.persistence.Basic;
031import javax.persistence.Column;
032import javax.persistence.Entity;
033import javax.persistence.Id;
034import javax.persistence.Lob;
035import javax.persistence.NamedNativeQueries;
036import javax.persistence.NamedNativeQuery;
037import javax.persistence.NamedQueries;
038import javax.persistence.NamedQuery;
039import javax.persistence.Table;
040import javax.persistence.Transient;
041
042import org.apache.hadoop.io.Writable;
043import org.apache.oozie.client.CoordinatorAction;
044import org.apache.oozie.client.CoordinatorJob;
045import org.apache.oozie.client.rest.JsonBean;
046import org.apache.oozie.client.rest.JsonTags;
047import org.apache.oozie.client.rest.JsonUtils;
048import org.apache.oozie.util.DateUtils;
049import org.apache.oozie.util.WritableUtils;
050import org.apache.openjpa.persistence.jdbc.Index;
051import org.apache.openjpa.persistence.jdbc.Strategy;
052import org.json.simple.JSONArray;
053import org.json.simple.JSONObject;
054
055@Entity
056@NamedQueries( {
057        @NamedQuery(name = "UPDATE_COORD_JOB", query = "update CoordinatorJobBean w set w.appName = :appName, w.appPath = :appPath,w.concurrency = :concurrency, w.conf = :conf, w.externalId = :externalId, w.frequency = :frequency, w.lastActionNumber = :lastActionNumber, w.timeOut = :timeOut, w.timeZone = :timeZone, w.createdTimestamp = :createdTime, w.endTimestamp = :endTime, w.execution = :execution, w.jobXml = :jobXml, w.lastActionTimestamp = :lastAction, w.lastModifiedTimestamp = :lastModifiedTime, w.nextMaterializedTimestamp = :nextMaterializedTime, w.origJobXml = :origJobXml, w.slaXml=:slaXml, w.startTimestamp = :startTime, w.statusStr = :status, w.timeUnitStr = :timeUnit, w.appNamespace = :appNamespace, w.bundleId = :bundleId, w.matThrottling = :matThrottling  where w.id = :id"),
058
059        @NamedQuery(name = "UPDATE_COORD_JOB_STATUS", query = "update CoordinatorJobBean w set w.statusStr =:status, w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"),
060
061        @NamedQuery(name = "UPDATE_COORD_JOB_PENDING", query = "update CoordinatorJobBean w set w.pending = :pending, w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"),
062
063        @NamedQuery(name = "UPDATE_COORD_JOB_BUNDLEID", query = "update CoordinatorJobBean w set w.bundleId = :bundleId where w.id = :id"),
064
065        @NamedQuery(name = "UPDATE_COORD_JOB_APPNAMESPACE", query = "update CoordinatorJobBean w set w.appNamespace = :appNamespace where w.id = :id"),
066
067        @NamedQuery(name = "UPDATE_COORD_JOB_STATUS_PENDING", query = "update CoordinatorJobBean w set w.statusStr = :status, w.pending = :pending where w.id = :id"),
068
069        @NamedQuery(name = "UPDATE_COORD_JOB_BUNDLEID_APPNAMESPACE_PAUSETIME", query = "update CoordinatorJobBean w set w.bundleId = :bundleId, w.appNamespace = :appNamespace, w.pauseTimestamp = :pauseTime where w.id = :id"),
070
071        @NamedQuery(name = "UPDATE_COORD_JOB_STATUS_MODTIME", query = "update CoordinatorJobBean w set w.statusStr = :status, w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"),
072
073        @NamedQuery(name = "UPDATE_COORD_JOB_STATUS_PENDING_MODTIME", query = "update CoordinatorJobBean w set w.statusStr = :status, w.lastModifiedTimestamp = :lastModifiedTime, w.pending = :pending where w.id = :id"),
074
075        @NamedQuery(name = "UPDATE_COORD_JOB_LAST_MODIFIED_TIME", query = "update CoordinatorJobBean w set w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"),
076
077        @NamedQuery(name = "UPDATE_COORD_JOB_STATUS_PENDING_TIME", query = "update CoordinatorJobBean w set w.statusStr = :status, w.pending = :pending, w.doneMaterialization = :doneMaterialization, w.lastModifiedTimestamp = :lastModifiedTime, w.suspendedTimestamp = :suspendedTime where w.id = :id"),
078
079        @NamedQuery(name = "UPDATE_COORD_JOB_MATERIALIZE", query = "update CoordinatorJobBean w set w.statusStr = :status, w.pending = :pending, w.doneMaterialization = :doneMaterialization, w.lastActionTimestamp = :lastActionTime, w.lastActionNumber = :lastActionNumber, w.nextMaterializedTimestamp = :nextMatdTime where w.id = :id"),
080
081        @NamedQuery(name = "UPDATE_COORD_JOB_CHANGE", query = "update CoordinatorJobBean w set w.endTimestamp = :endTime, w.statusStr = :status, w.pending = :pending, w.doneMaterialization = :doneMaterialization, w.concurrency = :concurrency, w.pauseTimestamp = :pauseTime, w.lastActionNumber = :lastActionNumber, w.lastActionTimestamp = :lastActionTime, w.nextMaterializedTimestamp = :nextMatdTime, w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"),
082
083        @NamedQuery(name = "UPDATE_COORD_JOB_CONF", query = "update CoordinatorJobBean w set w.conf = :conf where w.id = :id"),
084
085        @NamedQuery(name = "UPDATE_COORD_JOB_XML", query = "update CoordinatorJobBean w set w.jobXml = :jobXml where w.id = :id"),
086
087        @NamedQuery(name = "DELETE_COORD_JOB", query = "delete from CoordinatorJobBean w where w.id IN (:id)"),
088
089        @NamedQuery(name = "GET_COORD_JOBS", query = "select OBJECT(w) from CoordinatorJobBean w"),
090
091        @NamedQuery(name = "GET_COORD_JOB", query = "select OBJECT(w) from CoordinatorJobBean w where w.id = :id"),
092
093        @NamedQuery(name = "GET_COORD_JOB_USER_APPNAME", query = "select w.user, w.appName from CoordinatorJobBean w where w.id = :id"),
094
095        @NamedQuery(name = "GET_COORD_JOB_INPUT_CHECK", query = "select w.user, w.appName, w.statusStr, w.appNamespace, w.execution, w.frequency, w.timeUnitStr, w.timeZone, w.startTimestamp, w.endTimestamp, w.jobXml from CoordinatorJobBean w where w.id = :id"),
096
097        @NamedQuery(name = "GET_COORD_JOB_ACTION_READY", query = "select w.id, w.user, w.group, w.appName, w.statusStr, w.execution, w.concurrency, w.frequency, w.timeUnitStr, w.timeZone, w.startTimestamp, w.endTimestamp, w.jobXml from CoordinatorJobBean w where w.id = :id"),
098
099        @NamedQuery(name = "GET_COORD_JOB_ACTION_KILL", query = "select w.id, w.user, w.group, w.appName, w.statusStr from CoordinatorJobBean w where w.id = :id"),
100
101        @NamedQuery(name = "GET_COORD_JOB_MATERIALIZE", query = "select w.id, w.user, w.group, w.appName, w.statusStr, w.frequency, w.matThrottling, w.timeOut, w.timeZone, w.startTimestamp, w.endTimestamp, w.pauseTimestamp, w.nextMaterializedTimestamp, w.lastActionTimestamp, w.lastActionNumber, w.doneMaterialization, w.bundleId, w.conf, w.jobXml, w.appNamespace, w.timeUnitStr, w.execution from CoordinatorJobBean w where w.id = :id"),
102
103        @NamedQuery(name = "GET_COORD_JOB_SUSPEND_KILL", query = "select w.id, w.user, w.group, w.appName, w.statusStr, w.bundleId, w.appNamespace, w.doneMaterialization from CoordinatorJobBean w where w.id = :id"),
104
105        @NamedQuery(name = "GET_COORD_JOBS_PENDING", query = "select OBJECT(w) from CoordinatorJobBean w where w.pending = 1 order by w.lastModifiedTimestamp"),
106
107        @NamedQuery(name = "GET_COORD_JOBS_CHANGED", query = "select OBJECT(w) from CoordinatorJobBean w where w.pending = 1 AND w.doneMaterialization = 1 AND w.lastModifiedTimestamp >= :lastModifiedTime"),
108
109        @NamedQuery(name = "GET_COORD_JOBS_COUNT", query = "select count(w) from CoordinatorJobBean w"),
110
111        @NamedQuery(name = "GET_COORD_JOBS_COLUMNS", query = "select w.id, w.appName, w.statusStr, w.user, w.group, w.startTimestamp, w.endTimestamp, w.appPath, w.concurrency, w.frequency, w.lastActionTimestamp, w.nextMaterializedTimestamp, w.createdTimestamp, w.timeUnitStr, w.timeZone, w.timeOut from CoordinatorJobBean w order by w.createdTimestamp desc"),
112
113        //TODO need to remove.
114        @NamedQuery(name = "GET_COORD_JOBS_OLDER_THAN", query = "select OBJECT(w) from CoordinatorJobBean w where w.startTimestamp <= :matTime AND (w.statusStr = 'PREP' OR w.statusStr = 'RUNNING' or w.statusStr = 'RUNNINGWITHERROR') AND (w.nextMaterializedTimestamp < :matTime OR w.nextMaterializedTimestamp IS NULL) AND (w.nextMaterializedTimestamp IS NULL OR (w.endTimestamp > w.nextMaterializedTimestamp AND (w.pauseTimestamp IS NULL OR w.pauseTimestamp > w.nextMaterializedTimestamp))) order by w.lastModifiedTimestamp"),
115
116        @NamedQuery(name = "GET_COORD_JOBS_OLDER_FOR_MATERIALIZATION", query = "select w.id from CoordinatorJobBean w where w.startTimestamp <= :matTime AND (w.statusStr = 'PREP' OR w.statusStr = 'RUNNING' or w.statusStr = 'RUNNINGWITHERROR') AND (w.nextMaterializedTimestamp < :matTime OR w.nextMaterializedTimestamp IS NULL) AND (w.nextMaterializedTimestamp IS NULL OR (w.endTimestamp > w.nextMaterializedTimestamp AND (w.pauseTimestamp IS NULL OR w.pauseTimestamp > w.nextMaterializedTimestamp))) and w.matThrottling > ( select count(a.jobId) from CoordinatorActionBean a where a.jobId = w.id and a.statusStr = 'WAITING') order by w.lastModifiedTimestamp"),
117
118        @NamedQuery(name = "GET_COORD_JOBS_OLDER_THAN_STATUS", query = "select OBJECT(w) from CoordinatorJobBean w where w.statusStr = :status AND w.lastModifiedTimestamp <= :lastModTime order by w.lastModifiedTimestamp"),
119
120        @NamedQuery(name = "GET_COMPLETED_COORD_JOBS_OLDER_THAN_STATUS", query = "select OBJECT(w) from CoordinatorJobBean w where ( w.statusStr = 'SUCCEEDED' OR w.statusStr = 'FAILED' or w.statusStr = 'KILLED') AND w.lastModifiedTimestamp <= :lastModTime order by w.lastModifiedTimestamp"),
121
122        @NamedQuery(name = "GET_COMPLETED_COORD_JOBS_WITH_NO_PARENT_OLDER_THAN_STATUS", query = "select w.id from CoordinatorJobBean w where ( w.statusStr = 'SUCCEEDED' OR w.statusStr = 'FAILED' or w.statusStr = 'KILLED' or w.statusStr = 'DONEWITHERROR') AND w.lastModifiedTimestamp <= :lastModTime and w.bundleId is null order by w.lastModifiedTimestamp"),
123
124        @NamedQuery(name = "GET_COORD_JOBS_UNPAUSED", query = "select OBJECT(w) from CoordinatorJobBean w where w.statusStr = 'RUNNING' OR w.statusStr = 'RUNNINGWITHERROR' OR w.statusStr = 'PREP' order by w.lastModifiedTimestamp"),
125
126        @NamedQuery(name = "GET_COORD_JOBS_PAUSED", query = "select OBJECT(w) from CoordinatorJobBean w where w.statusStr = 'PAUSED' OR w.statusStr = 'PAUSEDWITHERROR' OR w.statusStr = 'PREPPAUSED' order by w.lastModifiedTimestamp"),
127
128        @NamedQuery(name = "GET_COORD_JOBS_FOR_BUNDLE", query = "select OBJECT(w) from CoordinatorJobBean w where w.bundleId = :bundleId order by w.lastModifiedTimestamp"),
129
130        @NamedQuery(name = "GET_COORD_JOBS_WITH_PARENT_ID", query = "select w.id from CoordinatorJobBean w where w.bundleId = :parentId"),
131
132        @NamedQuery(name = "GET_COORD_COUNT_WITH_PARENT_ID_NOT_READY_FOR_PURGE", query = "select count(w) from CoordinatorJobBean w where w.bundleId = :parentId and (w.statusStr NOT IN ('SUCCEEDED', 'FAILED', 'KILLED', 'DONEWITHERROR') OR w.lastModifiedTimestamp >= :lastModTime)"),
133
134        @NamedQuery(name = "GET_COORD_JOB_FOR_USER_APPNAME", query = "select w.user, w.appName from CoordinatorJobBean w where w.id = :id"),
135
136        @NamedQuery(name = "GET_COORD_JOB_FOR_USER", query = "select w.user from CoordinatorJobBean w where w.id = :id"),
137
138        @NamedQuery(name = "GET_COORD_JOB_STATUS", query = "select w.statusStr from CoordinatorJobBean w where w.id = :id"),
139
140        @NamedQuery(name = "GET_COORD_JOB_STATUS_PARENTID", query = "select w.statusStr, w.bundleId from CoordinatorJobBean w where w.id = :id"),
141
142        @NamedQuery(name = "GET_COORD_IDS_FOR_STATUS_TRANSIT", query = "select DISTINCT w.id from CoordinatorActionBean a, CoordinatorJobBean w where w.id = a.jobId and a.lastModifiedTimestamp >= :lastModifiedTime and (w.statusStr IN ('PAUSED', 'RUNNING', 'RUNNINGWITHERROR', 'PAUSEDWITHERROR') or w.pending = 1)  and w.statusStr <> 'IGNORED'"),
143
144        @NamedQuery(name = "GET_COORD_JOBS_FOR_BUNDLE_BY_APPNAME_ID", query = "select w.id from CoordinatorJobBean w where ( w.appName IN (:appName) OR w.id IN (:appName) )  AND w.bundleId = :bundleId"),
145
146        @NamedQuery(name = "GET_COORD_JOB_CONF", query = "select w.conf from CoordinatorJobBean w where w.id = :id"),
147
148        @NamedQuery(name = "GET_COORD_JOB_XML", query = "select w.jobXml from CoordinatorJobBean w where w.id = :id")
149
150})
151@NamedNativeQueries({
152        @NamedNativeQuery(name = "GET_COORD_FOR_ABANDONEDCHECK", query = "select w.id, w.USER_NAME, w.group_name, w.APP_NAME from coord_jobs w where ( w.STATUS = 'RUNNING' or w.STATUS = 'RUNNINGWITHERROR' ) and w.start_time < ?2 and w.created_time < ?2 and w.id in (select failedJobs.job_id from (select a.job_id from coord_actions a where ( a.STATUS = 'FAILED' or a.STATUS = 'TIMEDOUT'  or a.STATUS = 'SUSPENDED') group by a.job_id having count(*) >= ?1 ) failedJobs LEFT OUTER JOIN (select b.job_id from coord_actions b where b.STATUS = 'SUCCEEDED' group by b.job_id having count(*) > 0 ) successJobs   on  failedJobs.job_id = successJobs.job_id where successJobs.job_id is null )")
153
154})
155@Table(name = "COORD_JOBS")
156public class CoordinatorJobBean implements Writable, CoordinatorJob, JsonBean {
157
158    @Id
159    private String id;
160
161    @Basic
162    @Column(name = "app_path")
163    private String appPath = null;
164
165    @Basic
166    @Column(name = "app_name")
167    private String appName = null;
168
169    @Basic
170    @Column(name = "external_id")
171    private String externalId = null;
172
173    @Basic
174    @Column(name = "conf")
175    @Lob
176    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
177    private StringBlob conf = null;
178
179    @Basic
180    @Column(name = "frequency")
181    private String frequency = "0";
182
183    @Basic
184    @Column(name = "time_zone")
185    private String timeZone = null;
186
187    @Basic
188    @Column(name = "concurrency")
189    private int concurrency = 0;
190
191    @Basic
192    @Column(name = "mat_throttling")
193    private int matThrottling = 0;
194
195    @Basic
196    @Column(name = "time_out")
197    private int timeOut = 0;
198
199    @Basic
200    @Column(name = "last_action_number")
201    private int lastActionNumber;
202
203    @Basic
204    @Column(name = "user_name")
205    private String user = null;
206
207    @Basic
208    @Column(name = "group_name")
209    private String group = null;
210
211    @Basic
212    @Index
213    @Column(name = "bundle_id")
214    private String bundleId = null;
215
216    @Transient
217    private String consoleUrl;
218
219    @Transient
220    private List<CoordinatorActionBean> actions;
221
222    @Transient
223    private int numActions = 0;
224
225    @Basic
226    @Index
227    @Column(name = "status")
228    private String statusStr = CoordinatorJob.Status.PREP.toString();
229
230    @Basic
231    @Column(name = "start_time")
232    private java.sql.Timestamp startTimestamp = null;
233
234    @Basic
235    @Column(name = "end_time")
236    private java.sql.Timestamp endTimestamp = null;
237
238    @Basic
239    @Column(name = "pause_time")
240    private java.sql.Timestamp pauseTimestamp = null;
241
242    @Basic
243    @Index
244    @Column(name = "created_time")
245    private java.sql.Timestamp createdTimestamp = null;
246
247    @Basic
248    @Column(name = "time_unit")
249    private String timeUnitStr = CoordinatorJob.Timeunit.NONE.toString();
250
251    @Basic
252    @Column(name = "execution")
253    private String execution = CoordinatorJob.Execution.FIFO.toString();
254
255    @Basic
256    @Column(name = "last_action")
257    private java.sql.Timestamp lastActionTimestamp = null;
258
259    @Basic
260    @Index
261    @Column(name = "next_matd_time")
262    private java.sql.Timestamp nextMaterializedTimestamp = null;
263
264    @Basic
265    @Index
266    @Column(name = "last_modified_time")
267    private java.sql.Timestamp lastModifiedTimestamp = null;
268
269    @Basic
270    @Index
271    @Column(name = "suspended_time")
272    private java.sql.Timestamp suspendedTimestamp = null;
273
274    @Basic
275    @Column(name = "job_xml")
276    @Lob
277    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
278    private StringBlob jobXml = null;
279
280    @Basic
281    @Column(name = "orig_job_xml")
282    @Lob
283    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
284    private StringBlob origJobXml = null;
285
286    @Basic
287    @Column(name = "sla_xml")
288    @Lob
289    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
290    private StringBlob slaXml = null;
291
292    @Basic
293    @Column(name = "pending")
294    private int pending = 0;
295
296    @Basic
297    @Column(name = "done_materialization")
298    private int doneMaterialization = 0;
299
300    @Basic
301    @Column(name = "app_namespace")
302    private String appNamespace = null;
303
304    /**
305     * Get start timestamp
306     *
307     * @return start timestamp
308     */
309    public java.sql.Timestamp getStartTimestamp() {
310        return startTimestamp;
311    }
312
313    /**
314     * Set start timestamp
315     *
316     * @param startTimestamp start timestamp
317     */
318    public void setStartTimestamp(java.sql.Timestamp startTimestamp) {
319        this.startTimestamp = startTimestamp;
320    }
321
322    /**
323     * Get end timestamp
324     *
325     * @return end timestamp
326     */
327    public java.sql.Timestamp getEndTimestamp() {
328        return endTimestamp;
329    }
330
331    /**
332     * Set end timestamp
333     *
334     * @param endTimestamp end timestamp
335     */
336    public void setEndTimestamp(java.sql.Timestamp endTimestamp) {
337        this.endTimestamp = endTimestamp;
338    }
339
340    /**
341     * Get next materialized timestamp
342     *
343     * @return next materialized timestamp
344     */
345    public Timestamp getNextMaterializedTimestamp() {
346        return nextMaterializedTimestamp;
347    }
348
349    /**
350     * Set next materialized timestamp
351     *
352     * @param nextMaterializedTimestamp next materialized timestamp
353     */
354    public void setNextMaterializedTimestamp(java.sql.Timestamp nextMaterializedTimestamp) {
355        this.nextMaterializedTimestamp = nextMaterializedTimestamp;
356    }
357
358    /**
359     * Get last modified timestamp
360     *
361     * @return last modified timestamp
362     */
363    public Timestamp getLastModifiedTimestamp() {
364        return lastModifiedTimestamp;
365    }
366
367    /**
368     * Set last modified timestamp
369     *
370     * @param lastModifiedTimestamp last modified timestamp
371     */
372    public void setLastModifiedTimestamp(java.sql.Timestamp lastModifiedTimestamp) {
373        this.lastModifiedTimestamp = lastModifiedTimestamp;
374    }
375
376    /**
377     * Get suspended timestamp
378     *
379     * @return suspended timestamp
380     */
381    public Timestamp getSuspendedTimestamp() {
382        return suspendedTimestamp;
383    }
384
385    /**
386     * Set suspended timestamp
387     *
388     * @param suspendedTimestamp suspended timestamp
389     */
390    public void setSuspendedTimestamp(java.sql.Timestamp suspendedTimestamp) {
391        this.suspendedTimestamp = suspendedTimestamp;
392    }
393
394    /**
395     * Get job xml
396     *
397     * @return job xml
398     */
399    public String getJobXml() {
400        return jobXml == null ? null : jobXml.getString();
401    }
402
403    /**
404     * Set job xml
405     *
406     * @param jobXml job xml
407     */
408    public void setJobXml(String jobXml) {
409        if (this.jobXml == null) {
410            this.jobXml = new StringBlob(jobXml);
411        }
412        else {
413            this.jobXml.setString(jobXml);
414        }
415    }
416
417    public void setJobXmlBlob (StringBlob jobXmlBlob) {
418        this.jobXml = jobXmlBlob;
419    }
420
421    public StringBlob getJobXmlBlob() {
422        return jobXml;
423    }
424
425    /**
426     * Get original job xml
427     *
428     * @return original job xml
429     */
430    public String getOrigJobXml() {
431        return origJobXml == null ? null : origJobXml.getString();
432    }
433
434    /**
435     * Set original job xml
436     *
437     * @param origJobXml
438     */
439    public void setOrigJobXml(String origJobXml) {
440        if (this.origJobXml == null) {
441            this.origJobXml = new StringBlob(origJobXml);
442        }
443        else {
444            this.origJobXml.setString(origJobXml);
445        }
446    }
447
448    public void setOrigJobXmlBlob (StringBlob origJobXml) {
449        this.origJobXml = origJobXml;
450    }
451
452    public StringBlob getOrigJobXmlBlob() {
453        return origJobXml;
454    }
455
456    /**
457     * Get sla xml
458     *
459     * @return sla xml
460     */
461    public String getSlaXml() {
462        return slaXml == null ? null : slaXml.getString();
463    }
464
465    /**
466     * Set sla xml
467     *
468     * @param slaXml sla xml
469     */
470    public void setSlaXml(String slaXml) {
471        if (this.slaXml == null) {
472            this.slaXml = new StringBlob(slaXml);
473        }
474        else {
475            this.slaXml.setString(slaXml);
476        }
477    }
478
479    public void setSlaXmlBlob(StringBlob slaXml) {
480        this.slaXml = slaXml;
481    }
482
483    public StringBlob getSlaXmlBlob() {
484        return slaXml;
485    }
486
487
488
489    /**
490     * Set last action timestamp
491     *
492     * @param lastActionTimestamp last action timestamp
493     */
494    public void setLastActionTimestamp(java.sql.Timestamp lastActionTimestamp) {
495        this.lastActionTimestamp = lastActionTimestamp;
496    }
497
498    /**
499     * Return if the action is pending.
500     *
501     * @return if the action is pending.
502     */
503    public boolean isPending() {
504        return pending == 1 ? true : false;
505    }
506
507    /**
508     * Set doneMaterialization to true
509     */
510    public void setDoneMaterialization() {
511        this.doneMaterialization = 1;
512    }
513
514    /**
515     * Set doneMaterialization
516     */
517    public void setDoneMaterialization(int i) {
518        this.doneMaterialization = i;
519    }
520
521    /**
522     * Set doneMaterialization to false
523     */
524    public void resetDoneMaterialization() {
525        this.doneMaterialization = 0;
526    }
527
528    /**
529     * Return if the action is done with materialization
530     *
531     * @return if the action is done with materialization
532     */
533    public boolean isDoneMaterialization() {
534        return doneMaterialization == 1 ? true : false;
535    }
536
537
538    /**
539     * Get app namespce
540     *
541     * @return app namespce
542     */
543    public String getAppNamespace() {
544        return appNamespace;
545    }
546
547    /**
548     * Set app namespce
549     *
550     * @param appNamespace the app namespce to set
551     */
552    public void setAppNamespace(String appNamespace) {
553        this.appNamespace = appNamespace;
554    }
555
556    public CoordinatorJobBean() {
557        actions = new ArrayList<CoordinatorActionBean>();
558    }
559
560    /*
561     * Serialize the coordinator bean to a data output. @param dataOutput data
562     * output. @throws IOException thrown if the coordinator bean could not be
563     * serialized.
564     */
565    public void write(DataOutput dataOutput) throws IOException {
566        WritableUtils.writeStr(dataOutput, getAppPath());
567        WritableUtils.writeStr(dataOutput, getAppName());
568        WritableUtils.writeStr(dataOutput, getId());
569        WritableUtils.writeStr(dataOutput, getConf());
570        WritableUtils.writeStr(dataOutput, getStatusStr());
571        WritableUtils.writeStr(dataOutput, getFrequency());
572        WritableUtils.writeStr(dataOutput, getTimeUnit().toString());
573        WritableUtils.writeStr(dataOutput, getTimeZone());
574        dataOutput.writeInt(getConcurrency());
575        WritableUtils.writeStr(dataOutput, getExecutionOrder().toString());
576        dataOutput.writeLong((getLastActionTime() != null) ? getLastActionTime().getTime() : -1);
577        dataOutput.writeLong((getNextMaterializedTime() != null) ? getNextMaterializedTime().getTime() : -1);
578        dataOutput.writeLong((getStartTime() != null) ? getStartTime().getTime() : -1);
579        dataOutput.writeLong((getEndTime() != null) ? getEndTime().getTime() : -1);
580        WritableUtils.writeStr(dataOutput, getUser());
581        WritableUtils.writeStr(dataOutput, getGroup());
582        WritableUtils.writeStr(dataOutput, getExternalId());
583        dataOutput.writeInt(getTimeout());
584        dataOutput.writeInt(getMatThrottling());
585        if (isPending()) {
586            dataOutput.writeInt(1);
587        } else {
588            dataOutput.writeInt(0);
589        }
590        if (isDoneMaterialization()) {
591            dataOutput.writeInt(1);
592        } else {
593            dataOutput.writeInt(0);
594        }
595        WritableUtils.writeStr(dataOutput, getAppNamespace());
596    }
597
598    /**
599     * Deserialize a coordinator bean from a data input.
600     *
601     * @param dataInput data input.
602     * @throws IOException thrown if the workflow bean could not be deserialized.
603     */
604    public void readFields(DataInput dataInput) throws IOException {
605        setAppPath(WritableUtils.readStr(dataInput));
606        setAppName(WritableUtils.readStr(dataInput));
607        setId(WritableUtils.readStr(dataInput));
608        setConf(WritableUtils.readStr(dataInput));
609        setStatus(CoordinatorJob.Status.valueOf(WritableUtils.readStr(dataInput)));
610        setFrequency(WritableUtils.readStr(dataInput));
611        setTimeUnit(CoordinatorJob.Timeunit.valueOf(WritableUtils.readStr(dataInput)));
612        setTimeZone(WritableUtils.readStr(dataInput));
613        setConcurrency(dataInput.readInt());
614        setExecutionOrder(Execution.valueOf(WritableUtils.readStr(dataInput)));
615
616        long d = dataInput.readLong();
617        if (d != -1) {
618            setLastActionTime(new Date(d));
619        }
620        d = dataInput.readLong();
621        if (d != -1) {
622            setNextMaterializedTime(new Date(d));
623        }
624        d = dataInput.readLong();
625        if (d != -1) {
626            setStartTime(new Date(d));
627        }
628
629        d = dataInput.readLong();
630        if (d != -1) {
631            setEndTime(new Date(d));
632        }
633        setUser(WritableUtils.readStr(dataInput));
634        setGroup(WritableUtils.readStr(dataInput));
635        setExternalId(WritableUtils.readStr(dataInput));
636        setTimeout(dataInput.readInt());
637        setMatThrottling(dataInput.readInt());
638
639        d = dataInput.readInt();
640        if (d == 1) {
641            setPending();
642        }
643
644        d = dataInput.readInt();
645        if (d == 1) {
646            setDoneMaterialization();
647        }
648
649        setAppNamespace(WritableUtils.readStr(dataInput));
650    }
651
652    /**
653     * @return true if in terminal status
654     */
655    public boolean isTerminalStatus() {
656        boolean isTerminal = false;
657        switch (getStatus()) {
658            case SUCCEEDED:
659            case FAILED:
660            case KILLED:
661            case DONEWITHERROR:
662            case IGNORED:
663                isTerminal = true;
664                break;
665            default:
666                isTerminal = false;
667                break;
668        }
669        return isTerminal;
670    }
671
672    @Override
673    public Status getStatus() {
674        return Status.valueOf(this.statusStr);
675    }
676
677    /**
678     * Get status
679     *
680     * @return status
681     */
682    public String getStatusStr() {
683        return statusStr;
684    }
685
686    /**
687     * Set status
688     */
689    public void setStatusStr(String status) {
690        this.statusStr = status;
691    }
692
693    @Override
694    public void setStatus(Status val) {
695        this.statusStr = val.toString();
696    }
697
698    /**
699     * Get time unit
700     *
701     * @return time unit
702     */
703    public String getTimeUnitStr() {
704        return timeUnitStr;
705    }
706
707    /**
708     * Set time unit
709     *
710     */
711    public void setTimeUnitStr(String timeunit) {
712        this.timeUnitStr = timeunit;
713    }
714
715    public void setTimeUnit(Timeunit timeUnit) {
716        this.timeUnitStr = timeUnit.toString();
717    }
718
719    /* (non-Javadoc)
720     * @see org.apache.oozie.client.rest.JsonCoordinatorJob#getTimeUnit()
721     */
722    @Override
723    public Timeunit getTimeUnit() {
724        return Timeunit.valueOf(this.timeUnitStr);
725    }
726
727    /**
728     * Set order
729     *
730     * @param order
731     */
732    public void setExecutionOrder(Execution order) {
733        this.execution = order.toString();
734    }
735
736    /* (non-Javadoc)
737     * @see org.apache.oozie.client.rest.JsonCoordinatorJob#getExecutionOrder()
738     */
739    @Override
740    public Execution getExecutionOrder() {
741        return Execution.valueOf(this.execution);
742    }
743
744    /**
745     * Set execution order
746     */
747    public void setExecution(String order) {
748        this.execution = order;
749    }
750
751    /**
752     * Get execution
753     *
754     * @return execution
755     */
756    public String getExecution() {
757        return execution;
758    }
759
760    public void setLastActionTime(Date lastAction) {
761        this.lastActionTimestamp = DateUtils.convertDateToTimestamp(lastAction);
762    }
763
764    /* (non-Javadoc)
765     * @see org.apache.oozie.client.rest.JsonCoordinatorJob#getLastActionTime()
766     */
767    @Override
768    public Date getLastActionTime() {
769        return DateUtils.toDate(lastActionTimestamp);
770    }
771
772    /**
773     * Get last action timestamp
774     *
775     * @return last action timestamp
776     */
777    public Timestamp getLastActionTimestamp() {
778        return lastActionTimestamp;
779    }
780
781    public void setNextMaterializedTime(Date nextMaterializedTime) {
782        this.nextMaterializedTimestamp = DateUtils.convertDateToTimestamp(nextMaterializedTime);
783    }
784
785    /* (non-Javadoc)
786     * @see org.apache.oozie.client.rest.JsonCoordinatorJob#getNextMaterializedTime()
787     */
788    @Override
789    public Date getNextMaterializedTime() {
790        return DateUtils.toDate(nextMaterializedTimestamp);
791    }
792
793    /**
794     * Set last modified time
795     *
796     * @param lastModifiedTime last modified time
797     */
798    public void setLastModifiedTime(Date lastModifiedTime) {
799        this.lastModifiedTimestamp = DateUtils.convertDateToTimestamp(lastModifiedTime);
800    }
801
802    /**
803     * Get last modified time
804     *
805     * @return last modified time
806     */
807    public Date getLastModifiedTime() {
808        return DateUtils.toDate(lastModifiedTimestamp);
809    }
810
811    /**
812     * Set suspended time
813     *
814     * @param suspendedTime suspended time
815     */
816    public void setSuspendedTime(Date suspendedTime) {
817        this.suspendedTimestamp = DateUtils.convertDateToTimestamp(suspendedTime);
818    }
819
820    /**
821     * Get suspended time
822     *
823     * @return suspended time
824     */
825    public Date getSuspendedTime() {
826        return DateUtils.toDate(suspendedTimestamp);
827    }
828
829    public void setStartTime(Date startTime) {
830        this.startTimestamp = DateUtils.convertDateToTimestamp(startTime);
831    }
832
833    /* (non-Javadoc)
834     * @see org.apache.oozie.client.rest.JsonCoordinatorJob#getStartTime()
835     */
836    @Override
837    public Date getStartTime() {
838        return DateUtils.toDate(startTimestamp);
839    }
840
841    public void setEndTime(Date endTime) {
842        this.endTimestamp = DateUtils.convertDateToTimestamp(endTime);
843    }
844
845    public void setPauseTime(Date pauseTime) {
846        this.pauseTimestamp = DateUtils.convertDateToTimestamp(pauseTime);
847    }
848
849    @Override
850    public Date getEndTime() {
851        return DateUtils.toDate(endTimestamp);
852    }
853
854    @Override
855    public Date getPauseTime() {
856        return DateUtils.toDate(pauseTimestamp);
857    }
858
859    public Timestamp getPauseTimestamp() {
860        return pauseTimestamp;
861    }
862
863    /**
864     * Set created time
865     *
866     * @param createTime created time
867     */
868    public void setCreatedTime(Date createTime) {
869        this.createdTimestamp = DateUtils.convertDateToTimestamp(createTime);
870    }
871
872    /**
873     * Get created time
874     *
875     * @return created time
876     */
877    public Date getCreatedTime() {
878        return DateUtils.toDate(createdTimestamp);
879    }
880
881    /**
882     * Get created timestamp
883     *
884     * @return created timestamp
885     */
886    public Timestamp getCreatedTimestamp() {
887        return createdTimestamp;
888    }
889
890    public String getAppPath() {
891        return appPath;
892    }
893
894    public void setAppPath(String appPath) {
895        this.appPath = appPath;
896    }
897
898    public String getAppName() {
899        return appName;
900    }
901
902    public void setAppName(String appName) {
903        this.appName = appName;
904    }
905
906    public String getId() {
907        return id;
908    }
909
910    public void setId(String id) {
911        this.id = id;
912    }
913
914    public void setExternalId(String externalId) {
915        this.externalId = externalId;
916    }
917
918    public String getExternalId() {
919        return externalId;
920    }
921
922    public String getConf() {
923        return conf == null ? null : conf.getString();
924    }
925
926    public void setConf(String conf) {
927        if (this.conf == null) {
928            this.conf = new StringBlob(conf);
929        }
930        else {
931            this.conf.setString(conf);
932        }
933    }
934
935    public void setConfBlob(StringBlob conf) {
936        this.conf = conf;
937    }
938
939    public StringBlob getConfBlob() {
940        return conf;
941    }
942
943    public void setFrequency(String frequency) {
944        this.frequency = frequency;
945    }
946
947    public String getFrequency() {
948        return frequency;
949    }
950
951
952    public void setTimeZone(String timeZone) {
953        this.timeZone = timeZone;
954    }
955
956    public String getTimeZone() {
957        return timeZone;
958    }
959
960    public void setConcurrency(int concurrency) {
961        this.concurrency = concurrency;
962    }
963
964    public int getConcurrency() {
965        return concurrency;
966    }
967
968    public int getMatThrottling() {
969        return matThrottling;
970    }
971
972    public void setMatThrottling(int matThrottling) {
973        this.matThrottling = matThrottling;
974    }
975
976    public void setTimeout(int timeOut) {
977        this.timeOut = timeOut;
978    }
979
980    public int getTimeout() {
981        return timeOut;
982    }
983
984    public String getUser() {
985        return user;
986    }
987
988    public void setUser(String user) {
989        this.user = user;
990    }
991
992    public String getGroup() {
993        return group;
994    }
995
996    @Override
997    public String getAcl() {
998        return getGroup();
999    }
1000
1001    public void setGroup(String group) {
1002        this.group = group;
1003    }
1004
1005    public String getBundleId() {
1006        return bundleId;
1007    }
1008
1009    public void setBundleId(String bundleId) {
1010        this.bundleId = bundleId;
1011    }
1012
1013    /**
1014     * Return the coordinate application console URL.
1015     *
1016     * @return the coordinate application console URL.
1017     */
1018    public String getConsoleUrl() {
1019        return consoleUrl;
1020    }
1021
1022    /**
1023     * Set the coordinate application console URL.
1024     *
1025     * @param consoleUrl the coordinate application console URL.
1026     */
1027    public void setConsoleUrl(String consoleUrl) {
1028        this.consoleUrl = consoleUrl;
1029    }
1030
1031    @Override
1032    public String toString() {
1033        return MessageFormat.format("Coordinator application id[{0}] status[{1}]", getId(), getStatus());
1034    }
1035
1036    public void setActions(List<CoordinatorActionBean> nodes) {
1037        this.actions = (nodes != null) ? nodes : new ArrayList<CoordinatorActionBean>();
1038    }
1039
1040    @SuppressWarnings("unchecked")
1041    public List<CoordinatorAction> getActions() {
1042        return (List) actions;
1043    }
1044
1045    /**
1046     * Convert a coordinator application list into a JSONArray.
1047     *
1048     * @param applications list.
1049     * @param timeZoneId time zone to use for dates in the JSON array.
1050     * @return the corresponding JSON array.
1051     */
1052    @SuppressWarnings("unchecked")
1053    public static JSONArray toJSONArray(List<CoordinatorJobBean> applications, String timeZoneId) {
1054        JSONArray array = new JSONArray();
1055        if (applications != null) {
1056            for (CoordinatorJobBean application : applications) {
1057                array.add(application.toJSONObject(timeZoneId));
1058            }
1059        }
1060        return array;
1061    }
1062
1063    public int getLastActionNumber() {
1064        return lastActionNumber;
1065    }
1066
1067    public void setLastActionNumber(int lastActionNumber) {
1068        this.lastActionNumber = lastActionNumber;
1069    }
1070
1071    /**
1072     * Set pending to true
1073     */
1074    public void setPending() {
1075        this.pending = 1;
1076    }
1077
1078    /**
1079     * Set pending to false
1080     */
1081    public void resetPending() {
1082        this.pending = 0;
1083    }
1084
1085    public int getNumActions() {
1086        return numActions;
1087    }
1088
1089    public void setNumActions(int numAction) {
1090        this.numActions = numAction;
1091    }
1092
1093    @SuppressWarnings("unchecked")
1094    public JSONObject toJSONObject() {
1095        return toJSONObject("GMT");
1096    }
1097
1098    @SuppressWarnings("unchecked")
1099    public JSONObject toJSONObject(String timeZoneId) {
1100        JSONObject json = new JSONObject();
1101        json.put(JsonTags.COORDINATOR_JOB_PATH, getAppPath());
1102        json.put(JsonTags.COORDINATOR_JOB_NAME, getAppName());
1103        json.put(JsonTags.COORDINATOR_JOB_ID, getId());
1104        json.put(JsonTags.COORDINATOR_JOB_EXTERNAL_ID, getExternalId());
1105        json.put(JsonTags.COORDINATOR_JOB_BUNDLE_ID, getBundleId());
1106        json.put(JsonTags.COORDINATOR_JOB_CONF, getConf());
1107        json.put(JsonTags.COORDINATOR_JOB_STATUS, getStatus().toString());
1108        json.put(JsonTags.COORDINATOR_JOB_EXECUTIONPOLICY, getExecutionOrder().toString());
1109        json.put(JsonTags.COORDINATOR_JOB_FREQUENCY, getFrequency());
1110        json.put(JsonTags.COORDINATOR_JOB_TIMEUNIT, getTimeUnit().toString());
1111        json.put(JsonTags.COORDINATOR_JOB_TIMEZONE, getTimeZone());
1112        json.put(JsonTags.COORDINATOR_JOB_CONCURRENCY, getConcurrency());
1113        json.put(JsonTags.COORDINATOR_JOB_TIMEOUT, getTimeout());
1114        json.put(JsonTags.COORDINATOR_JOB_LAST_ACTION_TIME, JsonUtils.formatDateRfc822(getLastActionTime(), timeZoneId));
1115        json.put(JsonTags.COORDINATOR_JOB_NEXT_MATERIALIZED_TIME,
1116                JsonUtils.formatDateRfc822(getNextMaterializedTime(), timeZoneId));
1117        json.put(JsonTags.COORDINATOR_JOB_START_TIME, JsonUtils.formatDateRfc822(getStartTime(), timeZoneId));
1118        json.put(JsonTags.COORDINATOR_JOB_END_TIME, JsonUtils.formatDateRfc822(getEndTime(), timeZoneId));
1119        json.put(JsonTags.COORDINATOR_JOB_PAUSE_TIME, JsonUtils.formatDateRfc822(getPauseTime(), timeZoneId));
1120        json.put(JsonTags.COORDINATOR_JOB_USER, getUser());
1121        json.put(JsonTags.COORDINATOR_JOB_GROUP, getGroup());
1122        json.put(JsonTags.COORDINATOR_JOB_ACL, getAcl());
1123        json.put(JsonTags.COORDINATOR_JOB_CONSOLE_URL, getConsoleUrl());
1124        json.put(JsonTags.COORDINATOR_JOB_MAT_THROTTLING, getMatThrottling());
1125        json.put(JsonTags.COORDINATOR_ACTIONS, CoordinatorActionBean.toJSONArray(actions, timeZoneId));
1126        json.put(JsonTags.TO_STRING,toString());
1127        json.put(JsonTags.COORDINATOR_JOB_NUM_ACTION, numActions);
1128
1129        return json;
1130    }
1131
1132}