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