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 }