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