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_ACTIONS_FOR_COORDINATOR", query = "delete from CoordinatorActionBean a where a.jobId = :jobId and (a.status = 'SUCCEEDED' OR a.status = 'FAILED' OR a.status= 'KILLED' OR a.status= 'TIMEDOUT' OR a.status= 'DISCARDED')"),
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        @NamedQuery(name = "GET_COORD_ACTIONS_FOR_JOB_OLDER_THAN", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId = :jobId AND a.lastModifiedTimestamp > :lastModifiedTime")
086    
087        })
088    
089    @NamedNativeQueries({
090    
091        @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")
092            })
093    public class CoordinatorActionBean extends JsonCoordinatorAction implements
094            Writable {
095        @Basic
096        @Index
097        @Column(name = "job_id")
098        private String jobId;
099    
100        @Basic
101        @Index
102        @Column(name = "status")
103        private String status = null;
104    
105        @Basic
106        @Column(name = "nominal_time")
107        private java.sql.Timestamp nominalTimestamp = null;
108    
109        @Basic
110        @Index
111        @Column(name = "last_modified_time")
112        private java.sql.Timestamp lastModifiedTimestamp = null;
113    
114        @Basic
115        @Index
116        @Column(name = "created_time")
117        private java.sql.Timestamp createdTimestamp = null;
118    
119        @Basic
120        @Index
121        @Column(name = "rerun_time")
122        private java.sql.Timestamp rerunTimestamp = null;
123    
124        @Basic
125        @Index
126        @Column(name = "external_id")
127        private String externalId;
128    
129        @Column(name = "sla_xml")
130        @Lob
131        private String slaXml = null;
132    
133        public CoordinatorActionBean() {
134        }
135    
136        /**
137         * Serialize the coordinator bean to a data output.
138         *
139         * @param dataOutput data output.
140         * @throws IOException thrown if the coordinator bean could not be serialized.
141         */
142        public void write(DataOutput dataOutput) throws IOException {
143            WritableUtils.writeStr(dataOutput, getJobId());
144            WritableUtils.writeStr(dataOutput, getType());
145            WritableUtils.writeStr(dataOutput, getId());
146            WritableUtils.writeStr(dataOutput, getCreatedConf());
147            WritableUtils.writeStr(dataOutput, getStatus().toString());
148            dataOutput.writeInt(getActionNumber());
149            WritableUtils.writeStr(dataOutput, getRunConf());
150            WritableUtils.writeStr(dataOutput, getExternalStatus());
151            WritableUtils.writeStr(dataOutput, getTrackerUri());
152            WritableUtils.writeStr(dataOutput, getErrorCode());
153            WritableUtils.writeStr(dataOutput, getErrorMessage());
154        }
155    
156        /**
157         * Deserialize a coordinator bean from a data input.
158         *
159         * @param dataInput data input.
160         * @throws IOException thrown if the workflow bean could not be deserialized.
161         */
162        public void readFields(DataInput dataInput) throws IOException {
163            setJobId(WritableUtils.readStr(dataInput));
164            setType(WritableUtils.readStr(dataInput));
165            setId(WritableUtils.readStr(dataInput));
166            setCreatedConf(WritableUtils.readStr(dataInput));
167            setStatus(CoordinatorAction.Status.valueOf(WritableUtils
168                    .readStr(dataInput)));
169            setRunConf(WritableUtils.readStr(dataInput));
170            setExternalStatus(WritableUtils.readStr(dataInput));
171            setTrackerUri(WritableUtils.readStr(dataInput));
172            setConsoleUrl(WritableUtils.readStr(dataInput));
173            long d = dataInput.readLong();
174            if (d != -1) {
175                setCreatedTime(new Date(d));
176            }
177            d = dataInput.readLong();
178            if (d != -1) {
179                setLastModifiedTime(new Date(d));
180            }
181            d = dataInput.readLong();
182            d = dataInput.readLong();
183        }
184    
185        @Override
186        public String getJobId() {
187            return this.jobId;
188        }
189    
190        @Override
191        public void setJobId(String id) {
192            super.setJobId(id);
193            this.jobId = id;
194        }
195    
196        @Override
197        public Status getStatus() {
198            return Status.valueOf(status);
199        }
200    
201        @Override
202        public void setStatus(Status status) {
203            super.setStatus(status);
204            this.status = status.toString();
205        }
206    
207        @Override
208        public void setCreatedTime(Date createdTime) {
209            this.createdTimestamp = DateUtils.convertDateToTimestamp(createdTime);
210            super.setCreatedTime(createdTime);
211        }
212    
213        public void setRerunTime(Date rerunTime) {
214            this.rerunTimestamp = DateUtils.convertDateToTimestamp(rerunTime);
215        }
216    
217        @Override
218        public void setNominalTime(Date nominalTime) {
219            this.nominalTimestamp = DateUtils.convertDateToTimestamp(nominalTime);
220            super.setNominalTime(nominalTime);
221        }
222    
223        @Override
224        public void setLastModifiedTime(Date lastModifiedTime) {
225            this.lastModifiedTimestamp = DateUtils.convertDateToTimestamp(lastModifiedTime);
226            super.setLastModifiedTime(lastModifiedTime);
227        }
228    
229        @Override
230        public Date getCreatedTime() {
231            return DateUtils.toDate(createdTimestamp);
232        }
233    
234        public Timestamp getCreatedTimestamp() {
235            return createdTimestamp;
236        }
237    
238        public Date getRerunTime() {
239            return DateUtils.toDate(rerunTimestamp);
240        }
241    
242        public Timestamp getRerunTimestamp() {
243            return rerunTimestamp;
244        }
245    
246        @Override
247        public Date getLastModifiedTime() {
248            return DateUtils.toDate(lastModifiedTimestamp);
249        }
250    
251        public Timestamp getLastModifiedTimestamp() {
252            return lastModifiedTimestamp;
253        }
254    
255        @Override
256        public Date getNominalTime() {
257            return DateUtils.toDate(nominalTimestamp);
258        }
259    
260        public Timestamp getNominalTimestamp() {
261            return nominalTimestamp;
262        }
263    
264        @Override
265        public String getExternalId() {
266            return externalId;
267        }
268    
269        @Override
270        public void setExternalId(String externalId) {
271            super.setExternalId(externalId);
272            this.externalId = externalId;
273        }
274    
275        public String getSlaXml() {
276            return slaXml;
277        }
278    
279        public void setSlaXml(String slaXml) {
280            this.slaXml = slaXml;
281        }
282    
283        /**
284         * @return true if in terminal status
285         */
286        public boolean isTerminalStatus() {
287            boolean isTerminal = true;
288            switch (getStatus()) {
289                case WAITING:
290                case READY:
291                case SUBMITTED:
292                case RUNNING:
293                    isTerminal = false;
294                    break;
295                default:
296                    isTerminal = true;
297                    break;
298            }
299            return isTerminal;
300        }
301    
302    }