001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie;
016    
017    import java.io.DataInput;
018    import java.io.DataOutput;
019    import java.io.IOException;
020    import java.sql.Timestamp;
021    import java.util.Date;
022    
023    import javax.persistence.Basic;
024    import javax.persistence.Column;
025    import javax.persistence.ColumnResult;
026    import javax.persistence.Entity;
027    import javax.persistence.Lob;
028    import javax.persistence.NamedNativeQueries;
029    import javax.persistence.NamedNativeQuery;
030    import javax.persistence.NamedQueries;
031    import javax.persistence.NamedQuery;
032    import javax.persistence.SqlResultSetMapping;
033    
034    import org.apache.hadoop.io.Writable;
035    import org.apache.oozie.client.CoordinatorAction;
036    import org.apache.oozie.client.rest.JsonCoordinatorAction;
037    import org.apache.oozie.util.DateUtils;
038    import org.apache.oozie.util.WritableUtils;
039    import org.apache.openjpa.persistence.jdbc.Index;
040    
041    @SqlResultSetMapping(
042            name = "CoordActionJobIdLmt",
043            columns = {@ColumnResult(name = "job_id"),
044                @ColumnResult(name = "min_lmt")})
045    
046    @Entity
047    @NamedQueries({
048    
049        @NamedQuery(name = "UPDATE_COORD_ACTION", query = "update CoordinatorActionBean w set w.actionNumber = :actionNumber, w.actionXml = :actionXml, w.consoleUrl = :consoleUrl, w.createdConf = :createdConf, w.errorCode = :errorCode, w.errorMessage = :errorMessage, w.externalStatus = :externalStatus, w.missingDependencies = :missingDependencies, w.runConf = :runConf, w.timeOut = :timeOut, w.trackerUri = :trackerUri, w.type = :type, w.createdTimestamp = :createdTime, w.externalId = :externalId, w.jobId = :jobId, w.lastModifiedTimestamp = :lastModifiedTime, w.nominalTimestamp = :nominalTime, w.slaXml = :slaXml, w.status = :status where w.id = :id"),
050    
051        @NamedQuery(name = "UPDATE_COORD_ACTION_MIN", query = "update CoordinatorActionBean w set w.actionXml = :actionXml, w.missingDependencies = :missingDependencies, w.lastModifiedTimestamp = :lastModifiedTime, w.status = :status where w.id = :id"),
052    
053        @NamedQuery(name = "DELETE_COMPLETED_COORD_ACTIONS", query = "delete from CoordinatorActionBean a where a.id = :id and (a.status = 'SUCCEEDED' OR a.status = 'FAILED' OR a.status = 'KILLED')"),
054    
055        @NamedQuery(name = "GET_COORD_ACTIONS", query = "select OBJECT(w) from CoordinatorActionBean w"),
056    
057        @NamedQuery(name = "GET_COMPLETED_ACTIONS_OLDER_THAN", query = "select OBJECT(a) from CoordinatorActionBean a where a.createdTimestamp < :createdTime and (a.status = 'SUCCEEDED' OR a.status = 'FAILED' OR a.status = 'KILLED')"),
058    
059        @NamedQuery(name = "GET_COORD_ACTION", query = "select OBJECT(a) from CoordinatorActionBean a where a.id = :id"),
060    
061        @NamedQuery(name = "GET_COORD_ACTION_FOR_EXTERNALID", query = "select OBJECT(a) from CoordinatorActionBean a where a.externalId = :externalId"),
062    
063        @NamedQuery(name = "GET_COORD_ACTIONS_FOR_JOB_FIFO", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND a.status = 'READY' order by a.nominalTimestamp"),
064    
065        @NamedQuery(name = "GET_COORD_ACTIONS_FOR_JOB_LIFO", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND a.status = 'READY' order by a.nominalTimestamp desc"),
066    
067        @NamedQuery(name = "GET_COORD_RUNNING_ACTIONS_COUNT", query = "select count(a) from CoordinatorActionBean a where a.jobId = :jobId AND (a.status = 'RUNNING' OR a.status='SUBMITTED')"),
068    
069        @NamedQuery(name = "GET_COORD_ACTIONS_COUNT_BY_JOBID", query = "select count(a) from CoordinatorActionBean a where a.jobId = :jobId"),
070    
071        @NamedQuery(name = "GET_ACTIONS_FOR_COORD_JOB", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId"),
072    
073        @NamedQuery(name = "GET_RUNNING_ACTIONS_FOR_COORD_JOB", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND a.status = 'RUNNING'"),
074    
075        @NamedQuery(name = "GET_RUNNING_ACTIONS_OLDER_THAN", query = "select OBJECT(a) from CoordinatorActionBean a where a.status = 'RUNNING' AND a.lastModifiedTimestamp <= :lastModifiedTime"),
076    
077        @NamedQuery(name = "GET_WAITING_SUBMITTED_ACTIONS_OLDER_THAN", query = "select OBJECT(a) from CoordinatorActionBean a where (a.status = 'WAITING' OR a.status = 'SUBMITTED') AND a.lastModifiedTimestamp <= :lastModifiedTime"),
078    
079        @NamedQuery(name = "GET_ACTIONS_FOR_DATES", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND (a.status = 'TIMEDOUT' OR a.status = 'SUCCEEDED' OR a.status = 'KILLED' OR a.status = 'FAILED') AND a.nominalTimestamp >= :startTime AND a.nominalTimestamp <= :endTime"),
080    
081        @NamedQuery(name = "GET_ACTION_FOR_NOMINALTIME", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND a.nominalTimestamp = :nominalTime"),
082    
083        @NamedQuery(name = "GET_COORD_ACTIONS_COUNT", query = "select count(w) from CoordinatorActionBean w")})
084    
085    @NamedNativeQueries({
086    
087        @NamedNativeQuery(name = "GET_READY_ACTIONS_GROUP_BY_JOBID", query = "select a.job_id as job_id, MIN(a.last_modified_time) as min_lmt from COORD_ACTIONS a where a.status = 'READY' GROUP BY a.job_id HAVING MIN(a.last_modified_time) < ?", resultSetMapping = "CoordActionJobIdLmt")
088            })
089    public class CoordinatorActionBean extends JsonCoordinatorAction implements
090            Writable {
091        @Basic
092        @Index
093        @Column(name = "job_id")
094        private String jobId;
095    
096        @Basic
097        @Index
098        @Column(name = "status")
099        private String status = null;
100    
101        @Basic
102        @Column(name = "nominal_time")
103        private java.sql.Timestamp nominalTimestamp = null;
104    
105        @Basic
106        @Index
107        @Column(name = "last_modified_time")
108        private java.sql.Timestamp lastModifiedTimestamp = null;
109    
110        @Basic
111        @Index
112        @Column(name = "created_time")
113        private java.sql.Timestamp createdTimestamp = null;
114    
115        @Basic
116        @Index
117        @Column(name = "rerun_time")
118        private java.sql.Timestamp rerunTimestamp = null;
119    
120        @Basic
121        @Index
122        @Column(name = "external_id")
123        private String externalId;
124    
125        @Column(name = "sla_xml")
126        @Lob
127        private String slaXml = null;
128    
129        public CoordinatorActionBean() {
130        }
131    
132        /**
133         * Serialize the coordinator bean to a data output.
134         *
135         * @param dataOutput data output.
136         * @throws IOException thrown if the coordinator bean could not be serialized.
137         */
138        public void write(DataOutput dataOutput) throws IOException {
139            WritableUtils.writeStr(dataOutput, getJobId());
140            WritableUtils.writeStr(dataOutput, getType());
141            WritableUtils.writeStr(dataOutput, getId());
142            WritableUtils.writeStr(dataOutput, getCreatedConf());
143            WritableUtils.writeStr(dataOutput, getStatus().toString());
144            dataOutput.writeInt(getActionNumber());
145            WritableUtils.writeStr(dataOutput, getRunConf());
146            WritableUtils.writeStr(dataOutput, getExternalStatus());
147            WritableUtils.writeStr(dataOutput, getTrackerUri());
148            WritableUtils.writeStr(dataOutput, getErrorCode());
149            WritableUtils.writeStr(dataOutput, getErrorMessage());
150        }
151    
152        /**
153         * Deserialize a coordinator bean from a data input.
154         *
155         * @param dataInput data input.
156         * @throws IOException thrown if the workflow bean could not be deserialized.
157         */
158        public void readFields(DataInput dataInput) throws IOException {
159            setJobId(WritableUtils.readStr(dataInput));
160            setType(WritableUtils.readStr(dataInput));
161            setId(WritableUtils.readStr(dataInput));
162            setCreatedConf(WritableUtils.readStr(dataInput));
163            setStatus(CoordinatorAction.Status.valueOf(WritableUtils
164                    .readStr(dataInput)));
165            setRunConf(WritableUtils.readStr(dataInput));
166            setExternalStatus(WritableUtils.readStr(dataInput));
167            setTrackerUri(WritableUtils.readStr(dataInput));
168            setConsoleUrl(WritableUtils.readStr(dataInput));
169            long d = dataInput.readLong();
170            if (d != -1) {
171                setCreatedTime(new Date(d));
172            }
173            d = dataInput.readLong();
174            if (d != -1) {
175                setLastModifiedTime(new Date(d));
176            }
177            d = dataInput.readLong();
178            d = dataInput.readLong();
179        }
180    
181        @Override
182        public String getJobId() {
183            return this.jobId;
184        }
185    
186        @Override
187        public void setJobId(String id) {
188            super.setJobId(id);
189            this.jobId = id;
190        }
191    
192        @Override
193        public Status getStatus() {
194            return Status.valueOf(status);
195        }
196    
197        @Override
198        public void setStatus(Status status) {
199            super.setStatus(status);
200            this.status = status.toString();
201        }
202    
203        @Override
204        public void setCreatedTime(Date createdTime) {
205            this.createdTimestamp = DateUtils.convertDateToTimestamp(createdTime);
206            super.setCreatedTime(createdTime);
207        }
208    
209        public void setRerunTime(Date rerunTime) {
210            this.rerunTimestamp = DateUtils.convertDateToTimestamp(rerunTime);
211        }
212    
213        @Override
214        public void setNominalTime(Date nominalTime) {
215            this.nominalTimestamp = DateUtils.convertDateToTimestamp(nominalTime);
216            super.setNominalTime(nominalTime);
217        }
218    
219        @Override
220        public void setLastModifiedTime(Date lastModifiedTime) {
221            this.lastModifiedTimestamp = DateUtils.convertDateToTimestamp(lastModifiedTime);
222            super.setLastModifiedTime(lastModifiedTime);
223        }
224    
225        @Override
226        public Date getCreatedTime() {
227            return DateUtils.toDate(createdTimestamp);
228        }
229    
230        public Timestamp getCreatedTimestamp() {
231            return createdTimestamp;
232        }
233    
234        public Date getRerunTime() {
235            return DateUtils.toDate(rerunTimestamp);
236        }
237    
238        public Timestamp getRerunTimestamp() {
239            return rerunTimestamp;
240        }
241    
242        @Override
243        public Date getLastModifiedTime() {
244            return DateUtils.toDate(lastModifiedTimestamp);
245        }
246    
247        public Timestamp getLastModifiedTimestamp() {
248            return lastModifiedTimestamp;
249        }
250    
251        @Override
252        public Date getNominalTime() {
253            return DateUtils.toDate(nominalTimestamp);
254        }
255    
256        public Timestamp getNominalTimestamp() {
257            return nominalTimestamp;
258        }
259    
260        @Override
261        public String getExternalId() {
262            return externalId;
263        }
264    
265        @Override
266        public void setExternalId(String externalId) {
267            super.setExternalId(externalId);
268            this.externalId = externalId;
269        }
270    
271        public String getSlaXml() {
272            return slaXml;
273        }
274    
275        public void setSlaXml(String slaXml) {
276            this.slaXml = slaXml;
277        }
278    
279        /**
280         * @return true if in terminal status
281         */
282        public boolean isTerminalStatus() {
283            boolean isTerminal = true;
284            switch (getStatus()) {
285                case WAITING:
286                case READY:
287                case SUBMITTED:
288                case RUNNING:
289                    isTerminal = false;
290                    break;
291                default:
292                    isTerminal = true;
293                    break;
294            }
295            return isTerminal;
296        }
297    
298    }