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.Date; 027import java.util.List; 028 029import javax.persistence.Basic; 030import javax.persistence.Column; 031import javax.persistence.Entity; 032import javax.persistence.Id; 033import javax.persistence.Lob; 034import javax.persistence.NamedQueries; 035import javax.persistence.NamedQuery; 036import javax.persistence.Table; 037import javax.persistence.Transient; 038 039import org.apache.hadoop.io.Writable; 040import org.apache.oozie.client.CoordinatorAction; 041import org.apache.oozie.client.rest.JsonBean; 042import org.apache.oozie.client.rest.JsonTags; 043import org.apache.oozie.client.rest.JsonUtils; 044import org.apache.oozie.coord.input.dependency.CoordInputDependency; 045import org.apache.oozie.coord.input.dependency.CoordInputDependencyFactory; 046import org.apache.oozie.util.DateUtils; 047import org.apache.oozie.util.WritableUtils; 048import org.apache.openjpa.persistence.jdbc.Index; 049import org.apache.openjpa.persistence.jdbc.Strategy; 050import org.json.simple.JSONArray; 051import org.json.simple.JSONObject; 052 053 054@Entity 055@NamedQueries({ 056 057 @NamedQuery(name = "UPDATE_COORD_ACTION", query = "update CoordinatorActionBean w set w.actionNumber = :actionNumber," 058 + " w.actionXml = :actionXml, w.consoleUrl = :consoleUrl, w.createdConf = :createdConf, w.errorCode = :errorCode," 059 + " w.errorMessage = :errorMessage, w.externalStatus = :externalStatus, w.missingDependencies " 060 + "= :missingDependencies, w.runConf = :runConf, w.timeOut = :timeOut, w.trackerUri = :trackerUri, w.type " 061 + "= :type, w.createdTimestamp = :createdTime, w.externalId = :externalId, w.jobId = :jobId," 062 + " w.lastModifiedTimestamp = :lastModifiedTime, w.nominalTimestamp = :nominalTime, w.slaXml = :slaXml," 063 + " w.statusStr = :status where w.id = :id"), 064 065 @NamedQuery(name = "UPDATE_COORD_ACTION_MIN", query = "update CoordinatorActionBean w set w.actionXml = :actionXml," 066 + " w.missingDependencies = :missingDependencies, w.lastModifiedTimestamp = :lastModifiedTime, w.statusStr " 067 + "= :status where w.id = :id"), 068 // Query to update the action status, pending status and last modified time stamp of a Coordinator action 069 @NamedQuery(name = "UPDATE_COORD_ACTION_STATUS_PENDING_TIME", query = "update CoordinatorActionBean w set w.statusStr" 070 + " =:status, w.pending =:pending, w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"), 071 // Update query for InputCheck 072 @NamedQuery(name = "UPDATE_COORD_ACTION_FOR_INPUTCHECK", query = "update CoordinatorActionBean w set w.statusStr " 073 + "= :status, w.lastModifiedTimestamp = :lastModifiedTime, w.actionXml = :actionXml, w.missingDependencies " 074 + "= :missingDependencies where w.id = :id"), 075 // Update query for Push-based missing dependency check 076 @NamedQuery(name = "UPDATE_COORD_ACTION_FOR_PUSH_INPUTCHECK", query = "update CoordinatorActionBean w set w.statusStr " 077 + "= :status, w.lastModifiedTimestamp = :lastModifiedTime, w.actionXml = :actionXml, w.pushMissingDependencies " 078 + "= :pushMissingDependencies where w.id = :id"), 079 // Update query for Push-based missing dependency check 080 @NamedQuery(name = "UPDATE_COORD_ACTION_DEPENDENCIES", query = "update CoordinatorActionBean w set w.missingDependencies" 081 + " = :missingDependencies, w.pushMissingDependencies = :pushMissingDependencies where w.id = :id"), 082 // Update query for Start 083 @NamedQuery(name = "UPDATE_COORD_ACTION_FOR_START", query = "update CoordinatorActionBean w set w.statusStr =:status," 084 + " w.lastModifiedTimestamp = :lastModifiedTime, w.runConf = :runConf, w.externalId = :externalId, w.pending " 085 + "= :pending, w.errorCode = :errorCode, w.errorMessage = :errorMessage where w.id = :id"), 086 087 @NamedQuery(name = "UPDATE_COORD_ACTION_FOR_MODIFIED_DATE", query = "update CoordinatorActionBean w set" 088 + " w.lastModifiedTimestamp = :lastModifiedTime where w.id = :id"), 089 090 @NamedQuery(name = "UPDATE_COORD_ACTION_RERUN", query = "update CoordinatorActionBean w set w.actionXml =:actionXml," 091 + " w.statusStr = :status, w.externalId = :externalId, w.externalStatus = :externalStatus, w.rerunTimestamp " 092 + "= :rerunTime, w.lastModifiedTimestamp = :lastModifiedTime, w.createdTimestamp = :createdTime, w.createdConf " 093 + "= :createdConf, w.runConf = :runConf, w.missingDependencies = :missingDependencies, w.pushMissingDependencies " 094 + "= :pushMissingDependencies, w.errorCode = :errorCode, w.errorMessage = :errorMessage where w.id = :id"), 095 096 @NamedQuery(name = "DELETE_COMPLETED_ACTIONS_FOR_COORDINATOR", query = "delete from CoordinatorActionBean a where a.jobId" 097 + " = :jobId and (a.statusStr = 'SUCCEEDED' OR a.statusStr = 'FAILED' OR a.statusStr= 'KILLED')"), 098 099 @NamedQuery(name = "DELETE_ACTIONS_FOR_LONG_RUNNING_COORDINATOR", query = "delete from CoordinatorActionBean a where a.id" 100 + " IN (:actionId)"), 101 102 @NamedQuery(name = "DELETE_UNSCHEDULED_ACTION", query = "delete from CoordinatorActionBean a where a.id = :id " 103 + "and (a.statusStr = 'WAITING' OR a.statusStr = 'READY')"), 104 105 @NamedQuery(name = "GET_COORD_ACTIONS_FOR_COORDINATOR", query = "select a.id from CoordinatorActionBean a where a.jobId" 106 + " = :jobId"), 107 108 // Query used by XTestcase to setup tables 109 @NamedQuery(name = "GET_COORD_ACTIONS", query = "select OBJECT(w) from CoordinatorActionBean w"), 110 // Select query used only by test cases 111 @NamedQuery(name = "GET_COORD_ACTION", query = "select OBJECT(a) from CoordinatorActionBean a where a.id = :id"), 112 113 // Select query used by SLAService on restart 114 @NamedQuery(name = "GET_COORD_ACTION_FOR_SLA", query = "select a.id, a.jobId, a.statusStr, a.externalId," 115 + " a.lastModifiedTimestamp from CoordinatorActionBean a where a.id = :id"), 116 // Select query used by ActionInfo command 117 @NamedQuery(name = "GET_COORD_ACTION_FOR_INFO", query = "select a.id, a.jobId, a.actionNumber, a.consoleUrl, a.errorCode," 118 + " a.errorMessage, a.externalId, a.externalStatus, a.trackerUri, a.createdTimestamp, a.nominalTimestamp," 119 + " a.statusStr, a.lastModifiedTimestamp, a.missingDependencies, a.pushMissingDependencies " 120 + "from CoordinatorActionBean a where a.id = :id"), 121 // Select Query used by Timeout and skip commands 122 @NamedQuery(name = "GET_COORD_ACTION_FOR_TIMEOUT", query = "select a.id, a.jobId, a.statusStr, a.runConf, a.pending," 123 + " a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.id = :id"), 124 // Select query used by InputCheck command 125 @NamedQuery(name = "GET_COORD_ACTION_FOR_INPUTCHECK", query = "select a.id, a.actionNumber, a.jobId, a.statusStr," 126 + " a.runConf, a.nominalTimestamp, a.createdTimestamp, a.actionXml, a.missingDependencies," 127 + " a.pushMissingDependencies, a.timeOut, a.externalId from CoordinatorActionBean a where a.id = :id"), 128 // Select query used by CoordActionUpdate command 129 @NamedQuery(name = "GET_COORD_ACTION_FOR_EXTERNALID", query = "select a.id, a.jobId, a.statusStr, a.pending," 130 + " a.externalId, a.lastModifiedTimestamp, a.slaXml, a.nominalTimestamp, a.createdTimestamp " 131 + "from CoordinatorActionBean a where a.externalId = :externalId"), 132 // Select query used by Check command 133 @NamedQuery(name = "GET_COORD_ACTION_FOR_CHECK", query = "select a.id, a.jobId, a.statusStr, a.pending, a.externalId," 134 + " a.lastModifiedTimestamp, a.slaXml, a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a" 135 + " where a.id = :id"), 136 // Select query used by Start command 137 @NamedQuery(name = "GET_COORD_ACTION_FOR_START", query = "select a.id, a.jobId, a.statusStr, a.pending, a.createdConf," 138 + " a.slaXml, a.actionXml, a.externalId, a.errorMessage, a.errorCode, a.nominalTimestamp, a.createdTimestamp " 139 + "from CoordinatorActionBean a where a.id = :id"), 140 141 @NamedQuery(name = "GET_COORD_ACTIONS_FOR_JOB_FIFO", query = "select a.id, a.actionNumber, a.jobId, a.statusStr," 142 + " a.pending, a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.jobId = :jobId " 143 + "AND a.statusStr = 'READY' order by a.nominalTimestamp"), 144 145 @NamedQuery(name = "GET_COORD_ACTIONS_FOR_JOB_LIFO", query = "select a.id, a.actionNumber, a.jobId, a.statusStr," 146 + " a.pending, a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.jobId = :jobId " 147 + "AND a.statusStr = 'READY' order by a.nominalTimestamp desc"), 148 149 @NamedQuery(name = "GET_COORD_RUNNING_ACTIONS_COUNT", query = "select count(a) from CoordinatorActionBean a where a.jobId" 150 + " = :jobId AND (a.statusStr = 'RUNNING' OR a.statusStr='SUBMITTED')"), 151 152 @NamedQuery(name = "GET_COORD_ACTIONS_COUNT_BY_JOBID", query = "select count(a) from CoordinatorActionBean a " 153 + "where a.jobId = :jobId"), 154 155 @NamedQuery(name = "GET_COORD_ACTIVE_ACTIONS_COUNT_BY_JOBID", query = "select count(a) from CoordinatorActionBean a" 156 + " where a.jobId = :jobId AND a.statusStr = 'WAITING'"), 157 158 @NamedQuery(name = "GET_COORD_ACTIONS_PENDING_FALSE_COUNT", query = "select count(a) from CoordinatorActionBean a " 159 + "where a.jobId = :jobId AND a.pending = 0 AND (a.statusStr = 'SUSPENDED' OR a.statusStr = 'TIMEDOUT' " 160 + "OR a.statusStr = 'SUCCEEDED' OR a.statusStr = 'KILLED' OR a.statusStr = 'FAILED')"), 161 162 @NamedQuery(name = "GET_COORD_ACTIONS_PENDING_FALSE_STATUS_COUNT", query = "select count(a) from CoordinatorActionBean a" 163 + " where a.jobId = :jobId AND a.pending = 0 AND a.statusStr = :status"), 164 165 @NamedQuery(name = "GET_ACTIONS_FOR_COORD_JOB", query = "select count(a) from CoordinatorActionBean a where a.jobId" 166 + " = :jobId"), 167 // Query to retrieve Coordinator actions sorted by nominal time 168 @NamedQuery(name = "GET_ACTIONS_FOR_COORD_JOB_ORDER_BY_NOMINAL_TIME", query = "select a.id, a.actionNumber, a.consoleUrl," 169 + " a.errorCode, a.errorMessage, a.externalId, a.externalStatus, a.jobId, a.trackerUri, a.createdTimestamp," 170 + " a.nominalTimestamp, a.statusStr, a.lastModifiedTimestamp, a.missingDependencies, a.pushMissingDependencies," 171 + " a.timeOut from CoordinatorActionBean a where a.jobId = :jobId order by a.nominalTimestamp"), 172 // Query to maintain backward compatibility for coord job info command 173 @NamedQuery(name = "GET_ALL_COLS_FOR_ACTIONS_FOR_COORD_JOB_ORDER_BY_NOMINAL_TIME", query = "select OBJECT(a) " 174 + "from CoordinatorActionBean a where a.jobId = :jobId order by a.nominalTimestamp"), 175 // Query to retrieve action id, action status, pending status and external Id of not completed Coordinator actions 176 @NamedQuery(name = "GET_COORD_ACTIONS_NOT_COMPLETED", query = "select a.id, a.statusStr, a.pending, a.externalId," 177 + " a.pushMissingDependencies, a.nominalTimestamp, a.createdTimestamp, a.jobId from CoordinatorActionBean a" 178 + " where a.jobId = :jobId AND a.statusStr <> 'FAILED' AND a.statusStr <> 'TIMEDOUT' AND a.statusStr " 179 + "<> 'SUCCEEDED' AND a.statusStr <> 'KILLED' AND a.statusStr <> 'IGNORED'"), 180 181 // Query to retrieve action id, action status, pending status and external Id of running Coordinator actions 182 @NamedQuery(name = "GET_COORD_ACTIONS_RUNNING", query = "select a.id, a.statusStr, a.pending, a.externalId," 183 + " a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.jobId = :jobId " 184 + "and a.statusStr = 'RUNNING'"), 185 186 // Query to retrieve action id, action status, pending status and external Id of suspended Coordinator actions 187 @NamedQuery(name = "GET_COORD_ACTIONS_SUSPENDED", query = "select a.id, a.statusStr, a.pending, a.externalId," 188 + " a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.jobId = :jobId " 189 + "and a.statusStr = 'SUSPENDED'"), 190 191 // Query to retrieve count of Coordinator actions which are pending 192 @NamedQuery(name = "GET_COORD_ACTIONS_PENDING_COUNT", query = "select count(a) from CoordinatorActionBean a where a.jobId" 193 + " = :jobId AND a.pending > 0"), 194 195 // Query to retrieve status of Coordinator actions 196 @NamedQuery(name = "GET_COORD_ACTIONS_STATUS_UNIGNORED", query = "select a.statusStr, a.pending " 197 + "from CoordinatorActionBean a where a.jobId = :jobId AND a.statusStr <> 'IGNORED'"), 198 199 // Query to retrieve status of Coordinator actions 200 @NamedQuery(name = "GET_COORD_ACTION_STATUS", query = "select a.statusStr from CoordinatorActionBean a where a.id = :id"), 201 202 @NamedQuery(name = "GET_COORD_ACTION_FOR_COORD_JOB_BY_ACTION_NUMBER", query = "select a.id from CoordinatorActionBean a" 203 + " where a.jobId = :jobId AND a.actionNumber = :actionNumber"), 204 205 @NamedQuery(name = "GET_COORD_ACTIONS_BY_LAST_MODIFIED_TIME", query = "select a.jobId from CoordinatorActionBean a " 206 + "where a.lastModifiedTimestamp >= :lastModifiedTime"), 207 208 //Used by coordinator store only 209 @NamedQuery(name = "GET_RUNNING_ACTIONS_FOR_COORD_JOB", query = "select OBJECT(a) from CoordinatorActionBean a " 210 + "where a.jobId = :jobId AND a.statusStr = 'RUNNING'"), 211 212 @NamedQuery(name = "GET_RUNNING_ACTIONS_OLDER_THAN", query = "select a.id from CoordinatorActionBean a where a.statusStr" 213 + " = 'RUNNING' AND a.lastModifiedTimestamp <= :lastModifiedTime"), 214 215 @NamedQuery(name = "GET_COORD_ACTIONS_WAITING_READY_SUBMITTED_OLDER_THAN", query = "select a.id, a.jobId, a.statusStr," 216 + " a.externalId, a.pushMissingDependencies from CoordinatorActionBean a where (a.statusStr = 'WAITING' " 217 + "OR a.statusStr = 'SUBMITTED' OR a.statusStr = 'READY') AND a.lastModifiedTimestamp <= :lastModifiedTime " 218 + "and a.nominalTimestamp <= :currentTime and a.jobId in ( select w.id from CoordinatorJobBean w" 219 + " where w.statusStr = 'RUNNING' or w.statusStr = 'RUNNINGWITHERROR')"), 220 221 @NamedQuery(name = "GET_COORD_ACTIONS_FOR_RECOVERY_OLDER_THAN", query = "select a.id, a.jobId, a.statusStr, a.externalId," 222 + " a.pending from CoordinatorActionBean a where a.pending > 0 AND (a.statusStr = 'SUSPENDED' OR a.statusStr " 223 + "= 'KILLED' OR a.statusStr = 'RUNNING') AND a.lastModifiedTimestamp <= :lastModifiedTime"), 224 // Select query used by rerun, requires almost all columns so select * is used 225 @NamedQuery(name = "GET_TERMINATED_ACTIONS_FOR_DATES", query = "select OBJECT(a) from CoordinatorActionBean a " 226 + "where a.jobId = :jobId AND (a.statusStr = 'TIMEDOUT' OR a.statusStr = 'SUCCEEDED' OR a.statusStr = 'KILLED' " 227 + "OR a.statusStr = 'FAILED' OR a.statusStr = 'IGNORED') AND a.nominalTimestamp >= :startTime " 228 + "AND a.nominalTimestamp <= :endTime"), 229 // Select query used by log 230 @NamedQuery(name = "GET_TERMINATED_ACTION_IDS_FOR_DATES", query = "select a.id from CoordinatorActionBean a where a.jobId" 231 + " = :jobId AND (a.statusStr = 'TIMEDOUT' OR a.statusStr = 'SUCCEEDED' OR a.statusStr = 'KILLED' OR a.statusStr" 232 + " = 'FAILED') AND a.nominalTimestamp >= :startTime AND a.nominalTimestamp <= :endTime"), 233 // Select query used by rerun, requires almost all columns so select * is used 234 @NamedQuery(name = "GET_ACTION_FOR_NOMINALTIME", query = "select OBJECT(a) from CoordinatorActionBean a where a.jobId " 235 + "= :jobId AND a.nominalTimestamp = :nominalTime"), 236 237 @NamedQuery(name = "GET_ACTIVE_ACTIONS_FOR_DATES", query = "select a.id, a.jobId, a.statusStr, a.externalId, a.pending," 238 + " a.nominalTimestamp, a.createdTimestamp from CoordinatorActionBean a where a.jobId = :jobId AND (a.statusStr " 239 + "= 'WAITING' OR a.statusStr = 'READY' OR a.statusStr = 'SUBMITTED' OR a.statusStr = 'RUNNING' OR a.statusStr " 240 + "= 'SUSPENDED') AND a.nominalTimestamp >= :startTime AND a.nominalTimestamp <= :endTime"), 241 242 @NamedQuery(name = "GET_COORD_ACTIONS_COUNT", query = "select count(w) from CoordinatorActionBean w"), 243 244 @NamedQuery(name = "GET_COORD_ACTIONS_COUNT_RUNNING_FOR_RANGE", query = "select count(w) from CoordinatorActionBean w" 245 + " where w.statusStr = 'RUNNING' and w.jobId= :jobId and w.id >= :startAction AND w.id <= :endAction"), 246 247 @NamedQuery(name = "GET_COORD_ACTIONS_MAX_MODIFIED_DATE_FOR_RANGE", query = "select max(w.lastModifiedTimestamp) " 248 + "from CoordinatorActionBean w where w.jobId= :jobId and w.id >= :startAction AND w.id <= :endAction"), 249 250 @NamedQuery(name = "GET_ACTIVE_ACTIONS_IDS_FOR_SLA_CHANGE", query = "select a.id, a.nominalTimestamp," 251 + " a.createdTimestamp, a.actionXml from CoordinatorActionBean a where a.id in (:ids)" 252 + " and (a.statusStr <> 'FAILED' AND a.statusStr <> 'KILLED' AND a.statusStr <> 'SUCCEEDED' AND a.statusStr " 253 + "<> 'TIMEDOUT' AND a.statusStr <> 'IGNORED')"), 254 255 @NamedQuery(name = "GET_ACTIVE_ACTIONS_JOBID_FOR_SLA_CHANGE", query = "select a.id, a.nominalTimestamp," 256 + " a.createdTimestamp, a.actionXml from CoordinatorActionBean a where a.jobId = :jobId and (a.statusStr " 257 + "<> 'FAILED' AND a.statusStr <> 'KILLED' AND a.statusStr <> 'SUCCEEDED' AND a.statusStr <> 'TIMEDOUT' " 258 + "AND a.statusStr <> 'IGNORED')") 259 }) 260 261@Table(name = "COORD_ACTIONS") 262public class CoordinatorActionBean implements 263 Writable,CoordinatorAction,JsonBean { 264 265 @Id 266 private String id; 267 268 @Basic 269 @Index 270 @Column(name = "job_id") 271 private String jobId; 272 273 @Basic 274 @Index 275 @Column(name = "status") 276 private String statusStr = CoordinatorAction.Status.WAITING.toString(); 277 278 @Basic 279 @Index 280 @Column(name = "nominal_time") 281 private java.sql.Timestamp nominalTimestamp = null; 282 283 @Basic 284 @Index 285 @Column(name = "last_modified_time") 286 private java.sql.Timestamp lastModifiedTimestamp = null; 287 288 @Basic 289 @Index 290 @Column(name = "created_time") 291 private java.sql.Timestamp createdTimestamp = null; 292 293 @Basic 294 @Index 295 @Column(name = "rerun_time") 296 private java.sql.Timestamp rerunTimestamp = null; 297 298 @Basic 299 @Index 300 @Column(name = "external_id") 301 private String externalId; 302 303 @Basic 304 @Column(name = "sla_xml") 305 @Lob 306 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 307 private StringBlob slaXml = null; 308 309 @Basic 310 @Column(name = "pending") 311 private int pending = 0; 312 313 @Basic 314 @Column(name = "job_type") 315 private String type; 316 317 @Basic 318 @Column(name = "action_number") 319 private int actionNumber; 320 321 @Basic 322 @Column(name = "created_conf") 323 @Lob 324 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 325 private StringBlob createdConf; 326 327 @Basic 328 @Column(name = "time_out") 329 private int timeOut = 0; 330 331 @Basic 332 @Column(name = "run_conf") 333 @Lob 334 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 335 private StringBlob runConf; 336 337 @Basic 338 @Column(name = "action_xml") 339 @Lob 340 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 341 private StringBlob actionXml; 342 343 @Basic 344 @Column(name = "missing_dependencies") 345 @Lob 346 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 347 private StringBlob missingDependencies; 348 349 @Basic 350 @Column(name = "push_missing_dependencies") 351 @Lob 352 @Strategy("org.apache.oozie.executor.jpa.StringBlobValueHandler") 353 private StringBlob pushMissingDependencies; 354 355 @Basic 356 @Column(name = "external_status") 357 private String externalStatus; 358 359 @Basic 360 @Column(name = "tracker_uri") 361 private String trackerUri; 362 363 @Basic 364 @Column(name = "console_url") 365 private String consoleUrl; 366 367 @Basic 368 @Column(name = "error_code") 369 private String errorCode; 370 371 @Basic 372 @Column(name = "error_message") 373 private String errorMessage; 374 375 @SuppressWarnings("unchecked") 376 public JSONObject toJSONObject() { 377 return toJSONObject("GMT"); 378 } 379 380 @Transient 381 private CoordInputDependency coordPushInputDependency; 382 383 @Transient 384 private CoordInputDependency coordPullInputDependency; 385 386 387 public CoordinatorActionBean() { 388 } 389 390 /** 391 * Serialize the coordinator bean to a data output. 392 * 393 * @param dataOutput data output. 394 * @throws IOException thrown if the coordinator bean could not be 395 * serialized. 396 */ 397 @Override 398 public void write(DataOutput dataOutput) throws IOException { 399 WritableUtils.writeStr(dataOutput, getJobId()); 400 WritableUtils.writeStr(dataOutput, getType()); 401 WritableUtils.writeStr(dataOutput, getId()); 402 WritableUtils.writeStr(dataOutput, getCreatedConf()); 403 WritableUtils.writeStr(dataOutput, getStatus().toString()); 404 dataOutput.writeInt(getActionNumber()); 405 WritableUtils.writeStr(dataOutput, getRunConf()); 406 WritableUtils.writeStr(dataOutput, getExternalStatus()); 407 WritableUtils.writeStr(dataOutput, getTrackerUri()); 408 WritableUtils.writeStr(dataOutput, getConsoleUrl()); 409 WritableUtils.writeStr(dataOutput, getErrorCode()); 410 WritableUtils.writeStr(dataOutput, getErrorMessage()); 411 dataOutput.writeLong((getCreatedTime() != null) ? getCreatedTime().getTime() : -1); 412 dataOutput.writeLong((getLastModifiedTime() != null) ? getLastModifiedTime().getTime() : -1); 413 } 414 415 /** 416 * Deserialize a coordinator bean from a data input. 417 * 418 * @param dataInput data input. 419 * @throws IOException thrown if the workflow bean could not be 420 * deserialized. 421 */ 422 @Override 423 public void readFields(DataInput dataInput) throws IOException { 424 setJobId(WritableUtils.readStr(dataInput)); 425 setType(WritableUtils.readStr(dataInput)); 426 setId(WritableUtils.readStr(dataInput)); 427 setCreatedConf(WritableUtils.readStr(dataInput)); 428 setStatus(CoordinatorAction.Status.valueOf(WritableUtils.readStr(dataInput))); 429 setActionNumber(dataInput.readInt()); 430 setRunConf(WritableUtils.readStr(dataInput)); 431 setExternalStatus(WritableUtils.readStr(dataInput)); 432 setTrackerUri(WritableUtils.readStr(dataInput)); 433 setConsoleUrl(WritableUtils.readStr(dataInput)); 434 setErrorCode(WritableUtils.readStr(dataInput)); 435 setErrorMessage(WritableUtils.readStr(dataInput)); 436 long d = dataInput.readLong(); 437 if (d != -1) { 438 setCreatedTime(new Date(d)); 439 } 440 d = dataInput.readLong(); 441 if (d != -1) { 442 setLastModifiedTime(new Date(d)); 443 } 444 } 445 446 @Override 447 public String getJobId() { 448 return this.jobId; 449 } 450 451 public void setJobId(String id) { 452 this.jobId = id; 453 } 454 455 @Override 456 public Status getStatus() { 457 return Status.valueOf(statusStr); 458 } 459 460 /** 461 * Return the status in string 462 * @return statusStr 463 */ 464 public String getStatusStr() { 465 return statusStr; 466 } 467 468 public void setStatus(Status status) { 469 this.statusStr = status.toString(); 470 } 471 472 public void setStatusStr(String statusStr) { 473 this.statusStr = statusStr; 474 } 475 476 public void setCreatedTime(Date createdTime) { 477 this.createdTimestamp = DateUtils.convertDateToTimestamp(createdTime); 478 } 479 480 public void setRerunTime(Date rerunTime) { 481 this.rerunTimestamp = DateUtils.convertDateToTimestamp(rerunTime); 482 } 483 484 public void setNominalTime(Date nominalTime) { 485 this.nominalTimestamp = DateUtils.convertDateToTimestamp(nominalTime); 486 } 487 488 public void setLastModifiedTime(Date lastModifiedTime) { 489 this.lastModifiedTimestamp = DateUtils.convertDateToTimestamp(lastModifiedTime); 490 } 491 492 public Date getCreatedTime() { 493 return DateUtils.toDate(createdTimestamp); 494 } 495 496 public Timestamp getCreatedTimestamp() { 497 return createdTimestamp; 498 } 499 500 public Date getRerunTime() { 501 return DateUtils.toDate(rerunTimestamp); 502 } 503 504 public Timestamp getRerunTimestamp() { 505 return rerunTimestamp; 506 } 507 508 @Override 509 public Date getLastModifiedTime() { 510 return DateUtils.toDate(lastModifiedTimestamp); 511 } 512 513 public Timestamp getLastModifiedTimestamp() { 514 return lastModifiedTimestamp; 515 } 516 517 @Override 518 public Date getNominalTime() { 519 return DateUtils.toDate(nominalTimestamp); 520 } 521 522 public Timestamp getNominalTimestamp() { 523 return nominalTimestamp; 524 } 525 526 @Override 527 public String getExternalId() { 528 return externalId; 529 } 530 531 public void setExternalId(String externalId) { 532 this.externalId = externalId; 533 } 534 535 public StringBlob getSlaXmlBlob() { 536 return slaXml; 537 } 538 539 public void setSlaXmlBlob(StringBlob slaXml) { 540 this.slaXml = slaXml; 541 } 542 543 public String getSlaXml() { 544 return slaXml == null ? null : slaXml.getString(); 545 } 546 547 public void setSlaXml(String slaXml) { 548 if (this.slaXml == null) { 549 this.slaXml = new StringBlob(slaXml); 550 } 551 else { 552 this.slaXml.setString(slaXml); 553 } 554 } 555 556 /** 557 * @return true if in terminal status 558 */ 559 public boolean isTerminalStatus() { 560 boolean isTerminal = true; 561 switch (getStatus()) { 562 case WAITING: 563 case READY: 564 case SUBMITTED: 565 case RUNNING: 566 case SUSPENDED: 567 isTerminal = false; 568 break; 569 default: 570 isTerminal = true; 571 break; 572 } 573 return isTerminal; 574 } 575 576 /** 577 * Return if the action is complete with failure. 578 * 579 * @return if the action is complete with failure. 580 */ 581 public boolean isTerminalWithFailure() { 582 boolean result = false; 583 switch (getStatus()) { 584 case FAILED: 585 case KILLED: 586 case TIMEDOUT: 587 result = true; 588 } 589 return result; 590 } 591 592 /** 593 * Set some actions are in progress for particular coordinator action. 594 * 595 * @param pending set pending to true 596 */ 597 public void setPending(int pending) { 598 this.pending = pending; 599 } 600 601 /** 602 * increment pending and return it 603 * 604 * @return pending 605 */ 606 public int incrementAndGetPending() { 607 this.pending++; 608 return pending; 609 } 610 611 /** 612 * decrement pending and return it 613 * 614 * @return pending 615 */ 616 public int decrementAndGetPending() { 617 this.pending = Math.max(this.pending - 1, 0); 618 return pending; 619 } 620 621 /** 622 * Get some actions are in progress for particular bundle action. 623 * 624 * @return pending 625 */ 626 public int getPending() { 627 return this.pending; 628 } 629 630 /** 631 * Return if the action is pending. 632 * 633 * @return if the action is pending. 634 */ 635 public boolean isPending() { 636 return pending > 0 ? true : false; 637 } 638 639 @Override 640 public String getId() { 641 return id; 642 } 643 644 public void setId(String id) { 645 this.id = id; 646 } 647 648 public String getType() { 649 return type; 650 } 651 652 public void setType(String type) { 653 this.type = type; 654 } 655 656 public void setActionNumber(int actionNumber) { 657 this.actionNumber = actionNumber; 658 } 659 660 @Override 661 public int getActionNumber() { 662 return actionNumber; 663 } 664 665 @Override 666 public String getCreatedConf() { 667 return createdConf == null ? null : createdConf.getString(); 668 } 669 670 public void setCreatedConf(String createdConf) { 671 if (this.createdConf == null) { 672 this.createdConf = new StringBlob(createdConf); 673 } 674 else { 675 this.createdConf.setString(createdConf); 676 } 677 } 678 679 public void setCreatedConfBlob(StringBlob createdConf) { 680 this.createdConf = createdConf; 681 } 682 683 public StringBlob getCreatedConfBlob() { 684 return createdConf; 685 } 686 687 public void setRunConf(String runConf) { 688 if (this.runConf == null) { 689 this.runConf = new StringBlob(runConf); 690 } 691 else { 692 this.runConf.setString(runConf); 693 } 694 } 695 696 @Override 697 public String getRunConf() { 698 return runConf == null ? null : runConf.getString(); 699 } 700 701 public void setRunConfBlob(StringBlob runConf) { 702 this.runConf = runConf; 703 } 704 705 public StringBlob getRunConfBlob() { 706 return runConf; 707 } 708 709 710 public void setMissingDependencies(String missingDependencies) { 711 if (this.missingDependencies == null) { 712 this.missingDependencies = new StringBlob(missingDependencies); 713 } 714 else { 715 this.missingDependencies.setString(missingDependencies); 716 } 717 } 718 719 @Override 720 public String getMissingDependencies() { 721 return missingDependencies == null ? null : missingDependencies.getString(); 722 } 723 724 public void setMissingDependenciesBlob(StringBlob missingDependencies) { 725 this.missingDependencies = missingDependencies; 726 } 727 728 public StringBlob getMissingDependenciesBlob() { 729 return missingDependencies; 730 } 731 732 @Override 733 public String getPushMissingDependencies() { 734 return pushMissingDependencies == null ? null : pushMissingDependencies.getString(); 735 } 736 737 public void setPushMissingDependencies(String pushMissingDependencies) { 738 if (this.pushMissingDependencies == null) { 739 this.pushMissingDependencies = new StringBlob(pushMissingDependencies); 740 } 741 else { 742 this.pushMissingDependencies.setString(pushMissingDependencies); 743 } 744 } 745 746 public void setPushMissingDependenciesBlob(StringBlob pushMissingDependencies) { 747 this.pushMissingDependencies = pushMissingDependencies; 748 } 749 750 public StringBlob getPushMissingDependenciesBlob() { 751 return pushMissingDependencies; 752 } 753 754 public String getExternalStatus() { 755 return externalStatus; 756 } 757 758 public void setExternalStatus(String externalStatus) { 759 this.externalStatus = externalStatus; 760 } 761 762 @Override 763 public String getTrackerUri() { 764 return trackerUri; 765 } 766 767 public void setTrackerUri(String trackerUri) { 768 this.trackerUri = trackerUri; 769 } 770 771 @Override 772 public String getConsoleUrl() { 773 return consoleUrl; 774 } 775 776 public void setConsoleUrl(String consoleUrl) { 777 this.consoleUrl = consoleUrl; 778 } 779 780 @Override 781 public String getErrorCode() { 782 return errorCode; 783 } 784 785 @Override 786 public String getErrorMessage() { 787 return errorMessage; 788 } 789 790 public void setErrorInfo(String errorCode, String errorMessage) { 791 this.errorCode = errorCode; 792 this.errorMessage = errorMessage; 793 } 794 795 public String getActionXml() { 796 return actionXml == null ? null : actionXml.getString(); 797 } 798 799 public void setActionXml(String actionXml) { 800 if (this.actionXml == null) { 801 this.actionXml = new StringBlob(actionXml); 802 } 803 else { 804 this.actionXml.setString(actionXml); 805 } 806 } 807 808 public void setActionXmlBlob(StringBlob actionXml) { 809 this.actionXml = actionXml; 810 } 811 812 public StringBlob getActionXmlBlob() { 813 return actionXml; 814 } 815 816 @Override 817 public String toString() { 818 return MessageFormat.format("CoordinatorAction name[{0}] status[{1}]", 819 getId(), getStatus()); 820 } 821 822 public int getTimeOut() { 823 return timeOut; 824 } 825 826 public void setTimeOut(int timeOut) { 827 this.timeOut = timeOut; 828 } 829 830 831 public void setErrorCode(String errorCode) { 832 this.errorCode = errorCode; 833 } 834 835 public void setErrorMessage(String errorMessage) { 836 this.errorMessage = errorMessage; 837 } 838 839 @SuppressWarnings("unchecked") 840 public JSONObject toJSONObject(String timeZoneId) { 841 JSONObject json = new JSONObject(); 842 json.put(JsonTags.COORDINATOR_ACTION_ID, id); 843 json.put(JsonTags.COORDINATOR_JOB_ID, jobId); 844 json.put(JsonTags.COORDINATOR_ACTION_TYPE, type); 845 json.put(JsonTags.COORDINATOR_ACTION_NUMBER, actionNumber); 846 json.put(JsonTags.COORDINATOR_ACTION_CREATED_CONF, getCreatedConf()); 847 json.put(JsonTags.COORDINATOR_ACTION_CREATED_TIME, JsonUtils.formatDateRfc822(getCreatedTime(), timeZoneId)); 848 json.put(JsonTags.COORDINATOR_ACTION_NOMINAL_TIME, JsonUtils.formatDateRfc822(getNominalTime(), timeZoneId)); 849 json.put(JsonTags.COORDINATOR_ACTION_EXTERNALID, externalId); 850 // json.put(JsonTags.COORDINATOR_ACTION_START_TIME, JsonUtils 851 // .formatDateRfc822(startTime), timeZoneId); 852 json.put(JsonTags.COORDINATOR_ACTION_STATUS, statusStr); 853 json.put(JsonTags.COORDINATOR_ACTION_RUNTIME_CONF, getRunConf()); 854 json.put(JsonTags.COORDINATOR_ACTION_LAST_MODIFIED_TIME, 855 JsonUtils.formatDateRfc822(getLastModifiedTime(), timeZoneId)); 856 // json.put(JsonTags.COORDINATOR_ACTION_START_TIME, JsonUtils 857 // .formatDateRfc822(startTime), timeZoneId); 858 // json.put(JsonTags.COORDINATOR_ACTION_END_TIME, JsonUtils 859 // .formatDateRfc822(endTime), timeZoneId); 860 json.put(JsonTags.COORDINATOR_ACTION_MISSING_DEPS, getPullInputDependencies().getMissingDependencies()); 861 json.put(JsonTags.COORDINATOR_ACTION_PUSH_MISSING_DEPS, getPushInputDependencies().getMissingDependencies()); 862 json.put(JsonTags.COORDINATOR_ACTION_EXTERNAL_STATUS, externalStatus); 863 json.put(JsonTags.COORDINATOR_ACTION_TRACKER_URI, trackerUri); 864 json.put(JsonTags.COORDINATOR_ACTION_CONSOLE_URL, consoleUrl); 865 json.put(JsonTags.COORDINATOR_ACTION_ERROR_CODE, errorCode); 866 json.put(JsonTags.COORDINATOR_ACTION_ERROR_MESSAGE, errorMessage); 867 json.put(JsonTags.TO_STRING, toString()); 868 return json; 869 } 870 871 /** 872 * Convert a nodes list into a JSONArray. 873 * 874 * @param actions nodes list. 875 * @param timeZoneId time zone to use for dates in the JSON array. 876 * @return the corresponding JSON array. 877 */ 878 @SuppressWarnings("unchecked") 879 public static JSONArray toJSONArray(List<CoordinatorActionBean> actions, String timeZoneId) { 880 JSONArray array = new JSONArray(); 881 for (CoordinatorActionBean action : actions) { 882 array.add(action.toJSONObject(timeZoneId)); 883 } 884 return array; 885 } 886 887 @Override 888 public int hashCode() { 889 final int prime = 31; 890 int result = 1; 891 result = prime * result + ((id == null) ? 0 : id.hashCode()); 892 return result; 893 } 894 895 @Override 896 public boolean equals(Object obj) { 897 if (this == obj) { 898 return true; 899 } 900 if (obj == null) { 901 return false; 902 } 903 if (getClass() != obj.getClass()) { 904 return false; 905 } 906 CoordinatorActionBean other = (CoordinatorActionBean) obj; 907 if (id == null) { 908 if (other.id != null) { 909 return false; 910 } 911 } 912 else if (!id.equals(other.id)) { 913 return false; 914 } 915 return true; 916 } 917 918 public CoordInputDependency getPullInputDependencies() { 919 if (coordPullInputDependency == null) { 920 coordPullInputDependency = CoordInputDependencyFactory.getPullInputDependencies(missingDependencies); 921 } 922 return coordPullInputDependency; 923 924 } 925 926 public CoordInputDependency getPushInputDependencies() { 927 if (coordPushInputDependency == null) { 928 coordPushInputDependency = CoordInputDependencyFactory.getPushInputDependencies(pushMissingDependencies); 929 } 930 return coordPushInputDependency; 931 } 932 933 public void setPullInputDependencies(CoordInputDependency coordPullInputDependency) { 934 this.coordPullInputDependency = coordPullInputDependency; 935 } 936 937 public void setPushInputDependencies(CoordInputDependency coordPushInputDependency) { 938 this.coordPushInputDependency = coordPushInputDependency; 939 } 940 941}