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.WorkflowAction;
023import org.apache.oozie.client.WorkflowJob;
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.oozie.workflow.WorkflowInstance;
030import org.apache.oozie.workflow.lite.LiteWorkflowInstance;
031import org.apache.openjpa.persistence.jdbc.Index;
032import org.apache.openjpa.persistence.jdbc.Strategy;
033import org.json.simple.JSONArray;
034import org.json.simple.JSONObject;
035
036import javax.persistence.Basic;
037import javax.persistence.Column;
038import javax.persistence.Entity;
039import javax.persistence.Id;
040import javax.persistence.Lob;
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
056@NamedQueries({
057
058    @NamedQuery(name = "UPDATE_WORKFLOW", query = "update WorkflowJobBean w set w.appName = :appName, w.appPath = :appPath, w.conf = :conf, w.group = :groupName, w.run = :run, w.user = :user, w.createdTimestamp = :createdTime, w.endTimestamp = :endTime, w.externalId = :externalId, w.lastModifiedTimestamp = :lastModTime,w.logToken = :logToken, w.protoActionConf = :protoActionConf, w.slaXml =:slaXml, w.startTimestamp = :startTime, w.statusStr = :status, w.wfInstance = :wfInstance where w.id = :id"),
059
060    @NamedQuery(name = "UPDATE_WORKFLOW_MODTIME", query = "update WorkflowJobBean w set w.lastModifiedTimestamp = :lastModTime where w.id = :id"),
061
062    @NamedQuery(name = "UPDATE_WORKFLOW_STATUS_MODTIME", query = "update WorkflowJobBean w set w.statusStr = :status, w.lastModifiedTimestamp = :lastModTime where w.id = :id"),
063
064    @NamedQuery(name = "UPDATE_WORKFLOW_PARENT_MODIFIED", query = "update WorkflowJobBean w set w.parentId = :parentId, w.lastModifiedTimestamp = :lastModTime where w.id = :id"),
065
066    @NamedQuery(name = "UPDATE_WORKFLOW_STATUS_INSTANCE_MODIFIED", query = "update WorkflowJobBean w set w.statusStr = :status, w.wfInstance = :wfInstance, w.lastModifiedTimestamp = :lastModTime where w.id = :id"),
067
068    @NamedQuery(name = "UPDATE_WORKFLOW_STATUS_INSTANCE_MOD_END", query = "update WorkflowJobBean w set w.statusStr = :status, w.wfInstance = :wfInstance, w.lastModifiedTimestamp = :lastModTime, w.endTimestamp = :endTime where w.id = :id"),
069
070    @NamedQuery(name = "UPDATE_WORKFLOW_STATUS_INSTANCE_MOD_START_END", query = "update WorkflowJobBean w set w.statusStr = :status, w.wfInstance = :wfInstance, w.lastModifiedTimestamp = :lastModTime, w.startTimestamp = :startTime, w.endTimestamp = :endTime where w.id = :id"),
071
072    @NamedQuery(name = "UPDATE_WORKFLOW_RERUN", query = "update WorkflowJobBean w set w.appName = :appName, w.protoActionConf = :protoActionConf, w.appPath = :appPath, w.conf = :conf, w.logToken = :logToken, w.user = :user, w.group = :group, w.externalId = :externalId, w.endTimestamp = :endTime, w.run = :run, w.statusStr = :status, w.wfInstance = :wfInstance, w.lastModifiedTimestamp = :lastModTime where w.id = :id"),
073
074    @NamedQuery(name = "DELETE_WORKFLOW", query = "delete from WorkflowJobBean w where w.id IN (:id)"),
075
076    @NamedQuery(name = "GET_WORKFLOWS", query = "select OBJECT(w) from WorkflowJobBean w order by w.startTimestamp desc"),
077
078    @NamedQuery(name = "GET_WORKFLOWS_COLUMNS", query = "select w.id, w.appName, w.statusStr, w.run, w.user, w.group, w.createdTimestamp, w.startTimestamp, w.lastModifiedTimestamp, w.endTimestamp, w.externalId, w.parentId from WorkflowJobBean w order by w.createdTimestamp desc"),
079
080    @NamedQuery(name = "GET_WORKFLOWS_COUNT", query = "select count(w) from WorkflowJobBean w"),
081
082    @NamedQuery(name = "GET_COMPLETED_WORKFLOWS_OLDER_THAN", query = "select w from WorkflowJobBean w where w.endTimestamp < :endTime"),
083
084    @NamedQuery(name = "GET_COMPLETED_WORKFLOWS_WITH_NO_PARENT_OLDER_THAN", query = "select w.id from WorkflowJobBean w where w.endTimestamp < :endTime and w.parentId is null"),
085
086    @NamedQuery(name = "GET_COMPLETED_COORD_WORKFLOWS_OLDER_THAN", query = "select w.id, w.parentId from WorkflowJobBean w where w.endTimestamp < :endTime and w.parentId like '%C@%'"),
087
088    @NamedQuery(name = "GET_WORKFLOW", query = "select OBJECT(w) from WorkflowJobBean w where w.id = :id"),
089
090    @NamedQuery(name = "GET_WORKFLOW_STARTTIME", query = "select w.id, w.startTimestamp from WorkflowJobBean w where w.id = :id"),
091
092    @NamedQuery(name = "GET_WORKFLOW_START_END_TIME", query = "select w.id, w.startTimestamp, w.endTimestamp from WorkflowJobBean w where w.id = :id"),
093
094    @NamedQuery(name = "GET_WORKFLOW_USER_GROUP", query = "select w.user, w.group from WorkflowJobBean w where w.id = :id"),
095
096    @NamedQuery(name = "GET_WORKFLOW_SUSPEND", query = "select w.id, w.user, w.group, w.appName, w.statusStr, w.parentId, w.startTimestamp, w.endTimestamp, w.logToken, w.wfInstance  from WorkflowJobBean w where w.id = :id"),
097
098    @NamedQuery(name = "GET_WORKFLOW_RERUN", query = "select w.id, w.user, w.group, w.appName, w.statusStr, w.run, w.logToken, w.wfInstance, w.parentId from WorkflowJobBean w where w.id = :id"),
099
100    @NamedQuery(name = "GET_WORKFLOW_DEFINITION", query = "select w.id, w.user, w.group, w.appName, w.logToken, w.wfInstance from WorkflowJobBean w where w.id = :id"),
101
102    @NamedQuery(name = "GET_WORKFLOW_ACTION_OP", query = "select w.id, w.user, w.group, w.appName, w.appPath, w.statusStr, w.run, w.parentId, w.logToken, w.wfInstance, w.protoActionConf from WorkflowJobBean w where w.id = :id"),
103
104    @NamedQuery(name = "GET_WORKFLOW_KILL", query = "select w.id, w.user, w.group, w.appName, w.appPath, w.statusStr, w.parentId, w.startTimestamp, w.endTimestamp, w.logToken, w.wfInstance, w.slaXml, w.protoActionConf from WorkflowJobBean w where w.id = :id"),
105
106    @NamedQuery(name = "GET_WORKFLOW_RESUME", query = "select w.id, w.user, w.group, w.appName, w.appPath, w.statusStr, w.parentId, w.startTimestamp, w.endTimestamp, w.logToken, w.wfInstance, w.protoActionConf from WorkflowJobBean w where w.id = :id"),
107
108    @NamedQuery(name = "GET_WORKFLOW_FOR_UPDATE", query = "select OBJECT(w) from WorkflowJobBean w where w.id = :id"),
109
110    @NamedQuery(name = "GET_WORKFLOW_FOR_SLA", query = "select w.id, w.statusStr, w.startTimestamp, w.endTimestamp from WorkflowJobBean w where w.id = :id"),
111
112    @NamedQuery(name = "GET_WORKFLOW_ID_FOR_EXTERNAL_ID", query = "select  w.id from WorkflowJobBean w where w.externalId = :externalId"),
113
114    @NamedQuery(name = "GET_WORKFLOWS_COUNT_WITH_STATUS", query = "select count(w) from WorkflowJobBean w where w.statusStr = :status"),
115
116    @NamedQuery(name = "GET_WORKFLOWS_COUNT_WITH_STATUS_IN_LAST_N_SECS", query = "select count(w) from WorkflowJobBean w where w.statusStr = :status and w.lastModifiedTimestamp > :lastModTime"),
117
118    @NamedQuery(name = "GET_WORKFLOWS_WITH_WORKFLOW_PARENT_ID", query = "select w.id from WorkflowJobBean w where w.parentId = :parentId"),
119
120    @NamedQuery(name = "GET_WORKFLOWS_WITH_COORD_PARENT_ID", query = "select w.id from WorkflowJobBean w where w.parentId like :parentId"), // when setting parentId parameter, make sure to append a '%' (percent symbol) at the end (e.g. 0000004-130709155224435-oozie-rkan-C%")
121
122    @NamedQuery(name = "GET_WORKFLOWS_BASIC_INFO_BY_PARENT_ID", query = "select w.id, w.statusStr, w.endTimestamp from WorkflowJobBean w where w.parentId = :parentId"),
123
124    @NamedQuery(name = "GET_WORKFLOWS_BASIC_INFO_BY_COORD_PARENT_ID", query = "select w.id,  w.statusStr, w.endTimestamp from WorkflowJobBean w where w.parentId like :parentId"),
125
126    @NamedQuery(name = "GET_WORKFLOW_FOR_USER", query = "select w.user from WorkflowJobBean w where w.id = :id"),
127
128    @NamedQuery(name = "GET_WORKFLOW_STATUS", query = "select w.statusStr from WorkflowJobBean w where w.id = :id"),
129
130    @NamedQuery(name = "GET_WORKFLOWS_PARENT_COORD_RERUN", query = "select w.id, w.statusStr, w.startTimestamp, w.endTimestamp "
131            + "from WorkflowJobBean w where w.parentId = :parentId order by w.createdTimestamp")})
132@Table(name = "WF_JOBS")
133public class WorkflowJobBean implements Writable, WorkflowJob, JsonBean {
134
135    @Id
136    private String id;
137
138    @Basic
139    @Column(name = "proto_action_conf")
140    @Lob
141    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
142    private StringBlob protoActionConf;
143
144    @Basic
145    @Column(name = "log_token")
146    private String logToken = null;
147
148    @Basic
149    @Index
150    @Column(name = "external_id")
151    private String externalId = null;
152
153    @Basic
154    @Index
155    @Column(name = "status")
156    private String statusStr = WorkflowJob.Status.PREP.toString();
157
158    @Basic
159    @Column(name = "created_time")
160    private java.sql.Timestamp createdTimestamp = null;
161
162    @Basic
163    @Column(name = "start_time")
164    private java.sql.Timestamp startTimestamp = null;
165
166    @Basic
167    @Index
168    @Column(name = "end_time")
169    private java.sql.Timestamp endTimestamp = null;
170
171    @Basic
172    @Index
173    @Column(name = "last_modified_time")
174    private java.sql.Timestamp lastModifiedTimestamp = null;
175
176    @Basic
177    @Column(name = "wf_instance")
178    @Lob
179    @Strategy("org.apache.oozie.executor.jpa.BinaryBlobValueHandler")
180    private BinaryBlob wfInstance ;
181
182    @Basic
183    @Column(name = "sla_xml")
184    @Lob
185    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
186    private StringBlob slaXml;
187
188
189    @Basic
190    @Column(name = "app_name")
191    private String appName = null;
192
193    @Basic
194    @Column(name = "app_path")
195    private String appPath = null;
196
197    @Basic
198    @Column(name = "conf")
199    @Lob
200    @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler")
201    private StringBlob conf;
202
203    @Basic
204    @Column(name = "user_name")
205    private String user = null;
206
207    @Basic
208    @Column(name = "group_name")
209    private String group;
210
211    @Basic
212    @Column(name = "run")
213    private int run = 1;
214
215    @Basic
216    @Index
217    @Column(name = "parent_id")
218    private String parentId;
219
220    @Transient
221    private String consoleUrl;
222
223    @Transient
224    private List<WorkflowActionBean> actions;
225
226
227    /**
228     * Default constructor.
229     */
230    public WorkflowJobBean() {
231        actions = new ArrayList<WorkflowActionBean>();
232    }
233
234    /**
235     * Serialize the workflow bean to a data output.
236     *
237     * @param dataOutput data output.
238     * @throws IOException thrown if the workflow bean could not be serialized.
239     */
240    public void write(DataOutput dataOutput) throws IOException {
241        WritableUtils.writeStr(dataOutput, getAppPath());
242        WritableUtils.writeStr(dataOutput, getAppName());
243        WritableUtils.writeStr(dataOutput, getId());
244        WritableUtils.writeStr(dataOutput, getParentId());
245        WritableUtils.writeStr(dataOutput, getConf());
246        WritableUtils.writeStr(dataOutput, getStatusStr());
247        dataOutput.writeLong((getCreatedTime() != null) ? getCreatedTime().getTime() : -1);
248        dataOutput.writeLong((getStartTime() != null) ? getStartTime().getTime() : -1);
249        dataOutput.writeLong((getLastModifiedTime() != null) ? getLastModifiedTime().getTime() : -1);
250        dataOutput.writeLong((getEndTime() != null) ? getEndTime().getTime() : -1);
251        WritableUtils.writeStr(dataOutput, getUser());
252        WritableUtils.writeStr(dataOutput, getGroup());
253        dataOutput.writeInt(getRun());
254        WritableUtils.writeStr(dataOutput, logToken);
255        WritableUtils.writeStr(dataOutput, getProtoActionConf());
256    }
257
258    /**
259     * Deserialize a workflow bean from a data input.
260     *
261     * @param dataInput data input.
262     * @throws IOException thrown if the workflow bean could not be deserialized.
263     */
264    public void readFields(DataInput dataInput) throws IOException {
265        setAppPath(WritableUtils.readStr(dataInput));
266        setAppName(WritableUtils.readStr(dataInput));
267        setId(WritableUtils.readStr(dataInput));
268        setParentId(WritableUtils.readStr(dataInput));
269        setConf(WritableUtils.readStr(dataInput));
270        setStatus(WorkflowJob.Status.valueOf(WritableUtils.readStr(dataInput)));
271        // setStatus(WritableUtils.readStr(dataInput));
272        long d = dataInput.readLong();
273        if (d != -1) {
274            setCreatedTime(new Date(d));
275        }
276        d = dataInput.readLong();
277        if (d != -1) {
278        }
279        setStartTime(new Date(d));
280        d = dataInput.readLong();
281        if (d != -1) {
282            setLastModifiedTime(new Date(d));
283        }
284        d = dataInput.readLong();
285        if (d != -1) {
286            setEndTime(new Date(d));
287        }
288        setUser(WritableUtils.readStr(dataInput));
289        setGroup(WritableUtils.readStr(dataInput));
290        setRun(dataInput.readInt());
291        logToken = WritableUtils.readStr(dataInput);
292        setProtoActionConf(WritableUtils.readStr(dataInput));
293        setExternalId(getExternalId());
294    }
295
296    public boolean inTerminalState() {
297        boolean inTerminalState = false;
298        switch (WorkflowJob.Status.valueOf(statusStr)) {
299            case FAILED:
300            case KILLED:
301            case SUCCEEDED:
302                inTerminalState = true;
303                break;
304            default:
305                break;
306        }
307        return inTerminalState;
308    }
309
310    public String getLogToken() {
311        return logToken;
312    }
313
314    public void setLogToken(String logToken) {
315        this.logToken = logToken;
316    }
317
318    public String getSlaXml() {
319        return slaXml == null ? null : slaXml.getString();
320    }
321
322    public void setSlaXml(String slaXml) {
323        if (this.slaXml == null) {
324            this.slaXml = new StringBlob(slaXml);
325        }
326        else {
327            this.slaXml.setString(slaXml);
328        }
329    }
330
331    public void setSlaXmlBlob(StringBlob slaXml) {
332        this.slaXml = slaXml;
333    }
334
335    public StringBlob getSlaXmlBlob() {
336        return this.slaXml;
337    }
338
339    public WorkflowInstance getWorkflowInstance() {
340        return wfInstance == null ? null : get(wfInstance.getBytes());
341    }
342
343    public BinaryBlob getWfInstanceBlob() {
344        return this.wfInstance;
345    }
346
347    public void setWorkflowInstance(WorkflowInstance workflowInstance) {
348        if (this.wfInstance == null) {
349            this.wfInstance = new BinaryBlob(WritableUtils.toByteArray((LiteWorkflowInstance) workflowInstance), true);
350        }
351        else {
352            this.wfInstance.setBytes(WritableUtils.toByteArray((LiteWorkflowInstance) workflowInstance));
353        }
354    }
355
356    public void setWfInstanceBlob(BinaryBlob wfInstance) {
357        this.wfInstance = wfInstance;
358    }
359
360    public String getProtoActionConf() {
361        return protoActionConf == null ? null : protoActionConf.getString();
362    }
363
364    public void setProtoActionConf(String protoActionConf) {
365        if (this.protoActionConf == null) {
366            this.protoActionConf = new StringBlob(protoActionConf);
367        }
368        else {
369            this.protoActionConf.setString(protoActionConf);
370        }
371    }
372
373    public void setProtoActionConfBlob (StringBlob protoBytes) {
374        this.protoActionConf = protoBytes;
375    }
376
377    public StringBlob getProtoActionConfBlob() {
378        return this.protoActionConf;
379    }
380
381    public String getlogToken() {
382        return logToken;
383    }
384
385    public Timestamp getLastModifiedTimestamp() {
386        return lastModifiedTimestamp;
387    }
388
389    public Timestamp getStartTimestamp() {
390        return startTimestamp;
391    }
392
393    public Timestamp getCreatedTimestamp() {
394        return createdTimestamp;
395    }
396
397    public Timestamp getEndTimestamp() {
398        return endTimestamp;
399    }
400
401    public void setStatusStr (String statusStr) {
402        this.statusStr = statusStr;
403    }
404
405    public void setStatus(Status val) {
406        this.statusStr = val.toString();
407    }
408
409    @Override
410    public Status getStatus() {
411        return Status.valueOf(statusStr);
412    }
413
414    public String getStatusStr() {
415        return statusStr;
416    }
417
418    public void setExternalId(String externalId) {
419        this.externalId = externalId;
420    }
421
422    @Override
423    public String getExternalId() {
424        return externalId;
425    }
426
427    public void setLastModifiedTime(Date lastModifiedTime) {
428        this.lastModifiedTimestamp = DateUtils.convertDateToTimestamp(lastModifiedTime);
429    }
430
431    public Date getLastModifiedTime() {
432        return DateUtils.toDate(lastModifiedTimestamp);
433    }
434
435    public Date getCreatedTime() {
436        return DateUtils.toDate(createdTimestamp);
437    }
438
439    public void setCreatedTime(Date createdTime) {
440        this.createdTimestamp = DateUtils.convertDateToTimestamp(createdTime);
441    }
442
443    @Override
444    public Date getStartTime() {
445        return DateUtils.toDate(startTimestamp);
446    }
447
448    public void setStartTime(Date startTime) {
449        this.startTimestamp = DateUtils.convertDateToTimestamp(startTime);
450    }
451
452    public Date getEndTime() {
453        return DateUtils.toDate(endTimestamp);
454    }
455
456    public void setEndTime(Date endTime) {
457        this.endTimestamp = DateUtils.convertDateToTimestamp(endTime);
458    }
459
460    private WorkflowInstance get(byte[] array) {
461        LiteWorkflowInstance pInstance = WritableUtils.fromByteArray(array, LiteWorkflowInstance.class);
462        return pInstance;
463    }
464
465    public JSONObject toJSONObject() {
466        return toJSONObject("GMT");
467    }
468
469    @SuppressWarnings("unchecked")
470    public JSONObject toJSONObject(String timeZoneId) {
471        JSONObject json = new JSONObject();
472        json.put(JsonTags.WORKFLOW_APP_PATH, getAppPath());
473        json.put(JsonTags.WORKFLOW_APP_NAME, getAppName());
474        json.put(JsonTags.WORKFLOW_ID, getId());
475        json.put(JsonTags.WORKFLOW_EXTERNAL_ID, getExternalId());
476        json.put(JsonTags.WORKFLOW_PARENT_ID, getParentId());
477        json.put(JsonTags.WORKFLOW_CONF, getConf());
478        json.put(JsonTags.WORKFLOW_STATUS, getStatus().toString());
479        json.put(JsonTags.WORKFLOW_LAST_MOD_TIME, JsonUtils.formatDateRfc822(getLastModifiedTime(), timeZoneId));
480        json.put(JsonTags.WORKFLOW_CREATED_TIME, JsonUtils.formatDateRfc822(getCreatedTime(), timeZoneId));
481        json.put(JsonTags.WORKFLOW_START_TIME, JsonUtils.formatDateRfc822(getStartTime(), timeZoneId));
482        json.put(JsonTags.WORKFLOW_END_TIME, JsonUtils.formatDateRfc822(getEndTime(), timeZoneId));
483        json.put(JsonTags.WORKFLOW_USER, getUser());
484        json.put(JsonTags.WORKFLOW_GROUP, getGroup());
485        json.put(JsonTags.WORKFLOW_ACL, getAcl());
486        json.put(JsonTags.WORKFLOW_RUN, (long) getRun());
487        json.put(JsonTags.WORKFLOW_CONSOLE_URL, getConsoleUrl());
488        json.put(JsonTags.WORKFLOW_ACTIONS, WorkflowActionBean.toJSONArray(actions, timeZoneId));
489        json.put(JsonTags.TO_STRING, toString());
490        return json;
491    }
492
493    public String getAppPath() {
494        return appPath;
495    }
496
497    public void setAppPath(String appPath) {
498        this.appPath = appPath;
499    }
500
501    public String getAppName() {
502        return appName;
503    }
504
505    public void setAppName(String appName) {
506        this.appName = appName;
507    }
508
509    public String getId() {
510        return id;
511    }
512
513    public void setId(String id) {
514        this.id = id;
515    }
516
517    public String getConf() {
518        return conf == null ? null : conf.getString();
519    }
520
521    public void setConf(String conf) {
522        if (this.conf == null) {
523            this.conf = new StringBlob(conf);
524        }
525        else {
526            this.conf.setString(conf);
527        }
528    }
529
530    public void setConfBlob(StringBlob conf) {
531        this.conf = conf;
532    }
533
534    public StringBlob getConfBlob() {
535        return this.conf;
536    }
537
538    public String getUser() {
539        return user;
540    }
541
542    public void setUser(String user) {
543        this.user = user;
544    }
545
546    public String getGroup() {
547        return group;
548    }
549
550    @Override
551    public String getAcl() {
552        return getGroup();
553    }
554
555    public void setGroup(String group) {
556        this.group = group;
557    }
558
559    public int getRun() {
560        return run;
561    }
562
563    public void setRun(int run) {
564        this.run = run;
565    }
566
567    /**
568     * Return the workflow job console URL.
569     *
570     * @return the workflow job console URL.
571     */
572    public String getConsoleUrl() {
573        return consoleUrl;
574    }
575
576    /**
577     * For a sub-workflow, return the Parent Workflow ID and for a top level workflow
578     * return the Coordinator action id, if any.
579     *
580     * @return the Parent Workflow Id/Coordinator Id if any.
581     */
582    public String getParentId() {
583        return parentId;
584    }
585
586    /**
587     * Set parent id for the workflow.
588     * For a top level workflow it is the coordinator action id if submitted through coordinator
589     *
590     * @param parentId the Parent Action id
591     */
592    public void setParentId(String parentId) {
593        this.parentId = parentId;
594    }
595
596    /**
597     * Set the workflow job console URL.
598     *
599     * @param consoleUrl the workflow job console URL.
600     */
601    public void setConsoleUrl(String consoleUrl) {
602        this.consoleUrl = consoleUrl;
603    }
604
605    @SuppressWarnings("unchecked")
606    public List<WorkflowAction> getActions() {
607        return (List) actions;
608    }
609
610    public void setActions(List<WorkflowActionBean> nodes) {
611        this.actions = (nodes != null) ? nodes : new ArrayList<WorkflowActionBean>();
612    }
613
614    @Override
615    public String toString() {
616        return MessageFormat.format("Workflow id[{0}] status[{1}]", getId(), getStatus());
617    }
618
619    /**
620     * Convert a workflows list into a JSONArray.
621     *
622     * @param workflows workflows list.
623     * @param timeZoneId time zone to use for dates in the JSON array.
624     * @return the corresponding JSON array.
625     */
626    @SuppressWarnings("unchecked")
627    public static JSONArray toJSONArray(List<WorkflowJobBean> workflows, String timeZoneId) {
628        JSONArray array = new JSONArray();
629        if (workflows != null) {
630            for (WorkflowJobBean node : workflows) {
631                array.add(node.toJSONObject(timeZoneId));
632            }
633        }
634        return array;
635    }
636
637
638
639}