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